@datagrok/bio 2.11.13 → 2.11.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/23.js +2 -0
- package/dist/23.js.map +1 -0
- package/dist/282.js +2 -0
- package/dist/282.js.map +1 -0
- package/dist/361.js +1 -1
- package/dist/361.js.map +1 -1
- package/dist/40.js +2 -0
- package/dist/40.js.map +1 -0
- package/dist/562.js +2 -0
- package/dist/562.js.map +1 -0
- package/dist/586.js +2 -0
- package/dist/586.js.map +1 -0
- package/dist/65.js +2 -0
- package/dist/65.js.map +1 -0
- package/dist/{931.js → 935.js} +3 -3
- package/dist/935.js.map +1 -0
- package/dist/package-test.js +1 -1
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/package.json +4 -4
- package/scripts/sequence_generator.py +24 -22
- package/src/demo/bio05-helm-msa-sequence-space.ts +53 -13
- package/src/demo/utils.ts +2 -1
- package/src/function-edtiors/split-to-monomers-editor.ts +2 -2
- package/src/package.ts +80 -177
- package/src/tests/pepsea-tests.ts +1 -1
- package/src/tests/sequence-space-utils.ts +6 -2
- package/src/tests/similarity-diversity-tests.ts +16 -4
- package/src/utils/cell-renderer.ts +1 -1
- package/src/utils/helm-to-molfile.ts +1 -1
- package/src/utils/monomer-lib.ts +1 -1
- package/src/utils/pepsea.ts +16 -1
- package/src/viewers/vd-regions-viewer.ts +42 -16
- package/src/viewers/web-logo-viewer.ts +40 -20
- package/dist/1.js +0 -2
- package/dist/1.js.map +0 -1
- package/dist/190.js +0 -2
- package/dist/190.js.map +0 -1
- package/dist/381.js +0 -2
- package/dist/381.js.map +0 -1
- package/dist/770.js +0 -2
- package/dist/770.js.map +0 -1
- package/dist/868.js +0 -2
- package/dist/868.js.map +0 -1
- package/dist/931.js.map +0 -1
- package/src/utils/err-info.ts +0 -28
- /package/dist/{931.js.LICENSE.txt → 935.js.LICENSE.txt} +0 -0
package/dist/935.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"935.js","mappings":";+BAAIA,ECAAC,kCCOG,MAAM,UAAeC,cCArB,SAASC,EAAYC,GACxB,OAAOC,KAAKC,SAAWF,CAC3B,CAQO,SAAS,EAAUA,GACtB,OAAOC,KAAKE,MAAMJ,EAAYC,GAClC,CCTO,SAASI,EAAOC,GAAY,EAAOC,EAAU,oBAChD,IAAKD,EACD,MAAM,IAAIE,MAAMD,EACxB,CAkCO,SAASE,EAAUC,EAAGC,EAAGC,EAAa,GACzC,MAAMC,EAASH,EAAEI,OACjBT,EAAOQ,GAAUF,EAAEG,OAAQ,gCAC3B,MAAMC,EAAQ,IAAI,EAAOF,GACzB,IAAK,IAAIG,EAAI,EAAGA,EAAIN,EAAEI,SAAUE,EAC5BD,EAAMC,GAAKN,EAAEM,GAAKJ,EAAaD,EAAEK,GACrC,OAAOD,CACX,CAiDO,SAASE,EAAiBC,EAAYC,EAAYC,EAAQ,GAC7D,MAAMC,EAjFH,SAAyBH,EAAYC,EAAYG,EAAO,GAC3D,OAAO,IAAIC,MAAML,GAAYI,KAAKA,GAAME,KAAI,IAAO,IAAI,EAAOL,GAAYG,KAAKA,IACnF,CA+EmBG,CAAgBP,EAAYC,GAC3C,IAAK,IAAIH,EAAI,EAAGA,EAAIE,IAAcF,EAC9B,IAAK,IAAIU,EAAI,EAAGA,EAAIP,IAAcO,EAC9BL,EAAOL,GAAGU,GAAK1B,EAAYoB,GAEnC,OAAOC,CACX,CASO,SAASM,EAA2BjB,EAAGC,GAC1C,IAAIiB,EAAS,EACb,MAAMC,EAAMnB,EAAEI,OACd,GAAIe,IAAQlB,EAAEG,OACV,MAAM,IAAIN,MAAM,gDACpB,IAAK,IAAIQ,EAAI,EAAGA,EAAIa,IAAOb,EACvBY,GAAU1B,KAAK4B,IAAKpB,EAAEM,GAAKL,EAAEK,GAAK,GACtC,OAAOd,KAAK6B,KAAKH,EACrB,CC9FO,SAASI,EAAcC,GAC1B,MAAO,CAACjB,EAAGU,IAAMO,EAAOjB,EAAIU,EAAIxB,KAAKE,OAAQY,EAAI,IAAMA,EAAI,GAAM,EACrE,CCnCO,MAAMkB,EACTC,YAAYC,GAAuB,EAAMC,GAAsB,GAC3D,MAAMC,EAAcC,UAAUC,oBAC9BC,KAAKC,aAAeN,EAAuBlC,KAAKyC,IAAIL,EAAc,EAAG,GAAK,EAC1EG,KAAKG,SAAW,IAAIrB,MAAMkB,KAAKC,cAAcpB,KAAK,MAC7CE,KAAI,IAAM,IAAIqB,OAAO,IAAIC,IAAI,oBAClCL,KAAKM,qBAAuBV,CAChC,CAEAW,WAAWC,EAAQC,EAAQC,GAAY,EAAMC,GACzC,OAAO,IAAIC,SAAQL,MAAOM,EAASC,KAC/B,IACI,MAAM1B,EAAMoB,EAAOnC,OACb0C,EAAW,IAAIjC,MAAMkB,KAAKC,cAC1Be,EAAc5B,GAAOA,EAAM,GAAK,EACtCY,KAAKC,aAAexC,KAAKwD,IAAIjB,KAAKC,aAAce,GAChD,MAAME,EAAYF,EAAchB,KAAKC,aAC/BkB,EAAiB,IAAI7D,aAAa0D,GACxC,IAAII,EAAS,EACTC,EAAS,EAETC,EAAO,EACPC,EAAOC,OAAOC,UAClB,IAAK,IAAIlD,EAAI,EAAGA,EAAIyB,KAAKC,aAAc1B,IAAK,CACxC,MAAMmD,EAAQjE,KAAKE,MAAMY,EAAI2C,GACvBS,EAAOpD,IAAMyB,KAAKC,aAAe,EAAKe,EAAcvD,KAAKE,OAAOY,EAAI,GAAK2C,GACzEU,EAAWR,EACXS,EAAWR,EACb9C,IAAMyB,KAAKC,aAAe,IAE1BmB,EAAShC,EAAM,EAAI3B,KAAKE,MAAMF,KAAK6B,MAAM,EAAIqC,EAAM,EAAIvC,GAAOA,EAAM,GAAK,GAAK,EAAI,IAClFiC,EAASM,EAAMvC,EAAMgC,EAAS3D,KAAKE,OAAOyD,EAAS,IAAMA,EAAS,GAAK,IAE3EpB,KAAKG,SAAS5B,GAAGuD,YAAY,CAAEtB,SAAQC,SAAQmB,WAAUC,WAAUE,WAAYJ,EAAMD,EAAOf,SAC5FI,EAASxC,GAAK,IAAIqC,SAAQ,CAACoB,EAAeC,KACtCjC,KAAKG,SAAS5B,GAAG2D,UAAY,EAAGC,MAAQC,QAAOC,qBAAoBpB,MAAKf,WACpEF,KAAKM,sBAAwBN,KAAKG,SAAS5B,GAAG+D,YAC1CF,EACAH,EAAaG,IAGbjB,EAAeoB,IAAIF,EAAoBX,GACnCT,EAAMK,IACNA,EAAOL,GACPf,EAAMqB,IACNA,EAAOrB,GACX8B,IACJ,CACH,GAET,OACMpB,QAAQ4B,IAAIzB,GACdL,GACAS,EAAesB,SAAQ,CAACC,EAAOC,KAAYxB,EAAewB,IAAUD,EAAQpB,IAASC,EAAOD,EAAK,IACrGT,EAAQM,EACZ,CACA,MAAOyB,GACH9B,EAAO8B,EACX,IAER,CACAN,YACItC,KAAKG,SAASsC,SAASI,GAAWA,EAAOP,aAC7C,ECrDJ,MAAMQ,EAMFpD,YAAYqD,GACR/C,KAAKgD,MAAQD,GAASC,OAAS,EAC/BhD,KAAKiD,OAASF,GAASE,QAAU,IAEjCjD,KAAKkD,OAASH,GAASG,QAAU,EAEjClD,KAAKmD,OAASJ,GAASI,QAAU,EACjCnD,KAAKoD,QAAUL,GAASK,SAAW,IACnCpD,KAAKqD,QAAUrD,KAAKmD,OAAS,EAC7BnD,KAAKsD,SAAWtD,KAAKoD,QAAU,EAC/BpD,KAAKuD,QAAUR,GAASQ,SAAW,MAEnCvD,KAAKwD,iBAAmBT,GAASU,UAAYvE,EAC7Cc,KAAKyD,SAAW,IAAInG,aACpB0C,KAAK0D,qBAAuBX,GAASW,oBACzC,CAOAnD,mBAAmBoD,GACf3D,KAAK4D,aAAerE,EAAcoE,EAAQtF,QAC1C,MAAMwF,EAAgB,IAAIpE,GAAsB,GAAM,GACtDO,KAAKyD,eAAiBI,EAAcC,KAAKH,EAAS3D,KAAK0D,sBACvDG,EAAcvB,WAClB,CASAyB,aAAaJ,EAASK,EAAQC,GAC1B,OAAOjE,KAAKyD,SAASzD,KAAK4D,aAAaI,EAAQC,GACnD,CAOA1D,YAAYoD,GACR,MAAMvF,EAASuF,EAAQtF,OAGjB6F,EAAc1F,EAAiBJ,EAAQ0E,EAAQqB,UAFnC,IAGlB,IAAId,EAAUrD,KAAKqD,QACA,IAAfrD,KAAKgD,QACLhD,KAAKgD,MAAQW,EAAQtF,OAAS,SAC5B2B,KAAKoE,aAAaT,GACxB,IAAK,IAAIU,EAAQ,EAAGA,EAAQrE,KAAKiD,SAAUoB,EAAO,CAC9C,IAAK,IAAIC,EAAO,EAAGA,EAAOtE,KAAKgD,QAASsB,EAAM,CAE1C,MAAM/F,EAAI,EAAUH,GACpB,IAAIa,EAAI,EAAUb,GAClB,KAAOG,GAAKU,GACRA,EAAI,EAAUb,GAClB,MAAMmG,EAAOL,EAAY3F,GACnBiG,EAAON,EAAYjF,GAEnBwF,EAAIzE,KAAK+D,aAAaJ,EAASpF,EAAGU,GAElCyF,EAAIxF,EAA2BqF,EAAMC,GAE3C,GAAoB,GAAfxE,KAAKkD,QAAiBuB,GAAKzE,KAAKkD,QAAYwB,EAAID,EAAI,CACrD,MAAMtG,EAAakF,GAAWoB,EAAIC,IAAMA,EAAI1E,KAAKuD,SAE3CoB,EAAS3G,EAAUuG,EAAMC,GAAO,GACtCN,EAAY3F,GAAKP,EAAUuG,EAAMI,EAAQxG,GACzC+F,EAAYjF,GAAKjB,EAAUwG,EAAMG,GAASxG,EAC9C,CACJ,CAGA,GADAkF,GAAWrD,KAAKsD,SACZD,GAAW,EACX,KACR,CACA,OAAOa,CACX,EAEJpB,EAAQqB,UAAY,EASb,MAAMS,UAAiB9B,EAO1BvC,YAAYoD,GACR,MAAMvF,EAASuF,EAAQtF,OAGjB6F,EAAc1F,EAAiBJ,EAAQwG,EAAST,UAFpC,IAGlB,IAAIhB,EAASnD,KAAKmD,aACZnD,KAAKoE,aAAaT,GACxB,IAAK,IAAIU,EAAQ,EAAGA,EAAQrE,KAAKiD,SAAUoB,EAAO,CAE9C,MAAM9F,EAAI,EAAUH,GACdmG,EAAOL,EAAY3F,GAEzB,IAAK,IAAIU,EAAI,EAAGA,EAAIb,IAAUa,EAAG,CAC7B,GAAIV,GAAKU,EACL,SACJ,MAAMuF,EAAON,EAAYjF,GAEnBwF,EAAIzE,KAAK+D,aAAaJ,EAASpF,EAAGU,GAElCyF,EAAIxF,EAA2BqF,EAAMC,GAE3C,GAAoB,GAAfxE,KAAKkD,QAAiBuB,GAAKzE,KAAKkD,QAAYwB,EAAID,EAAI,CACrD,MAAMtG,EAAagF,GAAUsB,EAAIC,IAAMA,EAAI1E,KAAKuD,SAC1CoB,EAAS3G,EAAUuG,EAAMC,GAAO,GAEtCN,EAAYjF,GAAKjB,EAAUwG,EAAMG,GAASxG,EAC9C,CACJ,CAGA,GADAgF,GAAUnD,KAAKoD,QACXD,GAAU,EACV,KACR,CACA,OAAOe,CACX,EASG,MAAMW,UAAoB/B,EAC7BpD,YAAYqD,GACR+B,MAAM/B,GACN/C,KAAKiD,OAASF,GAASE,QAAU,IACjCjD,KAAKgD,MAAQD,GAASC,OAAS,IAC/BhD,KAAK+E,cAAgBhC,GAASgC,eAAiB,EAC/C/E,KAAKgF,YAAcjC,GAASiC,aAAe,KAC3ChF,KAAKiF,iBAAmBlC,GAASkC,kBAAoB,IACzD,CACA1E,YAAYoD,GACR,MAAMvF,EAASuF,EAAQtF,OAGjB6F,EAAc1F,EAAiBJ,EAAQyG,EAAYV,UAFvC,IAMlB,SAHMnE,KAAKoE,aAAaT,GACM,OAA1B3D,KAAKiF,mBACLjF,KAAKiF,iBAAmB7G,EAASX,KAAKE,OAAOS,EAAS,GAAK,IACtC,OAArB4B,KAAKgF,YAAsB,CAC3BhF,KAAKgF,aAAe,KACpB,IAAK,IAAIE,EAAI,EAAGA,EAAIlF,KAAKiF,iBAAkBC,IAAK,CAC5C,MAAM3G,EAAI,EAAUH,GACpB,IAAIa,EAAI,EAAUb,GAClB,KAAOG,GAAKU,GACRA,EAAI,EAAUb,GAClB,MAAMsG,EAAI1E,KAAK+D,aAAaJ,EAASpF,EAAGU,GACpCyF,EAAI1E,KAAKgF,cACThF,KAAKgF,YAAcN,EAC3B,CACJ,CACA,IAAIvB,EAASnD,KAAKmD,OAClB,MAAMgC,EAAgC,GAAtBnF,KAAK+E,cAAwB/E,KAAKgF,YAAchF,KAAKgF,YAAchF,KAAK+E,cACxF,IAAK,IAAIV,EAAQ,EAAGA,EAAQrE,KAAKiD,SAAUoB,EAAO,CAC9C,IAAK,IAAIC,EAAO,EAAGA,EAAOtE,KAAKgD,QAASsB,EAAM,CAE1C,MAAM/F,EAAI,EAAUH,GACpB,IAAIa,EAAI,EAAUb,GAClB,KAAOG,GAAKU,GACRA,EAAI,EAAUb,GAClB,MAAMmG,EAAOL,EAAY3F,GACnBiG,EAAON,EAAYjF,GAEnBwF,EAAIzE,KAAK+D,aAAaJ,EAASpF,EAAGU,GAElCyF,EAAIxF,EAA2BqF,EAAMC,GAC3C,GAAKC,GAAKU,GAAYT,EAAID,EAAI,CAC1B,MAAMtG,EAAsB,GAATgF,GAAgBsB,EAAIC,IAAMA,EAAI1E,KAAKuD,SAEhDoB,EAAS3G,EAAUuG,EAAMC,GAAO,GACtCN,EAAY3F,GAAKP,EAAUuG,EAAMI,EAAQxG,GACzC+F,EAAYjF,GAAKjB,EAAUwG,EAAMG,GAASxG,EAC9C,CACJ,CAGA,GAFAgF,IAAYnD,KAAKmD,OAASnD,KAAKoD,UAAYpD,KAAKiD,OAAS,GAErDE,EAASnD,KAAKoD,QACd,KACR,CACA,OAAOc,CACX,MCzNOkB,EAMAC,EAIAC,EAeAC,EAIAC,EASAC,iCArCX,SAAWL,GACPA,EAAgC,YAAI,cACpCA,EAAgC,YAAI,eACpCA,EAA8B,UAAI,WACrC,CAJD,CAIGA,IAAuBA,EAAqB,CAAC,IAEhD,SAAWC,GACPA,EAA8B,UAAI,WACrC,CAFD,CAEGA,IAAuBA,EAAqB,CAAC,IAEhD,SAAWC,GACPA,EAA+B,SAAI,WACnCA,EAA2B,KAAI,OAC/BA,EAAiC,WAAI,aACrCA,EAAoC,cAAI,iBACxCA,EAA6B,OAAI,SACjCA,EAAiC,WAAI,aACrCA,EAAmC,aAAI,gBACvCA,EAAoC,cAAI,iBACxCA,EAA6B,OAAI,SACjCA,EAA4B,MAAI,QAChCA,EAA8B,QAAI,UAClCA,EAAgC,UAAI,WACvC,CAbD,CAaGA,IAAyBA,EAAuB,CAAC,IAEpD,SAAWC,GACPA,EAAuC,iBAAI,kBAC9C,CAFD,CAEGA,IAAyBA,EAAuB,CAAC,IAEpD,SAAWC,GACPA,EAAgC,OAAI,SACpCA,EAAgC,OAAI,SACpCA,EAAkC,SAAI,WACtCA,EAAuC,cAAI,gBAC3CA,EAAgC,OAAI,SACpCA,EAAkC,SAAI,UACzC,CAPD,CAOGA,IAA4BA,EAA0B,CAAC,IAE1D,SAAWC,GACPA,EAA+B,WAAI,YACtC,CAFD,CAEGA,IAAuBA,EAAqB,CAAC,iBCOzC,SAASC,EAAmBC,EAAGC,GAClC,MAAMtH,EAAQqH,EAAEE,YAAcD,EAAEC,YAChC,GAAa,GAATvH,EACA,OAAO,EACX,MAAMwH,EAASH,EAAEI,iBAAiBH,GAAG,GACrC,OAAOE,GAAUxH,EAAQwH,EAC7B,CAoHO,SAASE,EAA0BC,GACtC,OAAsB,IAAfA,EAAmB,WAAgB,EAAIA,EAAc,CAChE,CAxKKX,EAAqBY,SACrBZ,EAAqBa,KACrBb,EAAqBc,WACrBd,EAAqBe,cACrBf,EAAqBgB,OACrBhB,EAAqBiB,WACrBjB,EAAqBkB,aACrBlB,EAAqBmB,cACrBnB,EAAqBoB,OACrBpB,EAAqBqB,MACrBrB,EAAqBsB,QACrBtB,EAAqBuB,UAGrBvB,EAAqBY,SACrBZ,EAAqBa,KACrBb,EAAqBc,WACrBd,EAAqBe,cACrBf,EAAqBgB,OACrBhB,EAAqBiB,WACrBjB,EAAqBkB,aACrBlB,EAAqBmB,cACrBnB,EAAqBoB,OACrBpB,EAAqBqB,MACrBrB,EAAqBsB,QACrBtB,EAAqBuB,UAGtBvB,EAAqBY,SACrBZ,EAAqBa,KACrBb,EAAqBgB,OAGrBhB,EAAqBY,SACrBZ,EAAqBc,WACrBd,EAAqBgB,OACrBhB,EAAqBqB,MAGrB,IAAyBG,QACzB,IAAyBC,YACzB,IAAyBC,0BACzB,IAAyBC,kBCxCtB,MAAMC,EAA+B,CACxC,CAAC7B,EAAmBwB,WAAY3H,GAEvBiI,EAA+B,CACxC,CAAC/B,EAAmBgC,aAAc,IAClC,CAAChC,EAAmBiC,aAAc,KAClC,CAACjC,EAAmBkC,WA2EjB,SAA2BC,EAAIC,GAClC,GAAID,EAAGlJ,SAAWmJ,EAAGnJ,OACjB,OAAO,EAEN,CACD,IAAIoJ,EAAO,EACX,IAAK,IAAIlJ,EAAI,EAAGA,EAAIgJ,EAAGlJ,OAAQE,IAC3BkJ,GAAQF,EAAGhJ,IAAMiJ,EAAGjJ,GAAK,EAAI,EACjC,OAAOkJ,EAAOF,EAAGlJ,MACrB,CACJ,GAnFaqJ,EAAiC,CAC1C,CAACpC,EAAqBY,UDwCnB,SAA0BP,EAAGC,GAChC,OAAOI,EAA0BN,EAAmBC,EAAGC,GAC3D,ECzCI,CAACN,EAAqBa,MDsDnB,SAAsBR,EAAGC,GAC5B,OAAOI,EARJ,SAAwBL,EAAGC,GAC9B,MAAMtH,EAAQqH,EAAEE,YAAcD,EAAEC,YAChC,OAAa,GAATvH,EACO,EAEJ,EADQqH,EAAEI,iBAAiBH,GAAG,GACjBtH,CACxB,CAEqCqJ,CAAehC,EAAGC,GACvD,ECvDI,CAACN,EAAqBc,YDmHnB,SAA4BT,EAAGC,GAClC,OAAOI,EARJ,SAA8BL,EAAGC,GACpC,MAAM3E,EAAMxD,KAAKwD,IAAI0E,EAAEE,YAAaD,EAAEC,aACtC,OAAW,GAAP5E,EACO,EACI0E,EAAEI,iBAAiBH,GAAG,GACrB3E,CACpB,CAEqC2G,CAAqBjC,EAAGC,GAC7D,ECpHI,CAACN,EAAqBe,eD4HnB,SAA+BV,EAAGC,GACrC,OAAOI,EARJ,SAAiCL,EAAGC,GACvC,MAAM1F,EAAMzC,KAAKyC,IAAIyF,EAAEE,YAAaD,EAAEC,aACtC,OAAW,GAAP3F,EACO,EACIyF,EAAEI,iBAAiBH,GAAG,GACrB1F,CACpB,CAEqC2H,CAAwBlC,EAAGC,GAChE,EC7HI,CAACN,EAAqBgB,QD6DnB,SAAwBX,EAAGC,GAC9B,OAAOI,EARJ,SAA0BL,EAAGC,GAChC,MAAMtH,EAAQqH,EAAEE,YAAcD,EAAEC,YAChC,OAAa,GAATvH,EACO,EACIqH,EAAEI,iBAAiBH,GAAG,GACrBnI,KAAK6B,KAAKhB,EAC9B,CAEqCwJ,CAAiBnC,EAAGC,GACzD,EC9DI,CAACN,EAAqBiB,YD2FnB,SAA4BZ,EAAGC,GAClC,OAAOI,EATJ,SAA8BL,EAAGC,GACpC,MAAMtH,EAAQqH,EAAEE,YAAcD,EAAEC,YAC1BkC,EAAYpC,EAAEE,YAAcD,EAAEC,YACpC,OAAiB,GAAbkC,EACO,EACIpC,EAAEI,iBAAiBH,GAAG,GACpBtH,GAAU,EAAIyJ,EACnC,CAEqCC,CAAqBrC,EAAGC,GAC7D,EC5FI,CAACN,EAAqBkB,cDqGnB,SAA8Bb,EAAGC,GACpC,OAAOI,EATJ,SAAgCL,EAAGC,GACtC,MAAMtH,EAAQqH,EAAEE,YAAcD,EAAEC,YAC1BkC,EAAYpC,EAAEE,YAAcD,EAAEC,YACpC,OAAiB,GAAbkC,EACO,GACIpC,EAAEI,iBAAiBH,GAAG,GACpBtH,EAAQyJ,GAAaA,CAC1C,CAEqCE,CAAuBtC,EAAGC,GAC/D,ECtGI,CAACN,EAAqBmB,eD8InB,SAA+Bd,EAAGC,GACrC,OAAOI,EAXJ,SAAiCL,EAAGC,GACvC,MAAME,EAASH,EAAEI,iBAAiBH,GAAG,GAC/BtH,EAAQqH,EAAEuC,WAAU,GAAQtC,EAAEsC,WAAU,GACxC9I,EAAMuG,EAAEtH,OACR8J,EAAO/I,EAAMd,EAAQwH,EAC3B,OAAKA,GAAU1G,GAAS+I,GAAQ/I,EACrB,EAEA0G,EAASxH,EAAQ6J,GAAQ,EAAI/I,EAAMd,EAClD,CAEqC8J,CAAwBzC,EAAGC,GAChE,EC/II,CAACN,EAAqBoB,QDgInB,SAAwBf,EAAGC,GAC9B,OAAOI,EAPJ,SAA0BL,EAAGC,GAChC,OAAgB,GAAZD,EAAEtH,OACK,EACIsH,EAAEI,iBAAiBH,GAAG,GACrBD,EAAEtH,MACtB,CAEqCgK,CAAiB1C,EAAGC,GACzD,ECjII,CAACN,EAAqBqB,OD4EnB,SAAuBhB,EAAGC,GAC7B,OAAOI,EANJ,SAAyBL,EAAGC,GAC/B,MAAMtH,EAAQqH,EAAEE,YAAcD,EAAEC,YAC1BC,EAASH,EAAEI,iBAAiBH,GAAG,GACrC,OAAOE,GAAU,EAAIxH,EAAQ,EAAIwH,EACrC,CAEqCwC,CAAgB3C,EAAGC,GACxD,EC7EI,CAACN,EAAqBsB,SDmEnB,SAAyBjB,EAAGC,GAC/B,OAAOD,EAAEE,YAAcD,EAAEC,YAAc,EAAIF,EAAEI,iBAAiBH,GAAG,EACrE,ECpEI,CAACN,EAAqBuB,WD4DnB,SAA2BlB,EAAGC,GACjC,OAAOnI,KAAK6B,KAAKqG,EAAEE,YAAcD,EAAEC,YAAc,EAAIF,EAAEI,iBAAiBH,GAAG,GAC/E,GC5Da2C,EAAiC,CAC1C,CAAChD,EAAqBiD,kBD6BnB,SAAkC7C,EAAGC,GAGxC,OAAOI,EAA0BN,EAFtB,IAAI,IAASC,EAAc,GAAXA,EAAEtH,QAClB,IAAI,IAASuH,EAAc,GAAXA,EAAEvH,SAEjC,GC/BaoK,EAA+B,CACxC,CAAChD,EAAmBiD,YD6IjB,SAAyB/C,EAAGC,GAC/B,OAAOnI,KAAKkL,IAAIhD,EAAIC,EACxB,GC7IagD,EAAmB,CAC5B,CAACpD,EAAwBqD,QAAS,CAC9B,CAACxD,EAAmBwB,WAAYK,EAA6B7B,EAAmBwB,YAEpF,CAACrB,EAAwBsD,QAAS,CAC9B,CAAC1D,EAAmBgC,aAAcD,EAA6B/B,EAAmBgC,aAClF,CAAChC,EAAmBiC,aAAcF,EAA6B/B,EAAmBiC,aAClF,CAACjC,EAAmBkC,WAAYH,EAA6B/B,EAAmBkC,YAEpF,CAAC9B,EAAwBuD,UAAW,CAChC,CAACzD,EAAqBY,UAAWwB,EAA+BpC,EAAqBY,UACrF,CAACZ,EAAqBa,MAAOuB,EAA+BpC,EAAqBa,MACjF,CAACb,EAAqBc,YAAasB,EAA+BpC,EAAqBc,YACvF,CAACd,EAAqBe,eAAgBqB,EAA+BpC,EAAqBe,eAC1F,CAACf,EAAqBgB,QAASoB,EAA+BpC,EAAqBgB,QACnF,CAAChB,EAAqBiB,YAAamB,EAA+BpC,EAAqBiB,YACvF,CAACjB,EAAqBkB,cAAekB,EAA+BpC,EAAqBkB,cACzF,CAAClB,EAAqBmB,eAAgBiB,EAA+BpC,EAAqBmB,eAC1F,CAACnB,EAAqBoB,QAASgB,EAA+BpC,EAAqBoB,QACnF,CAACpB,EAAqBqB,OAAQe,EAA+BpC,EAAqBqB,QAEtF,CAACnB,EAAwBwD,eAAgB,CACrC,CAAC,IAAyBlC,SAAU,IAAoB,IAAyBA,SACjF,CAAC,IAAyBC,aAAc,IAAoB,IAAyBA,aACrF,CAAC,IAAyBE,mBAAoB,IAAoB,IAAyBA,mBAC3F,CAAC,IAAyBD,2BAA4B,IAAoB,IAAyBA,4BAEvG,CAACxB,EAAwBhE,QAAS,CAC9B,CAACiE,EAAmBiD,YAAaD,EAA6BhD,EAAmBiD,aAErF,CAAClD,EAAwByD,UAAW,CAChC,CAAC1D,EAAqBiD,kBAAmBD,EAA+BhD,EAAqBiD,oBAGxFU,EAAmBC,OAAOC,KAAKR,GACvCS,QAAO,CAACC,EAAKC,KACd,IAAK,MAAMC,KAAOL,OAAOC,KAAKR,EAAiBW,IAC3CD,EAAIE,GAAOD,EACf,OAAOD,CAAG,GACX,CAAC,GA0BG,MAAMG,EAMT/J,YAAYgK,GACR1J,KAAK0J,OAASA,EACd1J,KAAK2J,SAAWT,EAAiBQ,EACrC,CAOAE,WAAWjJ,GACP,MAAMkJ,EAAOjB,EACb,IAAKiB,EAAKC,eAAe9J,KAAK2J,YAAcE,EAAK7J,KAAK2J,UAAUG,eAAe9J,KAAK0J,QAChF,MAAM,IAAI3L,MAAM,mBAAmBiC,KAAK0J,wBAAwB1J,KAAK2J,YACzE,OApC8BI,EAoCD/J,KAAK0J,OAnC/BR,EAAiBa,IAASvE,EAAwBwD,cAAcgB,WAoC/DH,EAAK7J,KAAK2J,UAAU3J,KAAK0J,QAAQ/I,GACjCkJ,EAAK7J,KAAK2J,UAAU3J,KAAK0J,QAtC9B,IAA+BK,CAuClC,CAOAE,2BAA2BN,GACvB,OAAOR,OAAOC,KAAKR,EAAiBe,GACxC,CAIWO,+BACP,OAAOf,OAAOC,KAAKR,EACvB,ECpHG,SAASuB,EAAWjF,EAAGxH,GAC1B,OAAOD,KAAKE,MAAMD,IAAWwH,EACjC,CAIO,SAASkF,EAAQ1M,GACpB,OAAOA,GACX,CAcO,SAAS2M,EAAMnF,GAClB,MAAMoF,EAAS,GACf,IAAK,IAAI/L,EAAI,EAAGA,EAAI2G,EAAG3G,IACnB+L,EAAOC,UAAKC,GAEhB,OAAOF,CACX,CAIO,SAAS9M,EAAM0H,GAClB,OAAOmF,EAAMnF,GAAGnG,KAAI,CAAC0L,EAAGlM,IAAMA,GAClC,CAIO,SAASmM,EAAOxF,EAAGyF,GACtB,OAAON,EAAMnF,GAAGnG,KAAI,IAAM4L,GAC9B,CAIO,SAASC,EAAM1F,GAClB,OAAOwF,EAAOxF,EAAG,EACrB,CAwBO,SAAS2F,EAAKC,GACjB,OAPG,SAAaA,GAChB,OAAOA,EAAMzB,QAAO,CAAC0B,EAAKvB,IAAQuB,EAAMvB,GAC5C,CAKWuB,CAAID,GAASA,EAAMzM,MAC9B,CAIO,SAAS,EAAIyM,GAChB,IAAI5K,EAAM,EACV,IAAK,IAAI3B,EAAI,EAAGA,EAAIuM,EAAMzM,OAAQE,IAC9B2B,EAAM4K,EAAMvM,GAAK2B,EAAM4K,EAAMvM,GAAK2B,EAEtC,OAAOA,CACX,CAkBO,SAAS8K,EAAgBC,EAAUC,EAAUxN,GAChD,MAAMyB,EAASyL,EAAMK,GACrB,IAAK,IAAI1M,EAAI,EAAGA,EAAI0M,EAAU1M,IAAK,CAC/B,IAAI4M,GAAe,EACnB,KAAOA,GAAc,CACjB,MAAMlM,EAAIkL,EAAWe,EAAUxN,GAC/B,IAAI0N,GAAS,EACb,IAAK,IAAIC,EAAI,EAAGA,EAAI9M,EAAG8M,IACnB,GAAIpM,IAAME,EAAOkM,GAAI,CACjBD,GAAS,EACT,KACJ,CAECA,IACDD,GAAe,GAEnBhM,EAAOZ,GAAKU,CAChB,CACJ,CACA,OAAOE,CACX,CAIO,SAASmM,EAAU3F,EAAG4F,EAAGC,GAC5B,MAAMC,EAAO,GACb,IAAIC,EAAQ,EACR/I,EAAQ,EACZ,GAAIgD,EAAEtH,SAAWkN,EAAIC,EACjB,MAAM,IAAIzN,MAAM,6CAEpB,IAAK,IAAIQ,EAAI,EAAGA,EAAIgN,EAAGhN,IAAK,CACxB,MAAMoN,EAAM,GACZ,IAAK,IAAI1M,EAAI,EAAGA,EAAIuM,EAAGvM,IACnB0M,EAAIpB,KAAK5E,EAAEhD,IACXA,GAAS,EAEb8I,EAAKlB,KAAKoB,GACVD,GAAS,CACb,CACA,OAAOD,CACX,CCrIO,SAASG,EAASC,EAASrM,GAC9B,MAAMsM,EAAcC,GACT,EAAYF,GAAS9M,KAAI,IACrB,EAAaS,EAAMuM,KAG5BC,EAAO,GAIb,OAHAA,EAAKzB,KAAKuB,GAAY,IACtBE,EAAKzB,KAAKuB,EAAWG,MACrBD,EAAKzB,KAAKuB,EAAW,IACdE,CACX,CAMO,SAAS,EAAgBf,EAAUC,EAAUxN,GAChD,MAAMyB,EAAS,EAAY8L,GAC3B,IAAK,IAAI1M,EAAI,EAAGA,EAAI0M,EAAU1M,IAAK,CAC/B,IAAI4M,GAAe,EACflM,EAAI,EACR,KAAOkM,GAAc,CACjBlM,EAAI,EAAiBiM,EAAUxN,GAC/B,IAAI0N,GAAS,EACb,IAAK,IAAIC,EAAI,EAAGA,EAAI9M,EAAG8M,IACnB,GAAIpM,IAAME,EAAOkM,GAAI,CACjBD,GAAS,EACT,KACJ,CAECA,IACDD,GAAe,EACvB,CACAhM,EAAOZ,GAAKU,CAChB,CACA,OAAOE,CACX,CAQO,SAAS+M,EAASF,EAAMG,EAAKC,EAAQzJ,EAAO0J,GAC/CF,EAAM1O,KAAKE,MAAMwO,GACjB,MAAMG,EAAUN,EAAK,GAAGG,GAClBI,EAAUP,EAAK,GAAGG,GAExB,GADcH,EAAK,GAAGG,GAClBC,GAAUG,EAAQ,GAClB,OAAO,EAGX,IAAK,IAAIhO,EAAI,EAAGA,EAAI+N,EAAQjO,OAAQE,IAChC,GAAIoE,IAAU2J,EAAQ/N,GAClB,OAAO,EAGf,OAAOiO,EAAkBR,EAAMG,EAAKC,EAAQzJ,EAAO0J,EACvD,CAQO,SAASG,EAAkBR,EAAMG,EAAKC,EAAQzJ,EAAO0J,GACxD,MAAMC,EAAUN,EAAK,GAAGG,GAClBI,EAAUP,EAAK,GAAGG,GAClBM,EAAQT,EAAK,GAAGG,GACtB,GAAIC,GAAUG,EAAQ,GAClB,OAAO,EAGXA,EAAQ,GAAKH,EACbE,EAAQ,GAAK3J,EACb8J,EAAM,GAAKJ,EAEX,IAAI9N,EAAI,EACJmO,EAAQ,EACZ,OAAa,CACT,MAAMC,EAAM,EAAIpO,EAAI,EACdqO,EAAMD,EAAM,EACZE,EAAab,EAAK,GAAG,GAAG3N,OAC9B,GAAIsO,GAAOE,EACP,MAEC,GAAID,GAAOC,EAAY,CACxB,KAAIN,EAAQI,GAAOP,GAIf,MAHAM,EAAQC,CAKhB,MACK,GAAIJ,EAAQI,IAAQJ,EAAQK,GAAM,CACnC,KAAIR,EAASG,EAAQI,IAIjB,MAHAD,EAAQC,CAKhB,KACK,CACD,KAAIP,EAASG,EAAQK,IAIjB,MAHAF,EAAQE,CAKhB,CACAL,EAAQhO,GAAKgO,EAAQG,GACrBJ,EAAQ/N,GAAK+N,EAAQI,GACrBD,EAAMlO,GAAKkO,EAAMC,GACjBnO,EAAImO,CACR,CAIA,OAHAH,EAAQhO,GAAK6N,EACbE,EAAQ/N,GAAKoE,EACb8J,EAAMlO,GAAK8N,EACJ,CACX,CAMO,SAASS,EAAgBC,EAAcC,EAAWC,EAAYC,EAAexP,GAChF,MAAMyP,EAAqBvB,EAASoB,EAAWE,GAC/C,IAAK,IAAI3O,EAAI,EAAGA,EAAIyO,EAAWzO,IAC3B,IAAK,IAAIU,EAAI,EAAGA,EAAIgO,EAAYhO,IAAK,CACjC,GAAI8N,EAAa,GAAGxO,GAAGU,GAAK,EACxB,SAEJ,MAAMmO,EAAML,EAAa,GAAGxO,GAAGU,GACzBoO,EAAMN,EAAa,GAAGxO,GAAGU,GACzByF,EAAI,EAAchH,GACxBwO,EAASiB,EAAoB5O,EAAGmG,EAAG0I,EAAKC,GACxCnB,EAASiB,EAAoBC,EAAK1I,EAAGnG,EAAG8O,GACxCN,EAAa,GAAGxO,GAAGU,GAAK,CAC5B,CAEJ,OAAOkO,CACX,CAOO,SAASG,EAAWtB,GACvB,MAAMM,EAAUN,EAAK,GACfO,EAAUP,EAAK,GACrB,IAAK,IAAIzN,EAAI,EAAGA,EAAI+N,EAAQjO,OAAQE,IAAK,CACrC,MAAMgP,EAAUjB,EAAQ/N,GAClBiP,EAAWjB,EAAQhO,GACzB,IAAK,IAAIU,EAAI,EAAGA,EAAIsO,EAAQlP,OAAS,EAAGY,IAAK,CACzC,MAAMwO,EAAeF,EAAQlP,OAASY,EAAI,EACpCyO,EAAgBF,EAASnP,OAASY,EAAI,EACtC0O,EAAQJ,EAAQ,GACtBA,EAAQ,GAAKA,EAAQE,GACrBF,EAAQE,GAAgBE,EACxB,MAAMC,EAAQJ,EAAS,GACvBA,EAAS,GAAKA,EAASE,GACvBF,EAASE,GAAiBE,EAC1BC,EAASL,EAAUD,EAASG,EAAe,EAC/C,CACJ,CACA,MAAO,CAAEpB,UAASC,UACtB,CAMA,SAASsB,EAASC,EAAOC,EAAOC,EAASC,GACrC,KAAa,EAANA,EAAU,EAAID,GAAS,CAC1B,MAAME,EAAkB,EAAND,EAAU,EACtBE,EAAaD,EAAY,EAC/B,IAAIE,EAAOH,EAOX,GANIH,EAAMM,GAAQN,EAAMI,KACpBE,EAAOF,GAEPC,EAAaH,GAAWF,EAAMM,GAAQN,EAAMK,KAC5CC,EAAOD,GAEPC,IAASH,EACT,MAEC,CACD,MAAMN,EAAQG,EAAMG,GACpBH,EAAMG,GAAOH,EAAMM,GACnBN,EAAMM,GAAQT,EACd,MAAMC,EAAQG,EAAME,GACpBF,EAAME,GAAOF,EAAMK,GACnBL,EAAMK,GAAQR,EACdK,EAAMG,CACV,CACJ,CACJ,CAIO,SAASC,EAAgBrC,EAAMG,GAClC,MAAMmC,EAAMtC,EAAK,GAAGG,GACd1E,EAAOuE,EAAK,GAAGG,GACfE,EAAOL,EAAK,GAAGG,GACrB,IAAIoC,EAAUtC,IACVuC,GAAe,EACnB,IAAK,IAAIjQ,EAAI,EAAGA,EAAI+P,EAAIjQ,OAAQE,IACZ,IAAZ8N,EAAK9N,IAAYkJ,EAAKlJ,GAAKgQ,IAC3BA,EAAU9G,EAAKlJ,GACfiQ,EAAcjQ,GAGtB,OAAIiQ,GAAe,GACfnC,EAAKmC,GAAe,EACb/Q,KAAKE,MAAM2Q,EAAIE,MAGd,CAEhB,CCtOO,MAAMC,GACT/O,YAAY+L,EAAMiD,EAAMlO,EAAQmO,GAI5B,GAHA3O,KAAK4O,QAAU,IAAIC,IACnB7O,KAAK8O,MAAQ,EACb9O,KAAK+O,MAAQ,EACTtD,EAAKpN,SAAWqQ,EAAKrQ,QAAUoN,EAAKpN,SAAWmC,EAAOnC,OACtD,MAAM,IAAIN,MAAM,8DAGpBiC,KAAK8O,MAAQH,EAAK,GAClB3O,KAAK+O,MAAQJ,EAAK,GAClB,IAAK,IAAIpQ,EAAI,EAAGA,EAAIiC,EAAOnC,OAAQE,IAAK,CACpC,MAAM4N,EAAMV,EAAKlN,GACXoN,EAAM+C,EAAKnQ,GACjByB,KAAKgP,UAAU7C,EAAKR,GACpB,MAAMpC,EAAMvJ,KAAKiP,QAAQ9C,EAAKR,GAC9B3L,KAAK4O,QAAQrM,IAAIgH,EAAK,CAAE7G,MAAOlC,EAAOjC,GAAI4N,MAAKR,OACnD,CACJ,CACAsD,QAAQ9C,EAAKR,GACT,MAAO,GAAGQ,KAAOR,GACrB,CACAqD,UAAU7C,EAAKR,GAEX,KADqBQ,EAAMnM,KAAK8O,OAASnD,EAAM3L,KAAK+O,OAEhD,MAAM,IAAIhR,MAAM,wDAExB,CACAwE,IAAI4J,EAAKR,EAAKjJ,GACV1C,KAAKgP,UAAU7C,EAAKR,GACpB,MAAMpC,EAAMvJ,KAAKiP,QAAQ9C,EAAKR,GACzB3L,KAAK4O,QAAQM,IAAI3F,GAIlBvJ,KAAK4O,QAAQO,IAAI5F,GAAK7G,MAAQA,EAH9B1C,KAAK4O,QAAQrM,IAAIgH,EAAK,CAAE7G,QAAOyJ,MAAKR,OAK5C,CACAwD,IAAIhD,EAAKR,EAAKyD,EAAe,GAEzB,MAAM7F,EAAMvJ,KAAKiP,QAAQ9C,EAAKR,GAC9B,OAAI3L,KAAK4O,QAAQM,IAAI3F,GACVvJ,KAAK4O,QAAQO,IAAI5F,GAAK7G,MAGtB0M,CAEf,CACAC,OAAOC,GAAU,GACb,MAAMC,EAAe,IAAIzQ,MAAMkB,KAAK4O,QAAQpP,MAAMX,KAAK,MACvD,IAAIN,EAAI,EAeR,OAdAyB,KAAK4O,QAAQnM,SAAQC,IACjB6M,EAAahR,KAAOmE,CAAK,IAEzB4M,GAEAC,EAAaC,MAAK,CAACjE,EAAGC,IACdD,EAAEY,MAAQX,EAAEW,IACLZ,EAAEI,IAAMH,EAAEG,IAGVJ,EAAEY,IAAMX,EAAEW,MAItBoD,CACX,CACAE,UACI,MAAO,CAACzP,KAAK8O,MAAO9O,KAAK+O,MAC7B,CACAW,UACI,OAAO5Q,MAAM6Q,KAAK3P,KAAK4O,SAAS,EAAErF,EAAK7G,KAAWA,EAAMyJ,KAE5D,CACAyD,UACI,OAAO9Q,MAAM6Q,KAAK3P,KAAK4O,SAAS,EAAErF,EAAK7G,KAAWA,EAAMiJ,KAE5D,CACAkE,YACI,OAAO/Q,MAAM6Q,KAAK3P,KAAK4O,SAAS,EAAErF,EAAK7G,KAAWA,EAAMA,OAE5D,CACAD,QAAQqN,GACJ9P,KAAK4O,QAAQnM,SAAQC,GAASoN,EAAGpN,EAAMA,MAAOA,EAAMyJ,IAAKzJ,EAAMiJ,MACnE,CACA5M,IAAI+Q,GACA,MAAMC,EAAO,IAAIzS,aAAa0C,KAAK4O,QAAQpP,MAC3C,IAAIjB,EAAI,EACRyB,KAAK4O,QAAQnM,SAAQC,IACjBqN,EAAKxR,KAAOuR,EAAGpN,EAAMA,MAAOA,EAAMyJ,IAAKzJ,EAAMiJ,IAAI,IAErD,MAAMgD,EAAO,CAAC3O,KAAK8O,MAAO9O,KAAK+O,OAC/B,OAAO,IAAIN,GAAazO,KAAK0P,UAAW1P,KAAK4P,UAAWG,EAAMpB,EAClE,CACAqB,UACI,MACM1F,EADO,EAAYtK,KAAK8O,OACV/P,KAAI,IACb,EAAYiB,KAAK+O,SAK5B,OAHA/O,KAAK4O,QAAQnM,SAAQC,IACjB4H,EAAO5H,EAAMyJ,KAAKzJ,EAAMiJ,KAAOjJ,EAAMA,KAAK,IAEvC4H,CACX,EAKG,SAAS,GAAU1L,GACtB,MAAMqR,EAAUrR,EAAO8Q,UACjBQ,EAAUtR,EAAOgR,UACjBO,EAAUvR,EAAOiR,YACjBO,EAASF,EAAQ7R,OACjBqQ,EAAO,IAAI2B,WAAWD,GACtB3E,EAAO,IAAI4E,WAAWD,GACtBL,EAAO,IAAIzS,aAAa8S,GAC9B1B,EAAKnM,IAAI0N,GACTxE,EAAKlJ,IAAI2N,GACTH,EAAKxN,IAAI4N,GACT,MAAMxB,EAAO,CAAC/P,EAAOmQ,MAAOnQ,EAAOkQ,OACnC,OAAO,IAAIL,GAAahD,EAAMiD,EAAMqB,EAAMpB,EAC9C,CAeO,SAAS2B,GAAiB/E,EAAGC,GAChC,OAAO+E,GAAYhF,EAAGC,GAAG,CAAC7F,EAAGC,IAAMD,EAAIC,GAC3C,CAIO,SAAS4K,GAAIjF,EAAGC,GACnB,OAAO+E,GAAYhF,EAAGC,GAAG,CAAC7F,EAAGC,IAAMD,EAAIC,GAC3C,CAIO,SAAS6K,GAASlF,EAAGC,GACxB,OAAO+E,GAAYhF,EAAGC,GAAG,CAAC7F,EAAGC,IAAMD,EAAIC,GAC3C,CAUO,SAAS8K,GAAenF,EAAGoF,GAC9B,OAAOpF,EAAExM,KAAK2D,GACHA,EAAQiO,GAEvB,CAIO,SAASC,GAAeC,GAC3B,MAAMC,EAAc,IAAIC,IAClBvQ,EAASqQ,EAAEhB,YACXpE,EAAOoF,EAAEnB,UACThB,EAAOmC,EAAEjB,UACf,IAAK,IAAIrR,EAAI,EAAGA,EAAIiC,EAAOnC,OAAQE,IACb,IAAdiC,EAAOjC,IACPuS,EAAYN,IAAIjS,GAGxB,MAAMyS,EAAoB,CAACvG,EAAG9H,KAAWmO,EAAY5B,IAAIvM,GACnDsO,EAAazQ,EAAO0Q,OAAOF,GAC3BG,EAAW1F,EAAKyF,OAAOF,GACvBI,EAAW1C,EAAKwC,OAAOF,GAC7B,OAAO,IAAIvC,GAAa0C,EAAUC,EAAUH,EAAYJ,EAAEpB,UAC9D,CAIO,SAAS,GAAUoB,EAAGQ,EAAW,MACpC,MAAMC,EAASC,GAAQF,GACjBG,EAAY,IAAI3C,IACtBgC,EAAEpO,SAAQ,CAACgI,EAAG0B,EAAKR,KACf,MAAM+C,EAAO8C,EAAUrC,IAAIhD,IAAQ,GACnCuC,EAAKnE,KAAKoB,GACV6F,EAAUjP,IAAI4J,EAAKuC,EAAK,IAE5B,MAAM+C,EAAa,IAAIhD,GAAa,GAAI,GAAI,GAAIoC,EAAEpB,WAClD,IAAK,IAAItD,KAAOqF,EAAUpI,OAAQ,CAC9B,MAAMsF,EAAO8C,EAAUrC,IAAIhD,GAAKqD,OAE1BkC,EAAOJ,EADA5C,EAAK3P,KAAI4M,GAAOkF,EAAE1B,IAAIhD,EAAKR,MAExC,IAAK,IAAIpN,EAAI,EAAGA,EAAImT,EAAKrT,OAAQE,IAC7BkT,EAAWlP,IAAI4J,EAAKuC,EAAKnQ,GAAImT,EAAKnT,GAE1C,CACA,OAAOkT,CACX,CACA,MAAMF,GAAU,CACZ,IAA6BI,IACzB,IAAIzR,GAAM,IACV,IAAK,IAAI3B,EAAI,EAAGA,EAAIoT,EAAGtT,OAAQE,IAC3B2B,EAAMyR,EAAGpT,GAAK2B,EAAMyR,EAAGpT,GAAK2B,EAEhC,OAAOyR,EAAG5S,KAAI4G,GAAKA,EAAIzF,GAAI,EAE/B,GAA2ByR,IACvB,IAAI5G,EAAM,EACV,IAAK,IAAIxM,EAAI,EAAGA,EAAIoT,EAAGtT,OAAQE,IAC3BwM,GAAO4G,EAAGpT,GAEd,OAAOoT,EAAG5S,KAAI4G,GAAKA,EAAIoF,GAAI,EAE/B,GAA2B4G,IACvB,IAAI5G,EAAM,EACV,IAAK,IAAIxM,EAAI,EAAGA,EAAIoT,EAAGtT,OAAQE,IAC3BwM,GAAO4G,EAAGpT,IAAM,EAEpB,OAAOoT,EAAG5S,KAAI4G,GAAKlI,KAAK6B,KAAKqG,GAAK,EAAIoF,IAAK,GAMnD,SAASwF,GAAYhF,EAAGC,EAAGoG,GACvB,MAAMC,EAAU,IAAId,IACdtF,EAAO,GACPiD,EAAO,GACPqB,EAAO,GACP+B,EAAU,CAAC3F,EAAKR,KAClBF,EAAKlB,KAAK4B,GACVuC,EAAKnE,KAAKoB,GACV,MAAMoG,EAAYH,EAAGrG,EAAE4D,IAAIhD,EAAKR,GAAMH,EAAE2D,IAAIhD,EAAKR,IACjDoE,EAAKxF,KAAKwH,EAAU,EAElBC,EAAUzG,EAAEsE,YACZoC,EAAQ1G,EAAEmE,UACVwC,EAAQ3G,EAAEqE,UAChB,IAAK,IAAIrR,EAAI,EAAGA,EAAIyT,EAAQ3T,OAAQE,IAAK,CACrC,MAAM4N,EAAM8F,EAAM1T,GACZoN,EAAMuG,EAAM3T,GACZgL,EAAM,GAAG4C,KAAOR,IACtBkG,EAAQrB,IAAIjH,GACZuI,EAAQ3F,EAAKR,EACjB,CACA,MAAMwG,EAAU3G,EAAEqE,YACZuC,EAAQ5G,EAAEkE,UACV2C,EAAQ7G,EAAEoE,UAChB,IAAK,IAAIrR,EAAI,EAAGA,EAAI4T,EAAQ9T,OAAQE,IAAK,CACrC,MAAM4N,EAAMiG,EAAM7T,GACZoN,EAAM0G,EAAM9T,GACZgL,EAAM,GAAG4C,KAAOR,IAClBkG,EAAQ3C,IAAI3F,IAEhBuI,EAAQ3F,EAAKR,EACjB,CACA,MAAMgD,EAAO,CAACpD,EAAEuD,MAAOvD,EAAEwD,OACzB,OAAO,IAAIN,GAAahD,EAAMiD,EAAMqB,EAAMpB,EAC9C,CAOO,SAAS2D,GAAO3M,GACnB,MAAMiJ,EAAU,GAChBjJ,EAAElD,SAAQ,CAACC,EAAOyJ,EAAKR,KACnBiD,EAAQrE,KAAK,CAAE7H,QAAOyJ,MAAKR,OAAM,IAErCiD,EAAQY,MAAK,CAACjE,EAAGC,IACTD,EAAEY,MAAQX,EAAEW,IACLZ,EAAEI,IAAMH,EAAEG,IAGVJ,EAAEY,IAAMX,EAAEW,MAGzB,MAAMG,EAAU,GACV9L,EAAS,GACT+R,EAAS,GACf,IAAIC,GAAc,EAClB,IAAK,IAAIjU,EAAI,EAAGA,EAAIqQ,EAAQvQ,OAAQE,IAAK,CACrC,MAAM,IAAE4N,EAAG,IAAER,EAAG,MAAEjJ,GAAUkM,EAAQrQ,GAChC4N,IAAQqG,IACRA,EAAarG,EACboG,EAAOhI,KAAKhM,IAEhB+N,EAAQ/B,KAAKoB,GACbnL,EAAO+J,KAAK7H,EAChB,CACA,MAAO,CAAE4J,UAAS9L,SAAQ+R,SAC9B,CCzQO,MAAME,GACT/S,YAAYgT,EAAaC,EAASC,EAAUtG,GACxCtM,KAAK0S,YAAcA,EACnB1S,KAAK2S,QAAUA,EACf3S,KAAK4S,SAAWA,EAChB5S,KAAKsM,QAAUA,CACnB,EAKG,SAASuG,GAAW1Q,EAAM8K,EAAY6F,EAAQpV,GACjD,MAAMqV,EAAWtV,KAAKyC,IAAI,GAAI+M,GACxB+F,EAAQ,EACHF,GACN/T,KAAI,CAAC0L,EAAGlM,IAQjB,SAAkB4D,EAAM4Q,EAAW,GAAI7N,EAAGxH,GAGtC,OADauV,GAAkB9Q,EADf,EAAYA,EAAK9D,QACa0U,EAAU7N,EAAGxH,EAE/D,CAZuBwV,CAAS/Q,EAAM4Q,EAAUxU,EAAGb,KACzCyV,EAASH,EAAMjU,KAAIqU,GAoG7B,SAAqBA,EAAML,GACvB,MAAMM,EAASC,GAASF,GAClBG,EAAUC,GAAUJ,GAEpBV,EAAc,EACTW,GACNtU,KAAI,IAAMqU,EAAKK,WAAa,EAAI,IAC/Bd,EAAU,EAAYU,GACtBT,EAAW,EAAYS,GAAQtU,KAAI,IAAM,EAAE,GAAI,KAC/CuN,EAAU,EACLiH,GACNxU,KAAI,IAAM,EAAYgU,GAAUhU,KAAI,KAAO,MAEhD,OADA2U,GAAiBN,EAAMV,EAAaC,EAASC,EAAUtG,EAAS,EAAG,GAC5D,IAAImG,GAASC,EAAaC,EAASC,EAAUtG,EACxD,CAlHqCqH,CAAYP,EAAML,KACnD,OAAOI,CACX,CAUA,SAASF,GAAkB9Q,EAAMmK,EAASyG,EAAW,GAAI7U,EAAGR,GACxD,GAAI4O,EAAQjO,OAAS0U,EAAU,CAC3B,MAAMa,EAoBd,SAAwCzR,EAAMmK,EAAS5O,GAGnD,IAAImW,EAAY,EAAiBvH,EAAQjO,OAAQX,GAC7CoW,EAAa,EAAiBxH,EAAQjO,OAAQX,GAClDoW,GAAcD,IAAcC,EAAa,EAAI,EAC7CA,GAA0BxH,EAAQjO,OAClC,MAAM0V,EAAOzH,EAAQuH,GACfG,EAAQ1H,EAAQwH,GAGtB,IAAIG,EAAmB,EACnBC,EAAmB,EACvBA,EAAmB/R,EAAK4R,GAAQ5R,EAAK6R,GACrCC,GACKC,GAAoB/R,EAAK4R,GAAQ5R,EAAK6R,IAAW,EAItD,IAAIG,EAAQ,EACRC,EAAS,EACb,MAAMC,EAAO,EAAY/H,EAAQjO,QACjC,IAAK,IAAIE,EAAI,EAAGA,EAAI+N,EAAQjO,OAAQE,IAAK,CACrC,IAAI+V,EAASL,EACbK,GAAUJ,EAAmB/R,EAAKmK,EAAQ/N,IAC3B,IAAX+V,GACAD,EAAK9V,GAAK,EAAiB,EAAGb,GACd,IAAZ2W,EAAK9V,GACL4V,GAAS,EAGTC,GAAU,GAGTE,EAAS,GACdD,EAAK9V,GAAK,EACV4V,GAAS,IAGTE,EAAK9V,GAAK,EACV6V,GAAU,EAElB,CAEA,MAAMG,EAAc,EAAYJ,GAC1BK,EAAe,EAAYJ,GAEjCD,EAAQ,EACRC,EAAS,EACT,IAAK,IAAI7V,EAAI,EAAGA,EAAI8V,EAAKhW,OAAQE,IACb,IAAZ8V,EAAK9V,IACLgW,EAAYJ,GAAS7H,EAAQ/N,GAC7B4V,GAAS,IAGTK,EAAaJ,GAAU9H,EAAQ/N,GAC/B6V,GAAU,GAGlB,MAAO,CACHG,cACAC,eACAf,WAAYS,EACZO,OAAQR,EAEhB,CArF6BS,CAA+BvS,EAAMmK,EAAS5O,IAC7D,YAAE6W,EAAW,aAAEC,EAAY,WAAEf,EAAU,OAAEgB,GAAWb,EAI1D,MADa,CAAE1F,UAFG+E,GAAkB9Q,EAAMoS,EAAaxB,EAAU7U,EAAI,EAAGR,GAE9CyQ,WADP8E,GAAkB9Q,EAAMqS,EAAczB,EAAU7U,EAAI,EAAGR,GACpCiX,QAAQ,EAAOlB,aAAYgB,SAErE,CAGI,MADa,CAAEnI,UAASqI,QAAQ,EAGxC,CA0FA,SAASjB,GAAiBN,EAAMV,EAAaC,EAASC,EAAUtG,EAASsI,EAASC,GAC9E,GAAIzB,EAAKuB,OAML,OALA/B,EAASgC,GAAS,IAAMC,EAGxBvI,EAAQuI,GAASC,OAAO,EAAG1B,EAAK9G,QAAQjO,UAAW+U,EAAK9G,SAEjD,CAAEsI,UAASC,QADlBA,GAAW,GAGV,CACDnC,EAAYkC,GAAWxB,EAAKK,WAC5Bd,EAAQiC,GAAWxB,EAAKqB,OACxB7B,EAASgC,GAAS,GAAKA,EAAU,EACjC,MAAMG,EAAaH,EACnB,IAAII,EAAMtB,GAAiBN,EAAKlF,UAAWwE,EAAaC,EAASC,EAAUtG,EAASsI,EAAU,EAAGC,GAKjG,OAJAD,EAAUI,EAAIJ,QACdC,EAAUG,EAAIH,QACdjC,EAASmC,GAAY,GAAKH,EAAU,EACpCI,EAAMtB,GAAiBN,EAAKjF,WAAYuE,EAAaC,EAASC,EAAUtG,EAASsI,EAAU,EAAGC,GACvF,CAAED,QAASI,EAAIJ,QAASC,QAASG,EAAIH,QAChD,CACJ,CACA,SAASvB,GAASF,GACd,OAAIA,EAAKuB,OACE,EAGA,EAAIrB,GAASF,EAAKlF,WAAaoF,GAASF,EAAKjF,WAE5D,CACA,SAASqF,GAAUJ,GACf,OAAIA,EAAKuB,OACE,EAGAnB,GAAUJ,EAAKlF,WAAasF,GAAUJ,EAAKjF,WAE1D,CAyBA,SAAS8G,GAAWxB,EAAYgB,EAAQS,EAAOxX,GAC3C,IAAI4W,EAASG,EAEb,OADAH,GAAUb,EAAayB,EACR,IAAXZ,EACa,EAAiB,EAAG5W,GAG5B4W,EAAS,EACP,EAGA,CAEf,CAIO,SAASa,GAAeD,EAAO9B,EAAM1V,GACxC,IAAI0X,EAAO,EACX,KAAOhC,EAAKR,SAASwC,GAAM,GAAK,GAGxBA,EADS,IADAH,GAAW7B,EAAKV,YAAY0C,GAAOhC,EAAKT,QAAQyC,GAAOF,EAAOxX,GAEhE0V,EAAKR,SAASwC,GAAM,GAGpBhC,EAAKR,SAASwC,GAAM,GAGnC,MAAMzS,GAAS,EAAIyQ,EAAKR,SAASwC,GAAM,GACvC,OAAOhC,EAAK9G,QAAQ3J,EACxB,CCxRA,MAAM,GAAWwG,OAAOkM,UAAUrL,SAEnB,SAASsL,GAAWC,GACjC,OAAO,GAASC,KAAKD,GAAQE,SAAS,SACxC,CCIe,SAASC,GACtBvT,EACAwT,EACAC,GAEA,IAAIxT,EAAQ,EACZ,MAAMyT,EAAOD,EAAsBD,GAEnC,IAAK,IAAIpX,EAAI,EAAGA,EAAI4D,EAAKwD,EAAEtH,OAAQE,IACjC6D,GAAS3E,KAAKkL,IAAIxG,EAAKyD,EAAErH,GAAKsX,EAAK1T,EAAKwD,EAAEpH,KAG5C,OAAO6D,CACT,CCrBA,MAAM,GAAW+G,OAAOkM,UAAUrL,SAO3B,SAAS,GAAWtH,GACvB,OAAO,GAAS8S,KAAK9S,GAAO+S,SAAS,SACzC,CCTA,MAAM,GAAWtM,OAAOkM,UAAUrL,SAO3B,SAAS,GAAWtH,GACvB,OAAO,GAAS8S,KAAK9S,GAAO+S,SAAS,SACzC,CCTA,MAAM,GAAWtM,OAAOkM,UAAUrL,SCAlC,MAAM,GAAWb,OAAOkM,UAAUrL,SCIlC,SAAS8L,GAAQhL,GACf,IAQIR,EARAvH,EAAUgT,UAAU1X,OAAS,QAAsBmM,IAAjBuL,UAAU,GAAmBA,UAAU,GAAK,CAAC,EAEnF,IAAK,GAAWjL,GACd,MAAM,IAAIkL,UAAU,0BACf,GAAqB,IAAjBlL,EAAMzM,OACf,MAAM,IAAI2X,UAAU,2BAKtB,QAAuBxL,IAAnBzH,EAAQuH,OAAsB,CAChC,IAAK,GAAWvH,EAAQuH,QACtB,MAAM,IAAI0L,UAAU,+CAGtB1L,EAASvH,EAAQuH,MACnB,MACEA,EAAS,IAAIxL,MAAMgM,EAAMzM,QAG3B,IAAI4X,ECvBN,SAAanL,GACX,IFIyBpI,EEJrBK,EAAUgT,UAAU1X,OAAS,QAAsBmM,IAAjBuL,UAAU,GAAmBA,UAAU,GAAK,CAAC,EAEnF,GFEyBrT,EEFToI,GFGP,GAAS0K,KAAK9S,GAAO+S,SAAS,UEFrC,MAAM,IAAIO,UAAU,0BAGtB,GAAqB,IAAjBlL,EAAMzM,OACR,MAAM,IAAI2X,UAAU,2BAGtB,IAAIE,EAAqBnT,EAAQoT,UAC7BA,OAAmC,IAAvBD,EAAgC,EAAIA,EAChDE,EAAmBrT,EAAQsT,QAC3BA,OAA+B,IAArBD,EAA8BtL,EAAMzM,OAAS+X,EAE3D,GAAID,EAAY,GAAKA,GAAarL,EAAMzM,SAAWmD,OAAO8U,UAAUH,GAClE,MAAM,IAAIpY,MAAM,4DAGlB,GAAIsY,GAAWF,GAAaE,EAAUvL,EAAMzM,SAAWmD,OAAO8U,UAAUD,GACtE,MAAM,IAAItY,MAAM,iFAKlB,IAFA,IAAIwY,EAAWzL,EAAMqL,GAEZ5X,EAAI4X,EAAY,EAAG5X,EAAI8X,EAAS9X,IACnCuM,EAAMvM,GAAKgY,IAAUA,EAAWzL,EAAMvM,IAG5C,OAAOgY,CACT,CDRmBtV,CAAI6J,GACjB0L,EExBN,SAAa1L,GACX,IJIyBpI,EIJrBK,EAAUgT,UAAU1X,OAAS,QAAsBmM,IAAjBuL,UAAU,GAAmBA,UAAU,GAAK,CAAC,EAEnF,GJEyBrT,EIFToI,GJGP,GAAS0K,KAAK9S,GAAO+S,SAAS,UIFrC,MAAM,IAAIO,UAAU,0BAGtB,GAAqB,IAAjBlL,EAAMzM,OACR,MAAM,IAAI2X,UAAU,2BAGtB,IAAIE,EAAqBnT,EAAQoT,UAC7BA,OAAmC,IAAvBD,EAAgC,EAAIA,EAChDE,EAAmBrT,EAAQsT,QAC3BA,OAA+B,IAArBD,EAA8BtL,EAAMzM,OAAS+X,EAE3D,GAAID,EAAY,GAAKA,GAAarL,EAAMzM,SAAWmD,OAAO8U,UAAUH,GAClE,MAAM,IAAIpY,MAAM,4DAGlB,GAAIsY,GAAWF,GAAaE,EAAUvL,EAAMzM,SAAWmD,OAAO8U,UAAUD,GACtE,MAAM,IAAItY,MAAM,iFAKlB,IAFA,IAAI0Y,EAAW3L,EAAMqL,GAEZ5X,EAAI4X,EAAY,EAAG5X,EAAI8X,EAAS9X,IACnCuM,EAAMvM,GAAKkY,IAAUA,EAAW3L,EAAMvM,IAG5C,OAAOkY,CACT,CFPmBvW,CAAI4K,GAErB,GAAImL,IAAeO,EACjB,MAAM,IAAIE,WAAW,+EAGvB,IAAIC,EAAe5T,EAAQ9B,IACvBsV,OAA4B,IAAjBI,EAA0B5T,EAAQ6T,WAAaX,EAAa,EAAIU,EAC3EE,EAAe9T,EAAQ7C,IACvBuW,OAA4B,IAAjBI,EAA0B9T,EAAQ6T,WAAaJ,EAAa,EAAIK,EAE/E,GAAIN,GAAYE,EACd,MAAM,IAAIC,WAAW,8CAKvB,IAFA,IAAII,GAAUL,EAAWF,IAAaC,EAAaP,GAE1C1X,EAAI,EAAGA,EAAIuM,EAAMzM,OAAQE,IAChC+L,EAAO/L,IAAMuM,EAAMvM,GAAK0X,GAAca,EAASP,EAGjD,OAAOjM,CACT,CGhDA,MAAMyM,GAAS,IAAIC,OAAO,GACpBC,GAAa,IAAID,OAAO,GAMvB,SAASE,GAAyBtY,EAAQmE,EAAU,CAAC,GAC1D,MAAM,QACJoU,EAAU,GAAE,WACZC,EAAa,GAAE,WACfC,EAAa,EAAC,SACdC,EAAW,QACTvU,EACJ,MAAO,GAAGnE,EAAOc,YAAYqK,WAC7BgN,QACAE,KAOF,SAAqBrY,EAAQuY,EAASC,EAAYC,EAAYC,GAC5D,MAAM,KAAE7L,EAAI,QAAE8L,GAAY3Y,EACpB4Y,EAAO/Z,KAAKwD,IAAIwK,EAAM0L,GACtBM,EAAOha,KAAKwD,IAAIsW,EAASH,GACzBjY,EAAS,GAEf,GAAiB,SAAbmY,EAAqB,CACvBA,GAAW,EACXI,EAAM,IAAK,IAAInZ,EAAI,EAAGA,EAAIiZ,EAAMjZ,IAC9B,IAAK,IAAIU,EAAI,EAAGA,EAAIwY,EAAMxY,IACxB,GAAIL,EAAOuQ,IAAI5Q,EAAGU,GAAK,EAAG,CACxBqY,GAAW,EACX,MAAMI,CACR,CAGN,CAEA,IAAK,IAAInZ,EAAI,EAAGA,EAAIiZ,EAAMjZ,IAAK,CAC7B,IAAIoZ,EAAO,GACX,IAAK,IAAI1Y,EAAI,EAAGA,EAAIwY,EAAMxY,IACxB0Y,EAAKpN,KAAKqN,GAAahZ,EAAOuQ,IAAI5Q,EAAGU,GAAIoY,EAAYC,IAEvDnY,EAAOoL,KAAK,GAAGoN,EAAKE,KAAK,OAC3B,CAOA,OANIJ,IAASF,IACXpY,EAAOA,EAAOd,OAAS,IAAM,QAAQkZ,EAAUH,kBAE7CI,IAAS/L,GACXtM,EAAOoL,KAAK,OAAOkB,EAAO0L,eAErBhY,EAAO0Y,KAAK,KAAKZ,KAC1B,CAvCea,CAAYlZ,EAAQuY,EAASC,EAAYC,EAAYC,OAClEP,QACAA,WAAenY,EAAO6M,SACtBsL,cAAkBnY,EAAO2Y,YAE3B,CAoCA,SAASK,GAAaG,EAAKV,EAAYC,GACrC,OACES,GAAO,GAAKT,EACR,IAAIU,GAAcD,EAAKV,EAAa,KACpCW,GAAcD,EAAKV,IACvBY,OAAOZ,EACX,CAEA,SAASW,GAAcD,EAAK3Y,GAE1B,IAAI8Y,EAAMH,EAAI/N,WACd,GAAIkO,EAAI7Z,QAAUe,EAAK,OAAO8Y,EAI9B,IAAIC,EAAMJ,EAAIK,QAAQhZ,GAItB,GAHI+Y,EAAI9Z,OAASe,IACf+Y,EAAMJ,EAAIK,QAAQ3a,KAAKyC,IAAI,EAAGd,GAAO+Y,EAAI9Z,OAASe,MAGlD+Y,EAAI9Z,QAAUe,IACb+Y,EAAIE,WAAW,WACfF,EAAIE,WAAW,UAEhB,OAAOF,EAIT,IAAIG,EAAMP,EAAIQ,cAAcnZ,GAI5B,OAHIkZ,EAAIja,OAASe,IACfkZ,EAAMP,EAAIQ,cAAc9a,KAAKyC,IAAI,EAAGd,GAAOkZ,EAAIja,OAASe,MAEnDkZ,EAAIE,MAAM,EACnB,CCjFO,SAASC,GAAc7Z,EAAQ+D,EAAO+V,GAC3C,IAAIxY,EAAMwY,EAAQ9Z,EAAO6M,KAAO7M,EAAO6M,KAAO,EAC9C,GAAI9I,EAAQ,GAAKA,EAAQzC,EACvB,MAAM,IAAIwW,WAAW,yBAEzB,CASO,SAASiC,GAAiB/Z,EAAQ+D,EAAO+V,GAC9C,IAAIxY,EAAMwY,EAAQ9Z,EAAO2Y,QAAU3Y,EAAO2Y,QAAU,EACpD,GAAI5U,EAAQ,GAAKA,EAAQzC,EACvB,MAAM,IAAIwW,WAAW,4BAEzB,CAUO,SAASkC,GAAeha,EAAQia,GAIrC,GAHIA,EAAOC,YACTD,EAASA,EAAOC,aAEdD,EAAOxa,SAAWO,EAAO2Y,QAC3B,MAAM,IAAIb,WACR,yDAGJ,OAAOmC,CACT,CAUO,SAASE,GAAkBna,EAAQia,GAIxC,GAHIA,EAAOC,YACTD,EAASA,EAAOC,aAEdD,EAAOxa,SAAWO,EAAO6M,KAC3B,MAAM,IAAIiL,WAAW,sDAEvB,OAAOmC,CACT,CA0BO,SAASG,GAAWpa,EAAQgD,EAAUR,EAAQ6X,EAAaC,GAChE,GAAyB,IAArBnD,UAAU1X,OACZ,MAAM,IAAIqY,WAAW,wBAMvB,GAJAyC,GAAY,WAAYvX,GACxBuX,GAAY,SAAU/X,GACtB+X,GAAY,cAAeF,GAC3BE,GAAY,YAAaD,GAEvBtX,EAAWR,GACX6X,EAAcC,GACdtX,EAAW,GACXA,GAAYhD,EAAO6M,MACnBrK,EAAS,GACTA,GAAUxC,EAAO6M,MACjBwN,EAAc,GACdA,GAAera,EAAO2Y,SACtB2B,EAAY,GACZA,GAAata,EAAO2Y,QAEpB,MAAM,IAAIb,WAAW,qCAEzB,CAEO,SAAS0C,GAAS/a,EAAQqE,EAAQ,GACvC,IAAI2W,EAAQ,GACZ,IAAK,IAAI9a,EAAI,EAAGA,EAAIF,EAAQE,IAC1B8a,EAAM9O,KAAK7H,GAEb,OAAO2W,CACT,CAEA,SAASF,GAAYpP,EAAMrH,GACzB,GAAqB,iBAAVA,EACT,MAAM,IAAIsT,UAAU,GAAGjM,qBAE3B,CAEO,SAASuP,GAAc1a,GAC5B,GAAIA,EAAO2a,UACT,MAAM,IAAIxb,MAAM,wCAEpB,CClGO,MAAMyb,GACXvP,mBAAmBwP,EAASC,EAAYC,GAEtC,GADaF,EAAUC,IACRC,EAAQtb,OACrB,MAAM,IAAIqY,WAAW,+CAEvB,IAAIkD,EAAY,IAAI,GAAOH,EAASC,GACpC,IAAK,IAAIvN,EAAM,EAAGA,EAAMsN,EAAStN,IAC/B,IAAK,IAAI0N,EAAS,EAAGA,EAASH,EAAYG,IACxCD,EAAUrX,IAAI4J,EAAK0N,EAAQF,EAAQxN,EAAMuN,EAAaG,IAG1D,OAAOD,CACT,CAEA3P,iBAAiB0P,GACf,IAAId,EAAS,IAAI,GAAO,EAAGc,EAAQtb,QACnC,IAAK,IAAIE,EAAI,EAAGA,EAAIob,EAAQtb,OAAQE,IAClCsa,EAAOtW,IAAI,EAAGhE,EAAGob,EAAQpb,IAE3B,OAAOsa,CACT,CAEA5O,oBAAoB0P,GAClB,IAAId,EAAS,IAAI,GAAOc,EAAQtb,OAAQ,GACxC,IAAK,IAAIE,EAAI,EAAGA,EAAIob,EAAQtb,OAAQE,IAClCsa,EAAOtW,IAAIhE,EAAG,EAAGob,EAAQpb,IAE3B,OAAOsa,CACT,CAEA5O,aAAawB,EAAM8L,GACjB,OAAO,IAAI,GAAO9L,EAAM8L,EAC1B,CAEAtN,YAAYwB,EAAM8L,GAChB,OAAO,IAAI,GAAO9L,EAAM8L,GAAS1Y,KAAK,EACxC,CAEAoL,YAAYwB,EAAM8L,EAASxU,EAAU,CAAC,GACpC,GAAuB,iBAAZA,EACT,MAAM,IAAIiT,UAAU,6BAEtB,MAAM,OAAEtY,EAASD,KAAKC,QAAWqF,EACjC,IAAInE,EAAS,IAAI,GAAO6M,EAAM8L,GAC9B,IAAK,IAAIhZ,EAAI,EAAGA,EAAIkN,EAAMlN,IACxB,IAAK,IAAIU,EAAI,EAAGA,EAAIsY,EAAStY,IAC3BL,EAAO2D,IAAIhE,EAAGU,EAAGvB,KAGrB,OAAOkB,CACT,CAEAqL,eAAewB,EAAM8L,EAASxU,EAAU,CAAC,GACvC,GAAuB,iBAAZA,EACT,MAAM,IAAIiT,UAAU,6BAEtB,MAAM,IAAE/U,EAAM,EAAC,IAAEf,EAAM,IAAI,OAAExC,EAASD,KAAKC,QAAWqF,EACtD,IAAKvB,OAAO8U,UAAUrV,GAAM,MAAM,IAAI+U,UAAU,0BAChD,IAAKxU,OAAO8U,UAAUpW,GAAM,MAAM,IAAI8V,UAAU,0BAChD,GAAI/U,GAAOf,EAAK,MAAM,IAAIwW,WAAW,gCACrC,IAAIoD,EAAW5Z,EAAMe,EACjBrC,EAAS,IAAI,GAAO6M,EAAM8L,GAC9B,IAAK,IAAIhZ,EAAI,EAAGA,EAAIkN,EAAMlN,IACxB,IAAK,IAAIU,EAAI,EAAGA,EAAIsY,EAAStY,IAAK,CAChC,IAAIyD,EAAQzB,EAAMxD,KAAKsc,MAAMrc,IAAWoc,GACxClb,EAAO2D,IAAIhE,EAAGU,EAAGyD,EACnB,CAEF,OAAO9D,CACT,CAEAqL,WAAWwB,EAAM8L,EAAS7U,QACR8H,IAAZ+M,IAAuBA,EAAU9L,QACvBjB,IAAV9H,IAAqBA,EAAQ,GACjC,IAAIzB,EAAMxD,KAAKwD,IAAIwK,EAAM8L,GACrB3Y,EAASoB,KAAK4K,MAAMa,EAAM8L,GAC9B,IAAK,IAAIhZ,EAAI,EAAGA,EAAI0C,EAAK1C,IACvBK,EAAO2D,IAAIhE,EAAGA,EAAGmE,GAEnB,OAAO9D,CACT,CAEAqL,YAAY9H,EAAMsJ,EAAM8L,GACtB,IAAIyC,EAAI7X,EAAK9D,YACAmM,IAATiB,IAAoBA,EAAOuO,QACfxP,IAAZ+M,IAAuBA,EAAU9L,GACrC,IAAIxK,EAAMxD,KAAKwD,IAAI+Y,EAAGvO,EAAM8L,GACxB3Y,EAASoB,KAAK4K,MAAMa,EAAM8L,GAC9B,IAAK,IAAIhZ,EAAI,EAAGA,EAAI0C,EAAK1C,IACvBK,EAAO2D,IAAIhE,EAAGA,EAAG4D,EAAK5D,IAExB,OAAOK,CACT,CAEAqL,WAAWgQ,EAASC,GAClBD,EAAUja,KAAKma,YAAYF,GAC3BC,EAAUla,KAAKma,YAAYD,GAC3B,IAAIzO,EAAOwO,EAAQxO,KACf8L,EAAU0C,EAAQ1C,QAClBpY,EAAS,IAAI,GAAOsM,EAAM8L,GAC9B,IAAK,IAAIhZ,EAAI,EAAGA,EAAIkN,EAAMlN,IACxB,IAAK,IAAIU,EAAI,EAAGA,EAAIsY,EAAStY,IAC3BE,EAAOoD,IAAIhE,EAAGU,EAAGxB,KAAKwD,IAAIgZ,EAAQ9K,IAAI5Q,EAAGU,GAAIib,EAAQ/K,IAAI5Q,EAAGU,KAGhE,OAAOE,CACT,CAEA8K,WAAWgQ,EAASC,GAClBD,EAAUja,KAAKma,YAAYF,GAC3BC,EAAUla,KAAKma,YAAYD,GAC3B,IAAIzO,EAAOwO,EAAQxO,KACf8L,EAAU0C,EAAQ1C,QAClBpY,EAAS,IAAIa,KAAKyL,EAAM8L,GAC5B,IAAK,IAAIhZ,EAAI,EAAGA,EAAIkN,EAAMlN,IACxB,IAAK,IAAIU,EAAI,EAAGA,EAAIsY,EAAStY,IAC3BE,EAAOoD,IAAIhE,EAAGU,EAAGxB,KAAKyC,IAAI+Z,EAAQ9K,IAAI5Q,EAAGU,GAAIib,EAAQ/K,IAAI5Q,EAAGU,KAGhE,OAAOE,CACT,CAEA8K,mBAAmBvH,GACjB,OAAO8W,GAAeY,SAAS1X,GAASA,EAAQ,IAAI,GAAOA,EAC7D,CAEAuH,gBAAgBvH,GACd,OAAgB,MAATA,GAAiC,WAAhBA,EAAM2X,KAChC,CAEI7a,WACF,OAAOQ,KAAKyL,KAAOzL,KAAKuX,OAC1B,CAEA+C,MAAMC,GACJ,GAAwB,mBAAbA,EACT,MAAM,IAAIvE,UAAU,+BAEtB,IAAK,IAAIzX,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCsb,EAAS/E,KAAKxV,KAAMzB,EAAGU,GAG3B,OAAOe,IACT,CAEA8Y,YACE,IAAIO,EAAQ,GACZ,IAAK,IAAI9a,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCoa,EAAM9O,KAAKvK,KAAKmP,IAAI5Q,EAAGU,IAG3B,OAAOoa,CACT,CAEAmB,YACE,IAAIC,EAAO,GACX,IAAK,IAAIlc,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAAK,CAClCkc,EAAKlQ,KAAK,IACV,IAAK,IAAItL,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCwb,EAAKlc,GAAGgM,KAAKvK,KAAKmP,IAAI5Q,EAAGU,GAE7B,CACA,OAAOwb,CACT,CAEAC,SACE,OAAO1a,KAAKwa,WACd,CAEAG,cACE,OAAqB,IAAd3a,KAAKyL,IACd,CAEAmP,iBACE,OAAwB,IAAjB5a,KAAKuX,OACd,CAEAsD,WACE,OAAqB,IAAd7a,KAAKyL,MAA+B,IAAjBzL,KAAKuX,OACjC,CAEAuD,WACE,OAAO9a,KAAKyL,OAASzL,KAAKuX,OAC5B,CAEAgC,UACE,OAAqB,IAAdvZ,KAAKyL,MAA+B,IAAjBzL,KAAKuX,OACjC,CAEAwD,cACE,GAAI/a,KAAK8a,WAAY,CACnB,IAAK,IAAIvc,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,GAAKV,EAAGU,IACtB,GAAIe,KAAKmP,IAAI5Q,EAAGU,KAAOe,KAAKmP,IAAIlQ,EAAGV,GACjC,OAAO,EAIb,OAAO,CACT,CACA,OAAO,CACT,CAEAyc,gBACE,IAAIzc,EAAI,EACJU,EAAI,EACJgc,GAAkB,EAClBD,GAAgB,EAChBE,GAAU,EACd,KAAO3c,EAAIyB,KAAKyL,MAAQuP,GAAe,CAGrC,IAFA/b,EAAI,EACJic,GAAU,EACHjc,EAAIe,KAAKuX,UAAuB,IAAZ2D,GACF,IAAnBlb,KAAKmP,IAAI5Q,EAAGU,GACdA,IAC4B,IAAnBe,KAAKmP,IAAI5Q,EAAGU,IAAYA,EAAIgc,GACrCC,GAAU,EACVD,EAAiBhc,IAEjB+b,GAAgB,EAChBE,GAAU,GAGd3c,GACF,CACA,OAAOyc,CACT,CAEAG,uBACE,IAAI5c,EAAI,EACJU,EAAI,EACJgc,GAAkB,EAClBE,GAAuB,EACvBD,GAAU,EACd,KAAO3c,EAAIyB,KAAKyL,MAAQ0P,GAAsB,CAG5C,IAFAlc,EAAI,EACJic,GAAU,EACHjc,EAAIe,KAAKuX,UAAuB,IAAZ2D,GACF,IAAnBlb,KAAKmP,IAAI5Q,EAAGU,GACdA,IAC4B,IAAnBe,KAAKmP,IAAI5Q,EAAGU,IAAYA,EAAIgc,GACrCC,GAAU,EACVD,EAAiBhc,IAEjBkc,GAAuB,EACvBD,GAAU,GAGd,IAAK,IAAI7P,EAAIpM,EAAI,EAAGoM,EAAIrL,KAAKyL,KAAMJ,IACV,IAAnBrL,KAAKmP,IAAI5Q,EAAG8M,KACd8P,GAAuB,GAG3B5c,GACF,CACA,OAAO4c,CACT,CAEAC,cACE,IAAIjc,EAASa,KAAKqb,QACdC,EAAI,EACJjQ,EAAI,EACR,KAAOiQ,EAAInc,EAAOsM,MAAQJ,EAAIlM,EAAOoY,SAAS,CAC5C,IAAIgE,EAAOD,EACX,IAAK,IAAI/c,EAAI+c,EAAG/c,EAAIY,EAAOsM,KAAMlN,IAC3BY,EAAOgQ,IAAI5Q,EAAG8M,GAAKlM,EAAOgQ,IAAIoM,EAAMlQ,KACtCkQ,EAAOhd,GAGX,GAA4B,IAAxBY,EAAOgQ,IAAIoM,EAAMlQ,GACnBA,QACK,CACLlM,EAAOqc,SAASF,EAAGC,GACnB,IAAIE,EAAMtc,EAAOgQ,IAAImM,EAAGjQ,GACxB,IAAK,IAAIpM,EAAIoM,EAAGpM,EAAIE,EAAOoY,QAAStY,IAClCE,EAAOoD,IAAI+Y,EAAGrc,EAAGE,EAAOgQ,IAAImM,EAAGrc,GAAKwc,GAEtC,IAAK,IAAIld,EAAI+c,EAAI,EAAG/c,EAAIY,EAAOsM,KAAMlN,IAAK,CACxC,IAAIuY,EAAS3X,EAAOgQ,IAAI5Q,EAAG8M,GAAKlM,EAAOgQ,IAAImM,EAAGjQ,GAC9ClM,EAAOoD,IAAIhE,EAAG8M,EAAG,GACjB,IAAK,IAAIpM,EAAIoM,EAAI,EAAGpM,EAAIE,EAAOoY,QAAStY,IACtCE,EAAOoD,IAAIhE,EAAGU,EAAGE,EAAOgQ,IAAI5Q,EAAGU,GAAKE,EAAOgQ,IAAImM,EAAGrc,GAAK6X,EAE3D,CACAwE,IACAjQ,GACF,CACF,CACA,OAAOlM,CACT,CAEAuc,qBACE,IAAIvc,EAASa,KAAKob,cACdvK,EAAI1R,EAAOoY,QACXrS,EAAI/F,EAAOsM,KACX6P,EAAIpW,EAAI,EACZ,KAAOoW,GAAK,GACV,GAAyB,IAArBnc,EAAOwc,OAAOL,GAChBA,QACK,CACL,IAAIrd,EAAI,EACJ2d,GAAQ,EACZ,KAAO3d,EAAIiH,IAAe,IAAV0W,GACW,IAArBzc,EAAOgQ,IAAImM,EAAGrd,GAChB2d,GAAQ,EAER3d,IAGJ,IAAK,IAAIM,EAAI,EAAGA,EAAI+c,EAAG/c,IAAK,CAC1B,IAAIuY,EAAS3X,EAAOgQ,IAAI5Q,EAAGN,GAC3B,IAAK,IAAIgB,EAAIhB,EAAGgB,EAAI4R,EAAG5R,IAAK,CAC1B,IAAIwc,EAAMtc,EAAOgQ,IAAI5Q,EAAGU,GAAK6X,EAAS3X,EAAOgQ,IAAImM,EAAGrc,GACpDE,EAAOoD,IAAIhE,EAAGU,EAAGwc,EACnB,CACF,CACAH,GACF,CAEF,OAAOnc,CACT,CAEAoD,MACE,MAAM,IAAIxE,MAAM,8BAClB,CAEAoR,MACE,MAAM,IAAIpR,MAAM,8BAClB,CAEAiZ,OAAOjU,EAAU,CAAC,GAChB,GAAuB,iBAAZA,EACT,MAAM,IAAIiT,UAAU,6BAEtB,MAAM,KAAEvK,EAAO,EAAC,QAAE8L,EAAU,GAAMxU,EAClC,IAAKvB,OAAO8U,UAAU7K,IAASA,GAAQ,EACrC,MAAM,IAAIuK,UAAU,mCAEtB,IAAKxU,OAAO8U,UAAUiB,IAAYA,GAAW,EAC3C,MAAM,IAAIvB,UAAU,sCAEtB,IAAIpX,EAAS,IAAI,GAAOoB,KAAKyL,KAAOA,EAAMzL,KAAKuX,QAAUA,GACzD,IAAK,IAAIhZ,EAAI,EAAGA,EAAIkN,EAAMlN,IACxB,IAAK,IAAIU,EAAI,EAAGA,EAAIsY,EAAStY,IAC3BL,EAAOid,aAAa7b,KAAMA,KAAKyL,KAAOlN,EAAGyB,KAAKuX,QAAUtY,GAG5D,OAAOL,CACT,CAEAC,KAAK6D,GACH,IAAK,IAAInE,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGyD,GAGnB,OAAO1C,IACT,CAEA8b,MACE,OAAO9b,KAAK+b,MAAM,EACpB,CAEAC,OAAOrZ,GACL8V,GAAczY,KAAM2C,GACpB,IAAIwJ,EAAM,GACV,IAAK,IAAI5N,EAAI,EAAGA,EAAIyB,KAAKuX,QAAShZ,IAChC4N,EAAI5B,KAAKvK,KAAKmP,IAAIxM,EAAOpE,IAE3B,OAAO4N,CACT,CAEA8P,aAAatZ,GACX,OAAO,GAAOuZ,UAAUlc,KAAKgc,OAAOrZ,GACtC,CAEAwZ,OAAOxZ,EAAO0W,GACZZ,GAAczY,KAAM2C,GACpB0W,EAAQT,GAAe5Y,KAAMqZ,GAC7B,IAAK,IAAI9a,EAAI,EAAGA,EAAIyB,KAAKuX,QAAShZ,IAChCyB,KAAKuC,IAAII,EAAOpE,EAAG8a,EAAM9a,IAE3B,OAAOyB,IACT,CAEAwb,SAASY,EAAMC,GACb5D,GAAczY,KAAMoc,GACpB3D,GAAczY,KAAMqc,GACpB,IAAK,IAAI9d,EAAI,EAAGA,EAAIyB,KAAKuX,QAAShZ,IAAK,CACrC,IAAI+d,EAAOtc,KAAKmP,IAAIiN,EAAM7d,GAC1ByB,KAAKuC,IAAI6Z,EAAM7d,EAAGyB,KAAKmP,IAAIkN,EAAM9d,IACjCyB,KAAKuC,IAAI8Z,EAAM9d,EAAG+d,EACpB,CACA,OAAOtc,IACT,CAEAuc,UAAU5Z,GACRgW,GAAiB3Y,KAAM2C,GACvB,IAAIkX,EAAS,GACb,IAAK,IAAItb,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7Bsb,EAAOtP,KAAKvK,KAAKmP,IAAI5Q,EAAGoE,IAE1B,OAAOkX,CACT,CAEA2C,gBAAgB7Z,GACd,OAAO,GAAO8Z,aAAazc,KAAKuc,UAAU5Z,GAC5C,CAEA+Z,UAAU/Z,EAAO0W,GACfV,GAAiB3Y,KAAM2C,GACvB0W,EAAQN,GAAkB/Y,KAAMqZ,GAChC,IAAK,IAAI9a,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7ByB,KAAKuC,IAAIhE,EAAGoE,EAAO0W,EAAM9a,IAE3B,OAAOyB,IACT,CAEA2c,YAAYC,EAASC,GACnBlE,GAAiB3Y,KAAM4c,GACvBjE,GAAiB3Y,KAAM6c,GACvB,IAAK,IAAIte,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAAK,CAClC,IAAI+d,EAAOtc,KAAKmP,IAAI5Q,EAAGqe,GACvB5c,KAAKuC,IAAIhE,EAAGqe,EAAS5c,KAAKmP,IAAI5Q,EAAGse,IACjC7c,KAAKuC,IAAIhE,EAAGse,EAASP,EACvB,CACA,OAAOtc,IACT,CAEA8c,aAAajE,GACXA,EAASD,GAAe5Y,KAAM6Y,GAC9B,IAAK,IAAIta,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAK4Z,EAAO5Z,IAG3C,OAAOe,IACT,CAEA+c,aAAalE,GACXA,EAASD,GAAe5Y,KAAM6Y,GAC9B,IAAK,IAAIta,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAK4Z,EAAO5Z,IAG3C,OAAOe,IACT,CAEAgd,aAAanE,GACXA,EAASD,GAAe5Y,KAAM6Y,GAC9B,IAAK,IAAIta,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAK4Z,EAAO5Z,IAG3C,OAAOe,IACT,CAEAid,aAAapE,GACXA,EAASD,GAAe5Y,KAAM6Y,GAC9B,IAAK,IAAIta,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAK4Z,EAAO5Z,IAG3C,OAAOe,IACT,CAEAkd,gBAAgBrE,GACdA,EAASE,GAAkB/Y,KAAM6Y,GACjC,IAAK,IAAIta,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAK4Z,EAAOta,IAG3C,OAAOyB,IACT,CAEAmd,gBAAgBtE,GACdA,EAASE,GAAkB/Y,KAAM6Y,GACjC,IAAK,IAAIta,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAK4Z,EAAOta,IAG3C,OAAOyB,IACT,CAEAod,gBAAgBvE,GACdA,EAASE,GAAkB/Y,KAAM6Y,GACjC,IAAK,IAAIta,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAK4Z,EAAOta,IAG3C,OAAOyB,IACT,CAEAqd,gBAAgBxE,GACdA,EAASE,GAAkB/Y,KAAM6Y,GACjC,IAAK,IAAIta,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAK4Z,EAAOta,IAG3C,OAAOyB,IACT,CAEAsd,OAAO3a,EAAOD,GACZ+V,GAAczY,KAAM2C,GACpB,IAAK,IAAIpE,EAAI,EAAGA,EAAIyB,KAAKuX,QAAShZ,IAChCyB,KAAKuC,IAAII,EAAOpE,EAAGyB,KAAKmP,IAAIxM,EAAOpE,GAAKmE,GAE1C,OAAO1C,IACT,CAEAud,UAAU5a,EAAOD,GACfiW,GAAiB3Y,KAAM2C,GACvB,IAAK,IAAIpE,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7ByB,KAAKuC,IAAIhE,EAAGoE,EAAO3C,KAAKmP,IAAI5Q,EAAGoE,GAASD,GAE1C,OAAO1C,IACT,CAEAE,IAAIsd,GACF,GAAIxd,KAAKuZ,UACP,OAAOkE,IAET,OAAQD,GACN,IAAK,MAAO,CACV,MAAMtd,EAAM,IAAIpB,MAAMkB,KAAKyL,MAAM5M,KAAK2C,OAAOkc,mBAC7C,IAAK,IAAIvR,EAAM,EAAGA,EAAMnM,KAAKyL,KAAMU,IACjC,IAAK,IAAI0N,EAAS,EAAGA,EAAS7Z,KAAKuX,QAASsC,IACtC7Z,KAAKmP,IAAIhD,EAAK0N,GAAU3Z,EAAIiM,KAC9BjM,EAAIiM,GAAOnM,KAAKmP,IAAIhD,EAAK0N,IAI/B,OAAO3Z,CACT,CACA,IAAK,SAAU,CACb,MAAMA,EAAM,IAAIpB,MAAMkB,KAAKuX,SAAS1Y,KAAK2C,OAAOkc,mBAChD,IAAK,IAAIvR,EAAM,EAAGA,EAAMnM,KAAKyL,KAAMU,IACjC,IAAK,IAAI0N,EAAS,EAAGA,EAAS7Z,KAAKuX,QAASsC,IACtC7Z,KAAKmP,IAAIhD,EAAK0N,GAAU3Z,EAAI2Z,KAC9B3Z,EAAI2Z,GAAU7Z,KAAKmP,IAAIhD,EAAK0N,IAIlC,OAAO3Z,CACT,CACA,UAAKsK,EAAW,CACd,IAAItK,EAAMF,KAAKmP,IAAI,EAAG,GACtB,IAAK,IAAIhD,EAAM,EAAGA,EAAMnM,KAAKyL,KAAMU,IACjC,IAAK,IAAI0N,EAAS,EAAGA,EAAS7Z,KAAKuX,QAASsC,IACtC7Z,KAAKmP,IAAIhD,EAAK0N,GAAU3Z,IAC1BA,EAAMF,KAAKmP,IAAIhD,EAAK0N,IAI1B,OAAO3Z,CACT,CACA,QACE,MAAM,IAAInC,MAAM,mBAAmByf,KAEzC,CAEAG,WACErE,GAActZ,MACd,IAAI2K,EAAI3K,KAAKmP,IAAI,EAAG,GAChB/B,EAAM,CAAC,EAAG,GACd,IAAK,IAAI7O,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAC5Be,KAAKmP,IAAI5Q,EAAGU,GAAK0L,IACnBA,EAAI3K,KAAKmP,IAAI5Q,EAAGU,GAChBmO,EAAI,GAAK7O,EACT6O,EAAI,GAAKnO,GAIf,OAAOmO,CACT,CAEAnM,IAAIuc,GACF,GAAIxd,KAAKuZ,UACP,OAAOkE,IAGT,OAAQD,GACN,IAAK,MAAO,CACV,MAAMvc,EAAM,IAAInC,MAAMkB,KAAKyL,MAAM5M,KAAK2C,OAAOoc,mBAC7C,IAAK,IAAIzR,EAAM,EAAGA,EAAMnM,KAAKyL,KAAMU,IACjC,IAAK,IAAI0N,EAAS,EAAGA,EAAS7Z,KAAKuX,QAASsC,IACtC7Z,KAAKmP,IAAIhD,EAAK0N,GAAU5Y,EAAIkL,KAC9BlL,EAAIkL,GAAOnM,KAAKmP,IAAIhD,EAAK0N,IAI/B,OAAO5Y,CACT,CACA,IAAK,SAAU,CACb,MAAMA,EAAM,IAAInC,MAAMkB,KAAKuX,SAAS1Y,KAAK2C,OAAOoc,mBAChD,IAAK,IAAIzR,EAAM,EAAGA,EAAMnM,KAAKyL,KAAMU,IACjC,IAAK,IAAI0N,EAAS,EAAGA,EAAS7Z,KAAKuX,QAASsC,IACtC7Z,KAAKmP,IAAIhD,EAAK0N,GAAU5Y,EAAI4Y,KAC9B5Y,EAAI4Y,GAAU7Z,KAAKmP,IAAIhD,EAAK0N,IAIlC,OAAO5Y,CACT,CACA,UAAKuJ,EAAW,CACd,IAAIvJ,EAAMjB,KAAKmP,IAAI,EAAG,GACtB,IAAK,IAAIhD,EAAM,EAAGA,EAAMnM,KAAKyL,KAAMU,IACjC,IAAK,IAAI0N,EAAS,EAAGA,EAAS7Z,KAAKuX,QAASsC,IACtC7Z,KAAKmP,IAAIhD,EAAK0N,GAAU5Y,IAC1BA,EAAMjB,KAAKmP,IAAIhD,EAAK0N,IAI1B,OAAO5Y,CACT,CACA,QACE,MAAM,IAAIlD,MAAM,mBAAmByf,KAEzC,CAEAK,WACEvE,GAActZ,MACd,IAAI2K,EAAI3K,KAAKmP,IAAI,EAAG,GAChB/B,EAAM,CAAC,EAAG,GACd,IAAK,IAAI7O,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAC5Be,KAAKmP,IAAI5Q,EAAGU,GAAK0L,IACnBA,EAAI3K,KAAKmP,IAAI5Q,EAAGU,GAChBmO,EAAI,GAAK7O,EACT6O,EAAI,GAAKnO,GAIf,OAAOmO,CACT,CAEAuO,OAAOxP,GAEL,GADAsM,GAAczY,KAAMmM,GAChBnM,KAAKuZ,UACP,OAAOkE,IAET,IAAI9S,EAAI3K,KAAKmP,IAAIhD,EAAK,GACtB,IAAK,IAAI5N,EAAI,EAAGA,EAAIyB,KAAKuX,QAAShZ,IAC5ByB,KAAKmP,IAAIhD,EAAK5N,GAAKoM,IACrBA,EAAI3K,KAAKmP,IAAIhD,EAAK5N,IAGtB,OAAOoM,CACT,CAEAmT,YAAY3R,GACVsM,GAAczY,KAAMmM,GACpBmN,GAActZ,MACd,IAAI2K,EAAI3K,KAAKmP,IAAIhD,EAAK,GAClBiB,EAAM,CAACjB,EAAK,GAChB,IAAK,IAAI5N,EAAI,EAAGA,EAAIyB,KAAKuX,QAAShZ,IAC5ByB,KAAKmP,IAAIhD,EAAK5N,GAAKoM,IACrBA,EAAI3K,KAAKmP,IAAIhD,EAAK5N,GAClB6O,EAAI,GAAK7O,GAGb,OAAO6O,CACT,CAEA2Q,OAAO5R,GAEL,GADAsM,GAAczY,KAAMmM,GAChBnM,KAAKuZ,UACP,OAAOkE,IAET,IAAI9S,EAAI3K,KAAKmP,IAAIhD,EAAK,GACtB,IAAK,IAAI5N,EAAI,EAAGA,EAAIyB,KAAKuX,QAAShZ,IAC5ByB,KAAKmP,IAAIhD,EAAK5N,GAAKoM,IACrBA,EAAI3K,KAAKmP,IAAIhD,EAAK5N,IAGtB,OAAOoM,CACT,CAEAqT,YAAY7R,GACVsM,GAAczY,KAAMmM,GACpBmN,GAActZ,MACd,IAAI2K,EAAI3K,KAAKmP,IAAIhD,EAAK,GAClBiB,EAAM,CAACjB,EAAK,GAChB,IAAK,IAAI5N,EAAI,EAAGA,EAAIyB,KAAKuX,QAAShZ,IAC5ByB,KAAKmP,IAAIhD,EAAK5N,GAAKoM,IACrBA,EAAI3K,KAAKmP,IAAIhD,EAAK5N,GAClB6O,EAAI,GAAK7O,GAGb,OAAO6O,CACT,CAEA6Q,UAAUpE,GAER,GADAlB,GAAiB3Y,KAAM6Z,GACnB7Z,KAAKuZ,UACP,OAAOkE,IAET,IAAI9S,EAAI3K,KAAKmP,IAAI,EAAG0K,GACpB,IAAK,IAAItb,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IACzByB,KAAKmP,IAAI5Q,EAAGsb,GAAUlP,IACxBA,EAAI3K,KAAKmP,IAAI5Q,EAAGsb,IAGpB,OAAOlP,CACT,CAEAuT,eAAerE,GACblB,GAAiB3Y,KAAM6Z,GACvBP,GAActZ,MACd,IAAI2K,EAAI3K,KAAKmP,IAAI,EAAG0K,GAChBzM,EAAM,CAAC,EAAGyM,GACd,IAAK,IAAItb,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IACzByB,KAAKmP,IAAI5Q,EAAGsb,GAAUlP,IACxBA,EAAI3K,KAAKmP,IAAI5Q,EAAGsb,GAChBzM,EAAI,GAAK7O,GAGb,OAAO6O,CACT,CAEA+Q,UAAUtE,GAER,GADAlB,GAAiB3Y,KAAM6Z,GACnB7Z,KAAKuZ,UACP,OAAOkE,IAET,IAAI9S,EAAI3K,KAAKmP,IAAI,EAAG0K,GACpB,IAAK,IAAItb,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IACzByB,KAAKmP,IAAI5Q,EAAGsb,GAAUlP,IACxBA,EAAI3K,KAAKmP,IAAI5Q,EAAGsb,IAGpB,OAAOlP,CACT,CAEAyT,eAAevE,GACblB,GAAiB3Y,KAAM6Z,GACvBP,GAActZ,MACd,IAAI2K,EAAI3K,KAAKmP,IAAI,EAAG0K,GAChBzM,EAAM,CAAC,EAAGyM,GACd,IAAK,IAAItb,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IACzByB,KAAKmP,IAAI5Q,EAAGsb,GAAUlP,IACxBA,EAAI3K,KAAKmP,IAAI5Q,EAAGsb,GAChBzM,EAAI,GAAK7O,GAGb,OAAO6O,CACT,CAEAiR,OACE,IAAIpd,EAAMxD,KAAKwD,IAAIjB,KAAKyL,KAAMzL,KAAKuX,SAC/B8G,EAAO,GACX,IAAK,IAAI9f,EAAI,EAAGA,EAAI0C,EAAK1C,IACvB8f,EAAK9T,KAAKvK,KAAKmP,IAAI5Q,EAAGA,IAExB,OAAO8f,CACT,CAEA3M,KAAK4M,EAAO,aACV,IAAInf,EAAS,EACb,GAAa,QAATmf,EACF,OAAOte,KAAKE,MACP,GAAa,cAAToe,EAAsB,CAC/B,IAAK,IAAI/f,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCE,GAAkBa,KAAKmP,IAAI5Q,EAAGU,GAAKe,KAAKmP,IAAI5Q,EAAGU,GAGnD,OAAOxB,KAAK6B,KAAKH,EACnB,CACE,MAAM,IAAIuX,WAAW,sBAAsB4H,IAE/C,CAEAC,gBACE,IAAIxT,EAAM,EACV,IAAK,IAAIxM,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChC8L,GAAO/K,KAAKmP,IAAI5Q,EAAGU,GACnBe,KAAKuC,IAAIhE,EAAGU,EAAG8L,GAGnB,OAAO/K,IACT,CAEAwe,IAAIC,GACEjF,GAAeY,SAASqE,KAAUA,EAAUA,EAAQ3F,aACxD,IAAI4F,EAAU1e,KAAK8Y,YACnB,GAAI4F,EAAQrgB,SAAWogB,EAAQpgB,OAC7B,MAAM,IAAIqY,WAAW,qCAEvB,IAAI8H,EAAM,EACV,IAAK,IAAIjgB,EAAI,EAAGA,EAAImgB,EAAQrgB,OAAQE,IAClCigB,GAAOE,EAAQngB,GAAKkgB,EAAQlgB,GAE9B,OAAOigB,CACT,CAEAG,KAAKC,GACHA,EAAQ,GAAOzE,YAAYyE,GAE3B,IAAI/N,EAAI7Q,KAAKyL,KACTvG,EAAIlF,KAAKuX,QACTtZ,EAAI2gB,EAAMrH,QAEVpY,EAAS,IAAI,GAAO0R,EAAG5S,GAEvB4gB,EAAQ,IAAIC,aAAa5Z,GAC7B,IAAK,IAAIjG,EAAI,EAAGA,EAAIhB,EAAGgB,IAAK,CAC1B,IAAK,IAAIoM,EAAI,EAAGA,EAAInG,EAAGmG,IACrBwT,EAAMxT,GAAKuT,EAAMzP,IAAI9D,EAAGpM,GAG1B,IAAK,IAAIV,EAAI,EAAGA,EAAIsS,EAAGtS,IAAK,CAC1B,IAAIwgB,EAAI,EACR,IAAK,IAAI1T,EAAI,EAAGA,EAAInG,EAAGmG,IACrB0T,GAAK/e,KAAKmP,IAAI5Q,EAAG8M,GAAKwT,EAAMxT,GAG9BlM,EAAOoD,IAAIhE,EAAGU,EAAG8f,EACnB,CACF,CACA,OAAO5f,CACT,CAEA6f,YAAYJ,GACVA,EAAQ,GAAOzE,YAAYyE,GAC3B,IAAIzf,EAAS,IAAI,GAAO,EAAG,GAC3B,MAAM8f,EAAMjf,KAAKmP,IAAI,EAAG,GAClB+P,EAAMN,EAAMzP,IAAI,EAAG,GACnBgQ,EAAMnf,KAAKmP,IAAI,EAAG,GAClBiQ,EAAMR,EAAMzP,IAAI,EAAG,GACnBkQ,EAAMrf,KAAKmP,IAAI,EAAG,GAClBmQ,EAAMV,EAAMzP,IAAI,EAAG,GACnBoQ,EAAMvf,KAAKmP,IAAI,EAAG,GAClBqQ,EAAMZ,EAAMzP,IAAI,EAAG,GAGnBsQ,GAAMR,EAAMM,IAAQL,EAAMM,GAC1BE,GAAML,EAAME,GAAOL,EACnBS,EAAKV,GAAOG,EAAMI,GAClBI,EAAKL,GAAOD,EAAMJ,GAClBW,GAAMZ,EAAME,GAAOK,EAKnBM,EAAML,EAAKG,EAAKC,GAHVV,EAAMI,IAAQD,EAAME,GAI1BO,EAAMJ,EAAKE,EACXG,EAAMN,EAAKE,EACXK,EAAMR,EAAKC,EAAKC,GAPVN,EAAMJ,IAAQC,EAAME,GAahC,OAJAjgB,EAAOoD,IAAI,EAAG,EAAGud,GACjB3gB,EAAOoD,IAAI,EAAG,EAAGwd,GACjB5gB,EAAOoD,IAAI,EAAG,EAAGyd,GACjB7gB,EAAOoD,IAAI,EAAG,EAAG0d,GACV9gB,CACT,CAEA+gB,YAAYtB,GACVA,EAAQ,GAAOzE,YAAYyE,GAC3B,IAAIzf,EAAS,IAAI,GAAO,EAAG,GAE3B,MAAMghB,EAAMngB,KAAKmP,IAAI,EAAG,GAClBiR,EAAMpgB,KAAKmP,IAAI,EAAG,GAClBkR,EAAMrgB,KAAKmP,IAAI,EAAG,GAClBmR,EAAMtgB,KAAKmP,IAAI,EAAG,GAClB8P,EAAMjf,KAAKmP,IAAI,EAAG,GAClBgQ,EAAMnf,KAAKmP,IAAI,EAAG,GAClBoR,EAAMvgB,KAAKmP,IAAI,EAAG,GAClBkQ,EAAMrf,KAAKmP,IAAI,EAAG,GAClBoQ,EAAMvf,KAAKmP,IAAI,EAAG,GAElBqR,EAAM5B,EAAMzP,IAAI,EAAG,GACnBsR,EAAM7B,EAAMzP,IAAI,EAAG,GACnBuR,EAAM9B,EAAMzP,IAAI,EAAG,GACnBwR,EAAM/B,EAAMzP,IAAI,EAAG,GACnB+P,EAAMN,EAAMzP,IAAI,EAAG,GACnBiQ,EAAMR,EAAMzP,IAAI,EAAG,GACnByR,EAAMhC,EAAMzP,IAAI,EAAG,GACnBmQ,EAAMV,EAAMzP,IAAI,EAAG,GACnBqQ,EAAMZ,EAAMzP,IAAI,EAAG,GAGnBuQ,GAAMS,EAAMG,KAASG,EAAMvB,GAE3BU,IAAOO,EAAMG,EAAMrB,IAAQuB,EAAMC,EAAMvB,GACvCW,GAAMS,EAAMrB,KAASuB,EAAMC,GAC3BI,EAAKV,EAAMK,EACXM,IAAOX,EAAMI,EAAMlB,IAAQmB,EAAME,EAAMtB,GACvC2B,IAAOZ,EAAMI,IAAQG,EAAMtB,GAC3B4B,GAAMT,EAAMlB,KAASmB,EAAME,GAG3BO,IAAQZ,EAAMhB,EAAME,IAAQL,EAAM0B,EAAMtB,GACxC4B,GAAOb,EAAMd,IAAQL,EAAMI,GAC3B6B,EAAMd,EAAMO,EACZQ,GAAO/B,EAAME,KAASqB,EAAMtB,GAC5B+B,IAAQhB,EAAMpB,EAAME,IAAQC,EAAMwB,EAAMpB,GACxC8B,GAAOjB,EAAMlB,IAAQC,EAAMI,GAC3B+B,GAAOtC,EAAME,KAASyB,EAAMpB,GAO5BM,EAAMe,EAAKM,EANLf,EAAMO,EAOZZ,GAzBMI,EAAMC,EAAMC,EAAMC,EAAMrB,EAAMI,EAAME,GAAOL,EAyBtCU,EAAKC,EAAKgB,EAAKI,EAAME,EAAMC,EACtCI,EAAMX,EAAKC,EAAKE,GAjBTb,EAAMC,EAAMC,EAAMpB,EAAME,EAAMoB,EAAMlB,GAAOD,EAiBvB+B,EAAME,EAAME,EACvCvB,EAAMN,EAzBDT,IAAQuB,EAAMC,EAAME,EAAMzB,EAAME,EAAMwB,EAAMpB,GAyBjCI,EAAKiB,EAAKM,EAAME,EAAMC,EACtCrB,EAAMP,EAAKE,EAAKC,EAAKgB,EATf1B,EAAMG,EAUZmC,EAAMN,EAAME,EAAMC,EAAMC,EATlBjB,EAAMI,EAUZgB,EAAMb,EAAKC,EAAKC,EApBV1B,IAAQmB,EAAME,EAAMC,EAAMzB,EAAME,EAAMwB,EAAMtB,GAoBvB2B,EAAMC,EAAMC,EACvCQ,EAAMV,EAAMC,EAAMC,EAAMC,EAVlBb,EAAME,EAWZmB,EAAMf,EAAKC,EAAKC,EAAKC,EAVfzB,EAAMC,EAqBlB,OATArgB,EAAOoD,IAAI,EAAG,EAAGud,GACjB3gB,EAAOoD,IAAI,EAAG,EAAGwd,GACjB5gB,EAAOoD,IAAI,EAAG,EAAGif,GACjBriB,EAAOoD,IAAI,EAAG,EAAGyd,GACjB7gB,EAAOoD,IAAI,EAAG,EAAG0d,GACjB9gB,EAAOoD,IAAI,EAAG,EAAGkf,GACjBtiB,EAAOoD,IAAI,EAAG,EAAGmf,GACjBviB,EAAOoD,IAAI,EAAG,EAAGof,GACjBxiB,EAAOoD,IAAI,EAAG,EAAGqf,GACVziB,CACT,CAEA0iB,aAAajc,GACXA,EAAI,GAAOuU,YAAYvU,GACvB,IAAID,EAAI3F,KAAKqb,QACTyG,EAAKnc,EAAE8F,KACPsW,EAAKpc,EAAE4R,QACPyK,EAAKpc,EAAE6F,KACPwW,EAAKrc,EAAE2R,QAUX,SAAS2K,EAAMC,EAAK1W,EAAMiD,GACxB,IAAIjK,EAAI0d,EAAI1W,KACR2W,EAAID,EAAI5K,QACZ,GAAI9S,IAAMgH,GAAQ2W,IAAM1T,EACtB,OAAOyT,EACF,CACL,IAAIE,EAAW7I,GAAe5O,MAAMa,EAAMiD,GAE1C,OADA2T,EAAWA,EAASxG,aAAasG,EAAK,EAAG,GAClCE,CACT,CACF,CAnBIN,IAAOC,GAETM,QAAQC,KACN,eAAeT,OAAQC,SAAUC,OAAQC,sCAsB7C,IAAIxd,EAAIhH,KAAKyC,IAAI4hB,EAAIE,GACjBI,EAAI3kB,KAAKyC,IAAI6hB,EAAIE,GAiFrB,OAhFAtc,EAAIuc,EAAMvc,EAAGlB,EAAG2d,GAIhB,SAASI,EAAUjX,EAAGC,EAAGC,EAAMiD,GAE7B,GAAIjD,GAAQ,KAAOiD,GAAQ,IACzB,OAAOnD,EAAEoT,KAAKnT,GAIZC,EAAO,GAAM,GAAKiD,EAAO,GAAM,GACjCnD,EAAI2W,EAAM3W,EAAGE,EAAO,EAAGiD,EAAO,GAC9BlD,EAAI0W,EAAM1W,EAAGC,EAAO,EAAGiD,EAAO,IACrBjD,EAAO,GAAM,GACtBF,EAAI2W,EAAM3W,EAAGE,EAAO,EAAGiD,GACvBlD,EAAI0W,EAAM1W,EAAGC,EAAO,EAAGiD,IACdA,EAAO,GAAM,IACtBnD,EAAI2W,EAAM3W,EAAGE,EAAMiD,EAAO,GAC1BlD,EAAI0W,EAAM1W,EAAGC,EAAMiD,EAAO,IAG5B,IAAI+T,EAAWC,SAASnX,EAAEE,KAAO,EAAG,IAChCkX,EAAWD,SAASnX,EAAEgM,QAAU,EAAG,IAEnC0H,EAAM1T,EAAEqX,UAAU,EAAGH,EAAW,EAAG,EAAGE,EAAW,GACjDzD,EAAM1T,EAAEoX,UAAU,EAAGH,EAAW,EAAG,EAAGE,EAAW,GAEjDxD,EAAM5T,EAAEqX,UAAU,EAAGH,EAAW,EAAGE,EAAUpX,EAAEgM,QAAU,GACzD6H,EAAM5T,EAAEoX,UAAU,EAAGH,EAAW,EAAGE,EAAUnX,EAAE+L,QAAU,GAEzD8H,EAAM9T,EAAEqX,UAAUH,EAAUlX,EAAEE,KAAO,EAAG,EAAGkX,EAAW,GACtDrD,EAAM9T,EAAEoX,UAAUH,EAAUjX,EAAEC,KAAO,EAAG,EAAGkX,EAAW,GAEtDpD,EAAMhU,EAAEqX,UAAUH,EAAUlX,EAAEE,KAAO,EAAGkX,EAAUpX,EAAEgM,QAAU,GAC9DiI,EAAMhU,EAAEoX,UAAUH,EAAUjX,EAAEC,KAAO,EAAGkX,EAAUnX,EAAE+L,QAAU,GAG9DkI,EAAK+C,EACPhJ,GAAehJ,IAAIyO,EAAKM,GACxB/F,GAAehJ,IAAI0O,EAAKM,GACxBiD,EACAE,GAEEjD,EAAK8C,EAAUhJ,GAAehJ,IAAI6O,EAAKE,GAAML,EAAKuD,EAAUE,GAC5DhD,EAAK6C,EAAUvD,EAAKzF,GAAeqJ,IAAIzD,EAAKI,GAAMiD,EAAUE,GAC5D/C,EAAK4C,EAAUjD,EAAK/F,GAAeqJ,IAAIvD,EAAKJ,GAAMuD,EAAUE,GAC5D9C,EAAK2C,EAAUhJ,GAAehJ,IAAIyO,EAAKE,GAAMK,EAAKiD,EAAUE,GAC5D9B,EAAK2B,EACPhJ,GAAeqJ,IAAIxD,EAAKJ,GACxBzF,GAAehJ,IAAI0O,EAAKE,GACxBqD,EACAE,GAEE7B,EAAK0B,EACPhJ,GAAeqJ,IAAI1D,EAAKI,GACxB/F,GAAehJ,IAAI8O,EAAKE,GACxBiD,EACAE,GAIE1C,EAAMzG,GAAehJ,IAAIiP,EAAIG,GACjCK,EAAI4C,IAAIhD,GACRI,EAAIzP,IAAIsQ,GACR,IAAIW,EAAMjI,GAAehJ,IAAImP,EAAIE,GAC7B8B,EAAMnI,GAAehJ,IAAIkP,EAAIE,GAC7BgC,EAAMpI,GAAeqJ,IAAIpD,EAAIC,GACjCkC,EAAIpR,IAAImP,GACRiC,EAAIpR,IAAIqQ,GAGR,IAAIwB,EAAW7I,GAAe5O,MAAM,EAAIqV,EAAIxU,KAAM,EAAIwU,EAAI1I,SAK1D,OAJA8K,EAAWA,EAASxG,aAAaoE,EAAK,EAAG,GACzCoC,EAAWA,EAASxG,aAAa4F,EAAKxB,EAAIxU,KAAM,GAChD4W,EAAWA,EAASxG,aAAa8F,EAAK,EAAG1B,EAAI1I,SAC7C8K,EAAWA,EAASxG,aAAa+F,EAAK3B,EAAIxU,KAAMwU,EAAI1I,SAC7C8K,EAASO,UAAU,EAAGnX,EAAO,EAAG,EAAGiD,EAAO,EACnD,CAEO8T,CAAU7c,EA/EjBC,EAAIsc,EAAMtc,EAAGnB,EAAG2d,GA+EO3d,EAAG2d,EAC5B,CAEAU,UAAU/f,EAAU,CAAC,GACnB,GAAuB,iBAAZA,EACT,MAAM,IAAIiT,UAAU,6BAEtB,MAAM,IAAE/U,EAAM,EAAC,IAAEf,EAAM,GAAM6C,EAC7B,IAAKvB,OAAOuhB,SAAS9hB,GAAM,MAAM,IAAI+U,UAAU,wBAC/C,IAAKxU,OAAOuhB,SAAS7iB,GAAM,MAAM,IAAI8V,UAAU,wBAC/C,GAAI/U,GAAOf,EAAK,MAAM,IAAIwW,WAAW,gCACrC,IAAIkD,EAAY,IAAI,GAAO5Z,KAAKyL,KAAMzL,KAAKuX,SAC3C,IAAK,IAAIhZ,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAAK,CAClC,MAAM4N,EAAMnM,KAAKgc,OAAOzd,GACpB4N,EAAI9N,OAAS,GACfyX,GAAQ3J,EAAK,CAAElL,MAAKf,MAAKoK,OAAQ6B,IAEnCyN,EAAUuC,OAAO5d,EAAG4N,EACtB,CACA,OAAOyN,CACT,CAEAoJ,aAAajgB,EAAU,CAAC,GACtB,GAAuB,iBAAZA,EACT,MAAM,IAAIiT,UAAU,6BAEtB,MAAM,IAAE/U,EAAM,EAAC,IAAEf,EAAM,GAAM6C,EAC7B,IAAKvB,OAAOuhB,SAAS9hB,GAAM,MAAM,IAAI+U,UAAU,wBAC/C,IAAKxU,OAAOuhB,SAAS7iB,GAAM,MAAM,IAAI8V,UAAU,wBAC/C,GAAI/U,GAAOf,EAAK,MAAM,IAAIwW,WAAW,gCACrC,IAAIkD,EAAY,IAAI,GAAO5Z,KAAKyL,KAAMzL,KAAKuX,SAC3C,IAAK,IAAIhZ,EAAI,EAAGA,EAAIyB,KAAKuX,QAAShZ,IAAK,CACrC,MAAMsb,EAAS7Z,KAAKuc,UAAUhe,GAC1Bsb,EAAOxb,QACTyX,GAAQ+D,EAAQ,CACd5Y,IAAKA,EACLf,IAAKA,EACLoK,OAAQuP,IAGZD,EAAU8C,UAAUne,EAAGsb,EACzB,CACA,OAAOD,CACT,CAEAqJ,WACE,MAAMC,EAASzlB,KAAK0lB,KAAKnjB,KAAKuX,QAAU,GACxC,IAAK,IAAIhZ,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIikB,EAAQjkB,IAAK,CAC/B,IAAImkB,EAAQpjB,KAAKmP,IAAI5Q,EAAGU,GACpBokB,EAAOrjB,KAAKmP,IAAI5Q,EAAGyB,KAAKuX,QAAU,EAAItY,GAC1Ce,KAAKuC,IAAIhE,EAAGU,EAAGokB,GACfrjB,KAAKuC,IAAIhE,EAAGyB,KAAKuX,QAAU,EAAItY,EAAGmkB,EACpC,CAEF,OAAOpjB,IACT,CAEAsjB,cACE,MAAMJ,EAASzlB,KAAK0lB,KAAKnjB,KAAKyL,KAAO,GACrC,IAAK,IAAIxM,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChC,IAAK,IAAIV,EAAI,EAAGA,EAAI2kB,EAAQ3kB,IAAK,CAC/B,IAAI6kB,EAAQpjB,KAAKmP,IAAI5Q,EAAGU,GACpBokB,EAAOrjB,KAAKmP,IAAInP,KAAKyL,KAAO,EAAIlN,EAAGU,GACvCe,KAAKuC,IAAIhE,EAAGU,EAAGokB,GACfrjB,KAAKuC,IAAIvC,KAAKyL,KAAO,EAAIlN,EAAGU,EAAGmkB,EACjC,CAEF,OAAOpjB,IACT,CAEAujB,iBAAiB3E,GACfA,EAAQ,GAAOzE,YAAYyE,GAE3B,IAAI/N,EAAI7Q,KAAKyL,KACTvG,EAAIlF,KAAKuX,QACTtZ,EAAI2gB,EAAMnT,KACVvN,EAAI0gB,EAAMrH,QAEVpY,EAAS,IAAI,GAAO0R,EAAI5S,EAAGiH,EAAIhH,GACnC,IAAK,IAAIK,EAAI,EAAGA,EAAIsS,EAAGtS,IACrB,IAAK,IAAIU,EAAI,EAAGA,EAAIiG,EAAGjG,IACrB,IAAK,IAAIoM,EAAI,EAAGA,EAAIpN,EAAGoN,IACrB,IAAK,IAAI2O,EAAI,EAAGA,EAAI9b,EAAG8b,IACrB7a,EAAOoD,IAAItE,EAAIM,EAAI8M,EAAGnN,EAAIe,EAAI+a,EAAGha,KAAKmP,IAAI5Q,EAAGU,GAAK2f,EAAMzP,IAAI9D,EAAG2O,IAKvE,OAAO7a,CACT,CAEAqkB,aAAa5E,GAEX,GADAA,EAAQ,GAAOzE,YAAYyE,IACtB5e,KAAK8a,aAAe8D,EAAM9D,WAC7B,MAAM,IAAI/c,MAAM,2CAElB,IAAI8S,EAAI7Q,KAAKyL,KACTvG,EAAI0Z,EAAMnT,KACVgY,EAAMzjB,KAAKujB,iBAAiB,GAAOG,IAAIxe,EAAGA,IAC1Cye,EAAM,GAAOD,IAAI7S,EAAGA,GAAG0S,iBAAiB3E,GAC5C,OAAO6E,EAAIjT,IAAImT,EACjB,CAEAC,YACE,IAAIzkB,EAAS,IAAI,GAAOa,KAAKuX,QAASvX,KAAKyL,MAC3C,IAAK,IAAIlN,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCE,EAAOoD,IAAItD,EAAGV,EAAGyB,KAAKmP,IAAI5Q,EAAGU,IAGjC,OAAOE,CACT,CAEA0kB,SAASC,EAAkBC,IACzB,IAAK,IAAIxlB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7ByB,KAAKmc,OAAO5d,EAAGyB,KAAKgc,OAAOzd,GAAGiR,KAAKsU,IAErC,OAAO9jB,IACT,CAEAgkB,YAAYF,EAAkBC,IAC5B,IAAK,IAAIxlB,EAAI,EAAGA,EAAIyB,KAAKuX,QAAShZ,IAChCyB,KAAK0c,UAAUne,EAAGyB,KAAKuc,UAAUhe,GAAGiR,KAAKsU,IAE3C,OAAO9jB,IACT,CAEA4iB,UAAUhhB,EAAUR,EAAQ6X,EAAaC,GACvCF,GAAWhZ,KAAM4B,EAAUR,EAAQ6X,EAAaC,GAChD,IAAIU,EAAY,IAAI,GAClBxY,EAASQ,EAAW,EACpBsX,EAAYD,EAAc,GAE5B,IAAK,IAAI1a,EAAIqD,EAAUrD,GAAK6C,EAAQ7C,IAClC,IAAK,IAAIU,EAAIga,EAAaha,GAAKia,EAAWja,IACxC2a,EAAUrX,IAAIhE,EAAIqD,EAAU3C,EAAIga,EAAajZ,KAAKmP,IAAI5Q,EAAGU,IAG7D,OAAO2a,CACT,CAEAqK,aAAa3X,EAAS2M,EAAaC,GAGjC,QAFoB1O,IAAhByO,IAA2BA,EAAc,QAC3BzO,IAAd0O,IAAyBA,EAAYlZ,KAAKuX,QAAU,GAEtD0B,EAAcC,GACdD,EAAc,GACdA,GAAejZ,KAAKuX,SACpB2B,EAAY,GACZA,GAAalZ,KAAKuX,QAElB,MAAM,IAAIb,WAAW,yBAGvB,IAAIkD,EAAY,IAAI,GAAOtN,EAAQjO,OAAQ6a,EAAYD,EAAc,GACrE,IAAK,IAAI1a,EAAI,EAAGA,EAAI+N,EAAQjO,OAAQE,IAClC,IAAK,IAAIU,EAAIga,EAAaha,GAAKia,EAAWja,IAAK,CAC7C,GAAIqN,EAAQ/N,GAAK,GAAK+N,EAAQ/N,IAAMyB,KAAKyL,KACvC,MAAM,IAAIiL,WAAW,2BAA2BpK,EAAQ/N,MAE1Dqb,EAAUrX,IAAIhE,EAAGU,EAAIga,EAAajZ,KAAKmP,IAAI7C,EAAQ/N,GAAIU,GACzD,CAEF,OAAO2a,CACT,CAEAsK,gBAAgB5X,EAAS1K,EAAUR,GAGjC,QAFiBoJ,IAAb5I,IAAwBA,EAAW,QACxB4I,IAAXpJ,IAAsBA,EAASpB,KAAKyL,KAAO,GAE7C7J,EAAWR,GACXQ,EAAW,GACXA,GAAY5B,KAAKyL,MACjBrK,EAAS,GACTA,GAAUpB,KAAKyL,KAEf,MAAM,IAAIiL,WAAW,yBAGvB,IAAIkD,EAAY,IAAI,GAAOxY,EAASQ,EAAW,EAAG0K,EAAQjO,QAC1D,IAAK,IAAIE,EAAI,EAAGA,EAAI+N,EAAQjO,OAAQE,IAClC,IAAK,IAAIU,EAAI2C,EAAU3C,GAAKmC,EAAQnC,IAAK,CACvC,GAAIqN,EAAQ/N,GAAK,GAAK+N,EAAQ/N,IAAMyB,KAAKuX,QACvC,MAAM,IAAIb,WAAW,8BAA8BpK,EAAQ/N,MAE7Dqb,EAAUrX,IAAItD,EAAI2C,EAAUrD,EAAGyB,KAAKmP,IAAIlQ,EAAGqN,EAAQ/N,IACrD,CAEF,OAAOqb,CACT,CAEAiC,aAAajd,EAAQgD,EAAUqX,GAE7B,IADAra,EAAS,GAAOub,YAAYvb,IACjB2a,UACT,OAAOvZ,KAITgZ,GAAWhZ,KAAM4B,EAFJA,EAAWhD,EAAO6M,KAAO,EAEHwN,EADnBA,EAAcra,EAAO2Y,QAAU,GAE/C,IAAK,IAAIhZ,EAAI,EAAGA,EAAIK,EAAO6M,KAAMlN,IAC/B,IAAK,IAAIU,EAAI,EAAGA,EAAIL,EAAO2Y,QAAStY,IAClCe,KAAKuC,IAAIX,EAAWrD,EAAG0a,EAAcha,EAAGL,EAAOuQ,IAAI5Q,EAAGU,IAG1D,OAAOe,IACT,CAEAmkB,UAAUC,EAAYC,ID7sCjB,SAAyBzlB,EAAQwlB,GACtC,IAAK,GAAWA,GACd,MAAM,IAAIpO,UAAU,gCAGtB,IAAK,IAAIzX,EAAI,EAAGA,EAAI6lB,EAAW/lB,OAAQE,IACrC,GAAI6lB,EAAW7lB,GAAK,GAAK6lB,EAAW7lB,IAAMK,EAAO6M,KAC/C,MAAM,IAAIiL,WAAW,+BAG3B,CCosCI4N,CAAgBtkB,KAAMokB,GDlsCnB,SAA4BxlB,EAAQylB,GACzC,IAAK,GAAWA,GACd,MAAM,IAAIrO,UAAU,mCAGtB,IAAK,IAAIzX,EAAI,EAAGA,EAAI8lB,EAAchmB,OAAQE,IACxC,GAAI8lB,EAAc9lB,GAAK,GAAK8lB,EAAc9lB,IAAMK,EAAO2Y,QACrD,MAAM,IAAIb,WAAW,kCAG3B,CCyrCI6N,CAAmBvkB,KAAMqkB,GACzB,IAAIzK,EAAY,IAAI,GAAOwK,EAAW/lB,OAAQgmB,EAAchmB,QAC5D,IAAK,IAAIE,EAAI,EAAGA,EAAI6lB,EAAW/lB,OAAQE,IAAK,CAC1C,IAAIimB,EAAWJ,EAAW7lB,GAC1B,IAAK,IAAIU,EAAI,EAAGA,EAAIolB,EAAchmB,OAAQY,IAAK,CAC7C,IAAIwlB,EAAcJ,EAAcplB,GAChC2a,EAAUrX,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAIqV,EAAUC,GACzC,CACF,CACA,OAAO7K,CACT,CAEA8K,QACE,IAAIzjB,EAAMxD,KAAKwD,IAAIjB,KAAKyL,KAAMzL,KAAKuX,SAC/BmN,EAAQ,EACZ,IAAK,IAAInmB,EAAI,EAAGA,EAAI0C,EAAK1C,IACvBmmB,GAAS1kB,KAAKmP,IAAI5Q,EAAGA,GAEvB,OAAOmmB,CACT,CAEArJ,QACE,IAAIzB,EAAY,IAAI,GAAO5Z,KAAKyL,KAAMzL,KAAKuX,SAC3C,IAAK,IAAIpL,EAAM,EAAGA,EAAMnM,KAAKyL,KAAMU,IACjC,IAAK,IAAI0N,EAAS,EAAGA,EAAS7Z,KAAKuX,QAASsC,IAC1CD,EAAUrX,IAAI4J,EAAK0N,EAAQ7Z,KAAKmP,IAAIhD,EAAK0N,IAG7C,OAAOD,CACT,CAEA7O,IAAIyS,GACF,OAAQA,GACN,IAAK,MACH,OCnzCD,SAAkB5e,GACvB,IAAImM,EAAMqO,GAASxa,EAAO6M,MAC1B,IAAK,IAAIlN,EAAI,EAAGA,EAAIK,EAAO6M,OAAQlN,EACjC,IAAK,IAAIU,EAAI,EAAGA,EAAIL,EAAO2Y,UAAWtY,EACpC8L,EAAIxM,IAAMK,EAAOuQ,IAAI5Q,EAAGU,GAG5B,OAAO8L,CACT,CD2yCe4Z,CAAS3kB,MAClB,IAAK,SACH,OC3yCD,SAAqBpB,GAC1B,IAAImM,EAAMqO,GAASxa,EAAO2Y,SAC1B,IAAK,IAAIhZ,EAAI,EAAGA,EAAIK,EAAO6M,OAAQlN,EACjC,IAAK,IAAIU,EAAI,EAAGA,EAAIL,EAAO2Y,UAAWtY,EACpC8L,EAAI9L,IAAML,EAAOuQ,IAAI5Q,EAAGU,GAG5B,OAAO8L,CACT,CDmyCe6Z,CAAY5kB,MACrB,UAAKwK,EACH,OCnyCD,SAAgB5L,GACrB,IAAI+L,EAAI,EACR,IAAK,IAAIpM,EAAI,EAAGA,EAAIK,EAAO6M,KAAMlN,IAC/B,IAAK,IAAIU,EAAI,EAAGA,EAAIL,EAAO2Y,QAAStY,IAClC0L,GAAK/L,EAAOuQ,IAAI5Q,EAAGU,GAGvB,OAAO0L,CACT,CD2xCeka,CAAO7kB,MAChB,QACE,MAAM,IAAIjC,MAAM,mBAAmByf,KAEzC,CAEAsH,QAAQtH,GACN,OAAQA,GACN,IAAK,MACH,OClyCD,SAAsB5e,GAC3B,IAAImM,EAAMqO,GAASxa,EAAO6M,KAAM,GAChC,IAAK,IAAIlN,EAAI,EAAGA,EAAIK,EAAO6M,OAAQlN,EACjC,IAAK,IAAIU,EAAI,EAAGA,EAAIL,EAAO2Y,UAAWtY,EACpC8L,EAAIxM,IAAMK,EAAOuQ,IAAI5Q,EAAGU,GAG5B,OAAO8L,CACT,CD0xCega,CAAa/kB,MACtB,IAAK,SACH,OC1xCD,SAAyBpB,GAC9B,IAAImM,EAAMqO,GAASxa,EAAO2Y,QAAS,GACnC,IAAK,IAAIhZ,EAAI,EAAGA,EAAIK,EAAO6M,OAAQlN,EACjC,IAAK,IAAIU,EAAI,EAAGA,EAAIL,EAAO2Y,UAAWtY,EACpC8L,EAAI9L,IAAML,EAAOuQ,IAAI5Q,EAAGU,GAG5B,OAAO8L,CACT,CDkxCeia,CAAgBhlB,MACzB,UAAKwK,EACH,OClxCD,SAAoB5L,GACzB,IAAI+L,EAAI,EACR,IAAK,IAAIpM,EAAI,EAAGA,EAAIK,EAAO6M,KAAMlN,IAC/B,IAAK,IAAIU,EAAI,EAAGA,EAAIL,EAAO2Y,QAAStY,IAClC0L,GAAK/L,EAAOuQ,IAAI5Q,EAAGU,GAGvB,OAAO0L,CACT,CD0wCesa,CAAWjlB,MACpB,QACE,MAAM,IAAIjC,MAAM,mBAAmByf,KAEzC,CAEA3S,KAAK2S,GACH,MAAMzS,EAAM/K,KAAK+K,IAAIyS,GACrB,OAAQA,GACN,IAAK,MACH,IAAK,IAAIjf,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7BwM,EAAIxM,IAAMyB,KAAKuX,QAEjB,OAAOxM,EAET,IAAK,SACH,IAAK,IAAIxM,EAAI,EAAGA,EAAIyB,KAAKuX,QAAShZ,IAChCwM,EAAIxM,IAAMyB,KAAKyL,KAEjB,OAAOV,EAET,UAAKP,EACH,OAAOO,EAAM/K,KAAKR,KACpB,QACE,MAAM,IAAIzB,MAAM,mBAAmByf,KAEzC,CAEA0H,SAAS1H,EAAIza,EAAU,CAAC,GAKtB,GAJkB,iBAAPya,IACTza,EAAUya,EACVA,OAAKhT,GAEgB,iBAAZzH,EACT,MAAM,IAAIiT,UAAU,6BAEtB,MAAM,SAAEmP,GAAW,EAAI,KAAEta,EAAO7K,KAAK6K,KAAK2S,IAAQza,EAClD,GAAwB,kBAAboiB,EACT,MAAM,IAAInP,UAAU,8BAEtB,OAAQwH,GACN,IAAK,MACH,IAAK,GAAW3S,GACd,MAAM,IAAImL,UAAU,yBAEtB,OCrzCD,SAAuBpX,EAAQumB,EAAUta,GAC9C,MAAMY,EAAO7M,EAAO6M,KACdiD,EAAO9P,EAAO2Y,QACd2N,EAAW,GAEjB,IAAK,IAAI3mB,EAAI,EAAGA,EAAIkN,EAAMlN,IAAK,CAC7B,IAAI6mB,EAAO,EACPC,EAAO,EACP1f,EAAI,EACR,IAAK,IAAI1G,EAAI,EAAGA,EAAIyP,EAAMzP,IACxB0G,EAAI/G,EAAOuQ,IAAI5Q,EAAGU,GAAK4L,EAAKtM,GAC5B6mB,GAAQzf,EACR0f,GAAQ1f,EAAIA,EAEVwf,EACFD,EAAS3a,MAAM8a,EAAQD,EAAOA,EAAQ1W,IAASA,EAAO,IAEtDwW,EAAS3a,MAAM8a,EAAQD,EAAOA,EAAQ1W,GAAQA,EAElD,CACA,OAAOwW,CACT,CDgyCeI,CAActlB,KAAMmlB,EAAUta,GAEvC,IAAK,SACH,IAAK,GAAWA,GACd,MAAM,IAAImL,UAAU,yBAEtB,OCpyCD,SAA0BpX,EAAQumB,EAAUta,GACjD,MAAMY,EAAO7M,EAAO6M,KACdiD,EAAO9P,EAAO2Y,QACd2N,EAAW,GAEjB,IAAK,IAAIjmB,EAAI,EAAGA,EAAIyP,EAAMzP,IAAK,CAC7B,IAAImmB,EAAO,EACPC,EAAO,EACP1f,EAAI,EACR,IAAK,IAAIpH,EAAI,EAAGA,EAAIkN,EAAMlN,IACxBoH,EAAI/G,EAAOuQ,IAAI5Q,EAAGU,GAAK4L,EAAK5L,GAC5BmmB,GAAQzf,EACR0f,GAAQ1f,EAAIA,EAEVwf,EACFD,EAAS3a,MAAM8a,EAAQD,EAAOA,EAAQ3Z,IAASA,EAAO,IAEtDyZ,EAAS3a,MAAM8a,EAAQD,EAAOA,EAAQ3Z,GAAQA,EAElD,CACA,OAAOyZ,CACT,CD+wCeK,CAAiBvlB,KAAMmlB,EAAUta,GAE1C,UAAKL,EACH,GAAoB,iBAATK,EACT,MAAM,IAAImL,UAAU,yBAEtB,OCnxCD,SAAqBpX,EAAQumB,EAAUta,GAC5C,MAAMY,EAAO7M,EAAO6M,KACdiD,EAAO9P,EAAO2Y,QACd/X,EAAOiM,EAAOiD,EAEpB,IAAI0W,EAAO,EACPC,EAAO,EACP1f,EAAI,EACR,IAAK,IAAIpH,EAAI,EAAGA,EAAIkN,EAAMlN,IACxB,IAAK,IAAIU,EAAI,EAAGA,EAAIyP,EAAMzP,IACxB0G,EAAI/G,EAAOuQ,IAAI5Q,EAAGU,GAAK4L,EACvBua,GAAQzf,EACR0f,GAAQ1f,EAAIA,EAGhB,OAAIwf,GACME,EAAQD,EAAOA,EAAQ5lB,IAASA,EAAO,IAEvC6lB,EAAQD,EAAOA,EAAQ5lB,GAAQA,CAE3C,CD+vCegmB,CAAYxlB,KAAMmlB,EAAUta,GAErC,QACE,MAAM,IAAI9M,MAAM,mBAAmByf,KAEzC,CAEAiI,kBAAkBjI,EAAIza,GACF,iBAAPya,IACTza,EAAUya,EACVA,OAAKhT,GAEP,MAAM0a,EAAWllB,KAAKklB,SAAS1H,EAAIza,GACnC,QAAWyH,IAAPgT,EACF,OAAO/f,KAAK6B,KAAK4lB,GAEjB,IAAK,IAAI3mB,EAAI,EAAGA,EAAI2mB,EAAS7mB,OAAQE,IACnC2mB,EAAS3mB,GAAKd,KAAK6B,KAAK4lB,EAAS3mB,IAEnC,OAAO2mB,CAEX,CAEAQ,OAAOlI,EAAIza,EAAU,CAAC,GAKpB,GAJkB,iBAAPya,IACTza,EAAUya,EACVA,OAAKhT,GAEgB,iBAAZzH,EACT,MAAM,IAAIiT,UAAU,6BAEtB,MAAM,OAAE0P,EAAS1lB,KAAK6K,KAAK2S,IAAQza,EACnC,OAAQya,GACN,IAAK,MACH,IAAK,GAAWkI,GACd,MAAM,IAAI1P,UAAU,2BAGtB,OCnyCD,SAAqBpX,EAAQiM,GAClC,IAAK,IAAItM,EAAI,EAAGA,EAAIK,EAAO6M,KAAMlN,IAC/B,IAAK,IAAIU,EAAI,EAAGA,EAAIL,EAAO2Y,QAAStY,IAClCL,EAAO2D,IAAIhE,EAAGU,EAAGL,EAAOuQ,IAAI5Q,EAAGU,GAAK4L,EAAKtM,GAG/C,CD4xCQonB,CAAY3lB,KAAM0lB,GACX1lB,KAET,IAAK,SACH,IAAK,GAAW0lB,GACd,MAAM,IAAI1P,UAAU,2BAGtB,OClyCD,SAAwBpX,EAAQiM,GACrC,IAAK,IAAItM,EAAI,EAAGA,EAAIK,EAAO6M,KAAMlN,IAC/B,IAAK,IAAIU,EAAI,EAAGA,EAAIL,EAAO2Y,QAAStY,IAClCL,EAAO2D,IAAIhE,EAAGU,EAAGL,EAAOuQ,IAAI5Q,EAAGU,GAAK4L,EAAK5L,GAG/C,CD2xCQ2mB,CAAe5lB,KAAM0lB,GACd1lB,KAET,UAAKwK,EACH,GAAsB,iBAAXkb,EACT,MAAM,IAAI1P,UAAU,2BAGtB,OCjyCD,SAAmBpX,EAAQiM,GAChC,IAAK,IAAItM,EAAI,EAAGA,EAAIK,EAAO6M,KAAMlN,IAC/B,IAAK,IAAIU,EAAI,EAAGA,EAAIL,EAAO2Y,QAAStY,IAClCL,EAAO2D,IAAIhE,EAAGU,EAAGL,EAAOuQ,IAAI5Q,EAAGU,GAAK4L,EAG1C,CD0xCQgb,CAAU7lB,KAAM0lB,GACT1lB,KAET,QACE,MAAM,IAAIjC,MAAM,mBAAmByf,KAEzC,CAEA7e,MAAM6e,EAAIza,EAAU,CAAC,GAKnB,GAJkB,iBAAPya,IACTza,EAAUya,EACVA,OAAKhT,GAEgB,iBAAZzH,EACT,MAAM,IAAIiT,UAAU,6BAEtB,IAAIrX,EAAQoE,EAAQpE,MACpB,OAAQ6e,GACN,IAAK,MACH,QAAchT,IAAV7L,EACFA,EC5yCH,SAAuBC,GAC5B,MAAMD,EAAQ,GACd,IAAK,IAAIJ,EAAI,EAAGA,EAAIK,EAAO6M,KAAMlN,IAAK,CACpC,IAAIwM,EAAM,EACV,IAAK,IAAI9L,EAAI,EAAGA,EAAIL,EAAO2Y,QAAStY,IAClC8L,GAAOtN,KAAK4B,IAAIT,EAAOuQ,IAAI5Q,EAAGU,GAAI,IAAML,EAAO2Y,QAAU,GAE3D5Y,EAAM4L,KAAK9M,KAAK6B,KAAKyL,GACvB,CACA,OAAOpM,CACT,CDkyCkBmnB,CAAc9lB,WACjB,IAAK,GAAWrB,GACrB,MAAM,IAAIqX,UAAU,0BAGtB,OCryCD,SAAoBpX,EAAQD,GACjC,IAAK,IAAIJ,EAAI,EAAGA,EAAIK,EAAO6M,KAAMlN,IAC/B,IAAK,IAAIU,EAAI,EAAGA,EAAIL,EAAO2Y,QAAStY,IAClCL,EAAO2D,IAAIhE,EAAGU,EAAGL,EAAOuQ,IAAI5Q,EAAGU,GAAKN,EAAMJ,GAGhD,CD8xCQwnB,CAAW/lB,KAAMrB,GACVqB,KAET,IAAK,SACH,QAAcwK,IAAV7L,EACFA,ECjyCH,SAA0BC,GAC/B,MAAMD,EAAQ,GACd,IAAK,IAAIM,EAAI,EAAGA,EAAIL,EAAO2Y,QAAStY,IAAK,CACvC,IAAI8L,EAAM,EACV,IAAK,IAAIxM,EAAI,EAAGA,EAAIK,EAAO6M,KAAMlN,IAC/BwM,GAAOtN,KAAK4B,IAAIT,EAAOuQ,IAAI5Q,EAAGU,GAAI,IAAML,EAAO6M,KAAO,GAExD9M,EAAM4L,KAAK9M,KAAK6B,KAAKyL,GACvB,CACA,OAAOpM,CACT,CDuxCkBqnB,CAAiBhmB,WACpB,IAAK,GAAWrB,GACrB,MAAM,IAAIqX,UAAU,0BAGtB,OC1xCD,SAAuBpX,EAAQD,GACpC,IAAK,IAAIJ,EAAI,EAAGA,EAAIK,EAAO6M,KAAMlN,IAC/B,IAAK,IAAIU,EAAI,EAAGA,EAAIL,EAAO2Y,QAAStY,IAClCL,EAAO2D,IAAIhE,EAAGU,EAAGL,EAAOuQ,IAAI5Q,EAAGU,GAAKN,EAAMM,GAGhD,CDmxCQgnB,CAAcjmB,KAAMrB,GACbqB,KAET,UAAKwK,EACH,QAAcA,IAAV7L,EACFA,ECtxCH,SAAqBC,GAC1B,MAAMsnB,EAAUtnB,EAAOY,KAAO,EAC9B,IAAIuL,EAAM,EACV,IAAK,IAAI9L,EAAI,EAAGA,EAAIL,EAAO2Y,QAAStY,IAClC,IAAK,IAAIV,EAAI,EAAGA,EAAIK,EAAO6M,KAAMlN,IAC/BwM,GAAOtN,KAAK4B,IAAIT,EAAOuQ,IAAI5Q,EAAGU,GAAI,GAAKinB,EAG3C,OAAOzoB,KAAK6B,KAAKyL,EACnB,CD6wCkBob,CAAYnmB,WACf,GAAqB,iBAAVrB,EAChB,MAAM,IAAIqX,UAAU,0BAGtB,OChxCD,SAAkBpX,EAAQD,GAC/B,IAAK,IAAIJ,EAAI,EAAGA,EAAIK,EAAO6M,KAAMlN,IAC/B,IAAK,IAAIU,EAAI,EAAGA,EAAIL,EAAO2Y,QAAStY,IAClCL,EAAO2D,IAAIhE,EAAGU,EAAGL,EAAOuQ,IAAI5Q,EAAGU,GAAKN,EAG1C,CDywCQynB,CAASpmB,KAAMrB,GACRqB,KAET,QACE,MAAM,IAAIjC,MAAM,mBAAmByf,KAEzC,CAEAxT,SAASjH,GACP,OAAOmU,GAAyBlX,KAAM+C,EACxC,EASF,SAASghB,GAAexY,EAAGC,GACzB,OAAOD,EAAIC,CACb,CARAgO,GAAenE,UAAUgF,MAAQ,SACX,oBAAXgM,SACT7M,GAAenE,UAAUgR,OAAOC,IAAI,+BFx+C/B,WACL,OAAOpP,GAAyBlX,KAClC,GEq/CAwZ,GAAe9b,OAAS8b,GAAe+M,KACvC/M,GAAegN,UAAYhN,GAAeiN,QAC1CjN,GAAekN,SAAWlN,GAAe6E,KACzC7E,GAAenE,UAAUqR,SAAWlN,GAAenE,UAAUgJ,KAC7D7E,GAAemN,SAAWnN,GAAekK,IACzClK,GAAenE,UAAUuR,OAASpN,GAAenE,UAAUyG,IAC3DtC,GAAenE,UAAUwR,cACvBrN,GAAenE,UAAUkO,iBAEZ,MAAM,WAAe/J,GAClC9Z,YAAYoP,EAAOgY,GAEjB,GADAhiB,QACI,GAAOsV,SAAStL,GAElB,OAAOA,EAAMuM,QACR,GAAI7Z,OAAO8U,UAAUxH,IAAUA,GAAS,EAAG,CAGhD,GADA9O,KAAKmC,KAAO,KACRX,OAAO8U,UAAUwQ,IAAaA,GAAY,GAK5C,MAAM,IAAI9Q,UAAU,uCAJpB,IAAK,IAAIzX,EAAI,EAAGA,EAAIuQ,EAAOvQ,IACzByB,KAAKmC,KAAKoI,KAAK,IAAIuU,aAAagI,GAKtC,KAAO,KAAI,GAAWhY,GAqBpB,MAAM,IAAIkH,UACR,wDAtB0B,CAE5B,MAAM+Q,EAAYjY,EAGlB,GAAwB,iBADxBgY,GADAhY,EAAQiY,EAAU1oB,QACC0oB,EAAU,GAAG1oB,OAAS,GAEvC,MAAM,IAAI2X,UACR,qDAGJhW,KAAKmC,KAAO,GACZ,IAAK,IAAI5D,EAAI,EAAGA,EAAIuQ,EAAOvQ,IAAK,CAC9B,GAAIwoB,EAAUxoB,GAAGF,SAAWyoB,EAC1B,MAAM,IAAIpQ,WAAW,iCAEvB,IAAsBqQ,EAAUxoB,GA9CzByoB,OAAOC,GACQ,iBAAZA,IA8CR,MAAM,IAAIjR,UAAU,0CAEtBhW,KAAKmC,KAAKoI,KAAKuU,aAAanP,KAAKoX,EAAUxoB,IAC7C,CACF,CAIA,CACAyB,KAAKyL,KAAOqD,EACZ9O,KAAKuX,QAAUuP,CACjB,CAEAvkB,IAAIiiB,EAAUC,EAAa/hB,GAEzB,OADA1C,KAAKmC,KAAKqiB,GAAUC,GAAe/hB,EAC5B1C,IACT,CAEAmP,IAAIqV,EAAUC,GACZ,OAAOzkB,KAAKmC,KAAKqiB,GAAUC,EAC7B,CAEAyC,UAAUvkB,GAIR,OAHA8V,GAAczY,KAAM2C,GACpB3C,KAAKmC,KAAK2S,OAAOnS,EAAO,GACxB3C,KAAKyL,MAAQ,EACNzL,IACT,CAEAmnB,OAAOxkB,EAAO0W,GASZ,YARc7O,IAAV6O,IACFA,EAAQ1W,EACRA,EAAQ3C,KAAKyL,MAEfgN,GAAczY,KAAM2C,GAAO,GAC3B0W,EAAQyF,aAAanP,KAAKiJ,GAAe5Y,KAAMqZ,IAC/CrZ,KAAKmC,KAAK2S,OAAOnS,EAAO,EAAG0W,GAC3BrZ,KAAKyL,MAAQ,EACNzL,IACT,CAEAonB,aAAazkB,GACXgW,GAAiB3Y,KAAM2C,GACvB,IAAK,IAAIpE,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAAK,CAClC,MAAM8oB,EAAS,IAAIvI,aAAa9e,KAAKuX,QAAU,GAC/C,IAAK,IAAItY,EAAI,EAAGA,EAAI0D,EAAO1D,IACzBooB,EAAOpoB,GAAKe,KAAKmC,KAAK5D,GAAGU,GAE3B,IAAK,IAAIA,EAAI0D,EAAQ,EAAG1D,EAAIe,KAAKuX,QAAStY,IACxCooB,EAAOpoB,EAAI,GAAKe,KAAKmC,KAAK5D,GAAGU,GAE/Be,KAAKmC,KAAK5D,GAAK8oB,CACjB,CAEA,OADArnB,KAAKuX,SAAW,EACTvX,IACT,CAEAsnB,UAAU3kB,EAAO0W,QACM,IAAVA,IACTA,EAAQ1W,EACRA,EAAQ3C,KAAKuX,SAEfoB,GAAiB3Y,KAAM2C,GAAO,GAC9B0W,EAAQN,GAAkB/Y,KAAMqZ,GAChC,IAAK,IAAI9a,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAAK,CAClC,MAAM8oB,EAAS,IAAIvI,aAAa9e,KAAKuX,QAAU,GAC/C,IAAItY,EAAI,EACR,KAAOA,EAAI0D,EAAO1D,IAChBooB,EAAOpoB,GAAKe,KAAKmC,KAAK5D,GAAGU,GAG3B,IADAooB,EAAOpoB,KAAOoa,EAAM9a,GACbU,EAAIe,KAAKuX,QAAU,EAAGtY,IAC3BooB,EAAOpoB,GAAKe,KAAKmC,KAAK5D,GAAGU,EAAI,GAE/Be,KAAKmC,KAAK5D,GAAK8oB,CACjB,CAEA,OADArnB,KAAKuX,SAAW,EACTvX,IACT,GEjnDK,SAA+BwZ,EAAgB+N,GACpD/N,EAAenE,UAAU7E,IAAM,SAAa9N,GAC1C,MAAqB,iBAAVA,EAA2B1C,KAAKwnB,KAAK9kB,GACzC1C,KAAKynB,KAAK/kB,EACnB,EAEA8W,EAAenE,UAAUmS,KAAO,SAAc9kB,GAC5C,IAAK,IAAInE,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAKyD,GAGpC,OAAO1C,IACT,EAEAwZ,EAAenE,UAAUoS,KAAO,SAAc7oB,GAE5C,GADAA,EAAS2oB,EAAOpN,YAAYvb,GACxBoB,KAAKyL,OAAS7M,EAAO6M,MACvBzL,KAAKuX,UAAY3Y,EAAO2Y,QACxB,MAAM,IAAIb,WAAW,qCAEvB,IAAK,IAAInY,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAKL,EAAOuQ,IAAI5Q,EAAGU,IAGlD,OAAOe,IACT,EAEAwZ,EAAehJ,IAAM,SAAa5R,EAAQ8D,GAExC,OADkB,IAAI6kB,EAAO3oB,GACZ4R,IAAI9N,EACvB,EAEA8W,EAAenE,UAAUwN,IAAM,SAAangB,GAC1C,MAAqB,iBAAVA,EAA2B1C,KAAK0nB,KAAKhlB,GACzC1C,KAAK2nB,KAAKjlB,EACnB,EAEA8W,EAAenE,UAAUqS,KAAO,SAAchlB,GAC5C,IAAK,IAAInE,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAKyD,GAGpC,OAAO1C,IACT,EAEAwZ,EAAenE,UAAUsS,KAAO,SAAc/oB,GAE5C,GADAA,EAAS2oB,EAAOpN,YAAYvb,GACxBoB,KAAKyL,OAAS7M,EAAO6M,MACvBzL,KAAKuX,UAAY3Y,EAAO2Y,QACxB,MAAM,IAAIb,WAAW,qCAEvB,IAAK,IAAInY,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAKL,EAAOuQ,IAAI5Q,EAAGU,IAGlD,OAAOe,IACT,EAEAwZ,EAAeqJ,IAAM,SAAajkB,EAAQ8D,GAExC,OADkB,IAAI6kB,EAAO3oB,GACZikB,IAAIngB,EACvB,EACA8W,EAAenE,UAAU5E,SAAW+I,EAAenE,UAAUwN,IAC7DrJ,EAAenE,UAAUuS,UAAYpO,EAAenE,UAAUqS,KAC9DlO,EAAenE,UAAUwS,UAAYrO,EAAenE,UAAUsS,KAC9DnO,EAAe/I,SAAW+I,EAAeqJ,IAEzCrJ,EAAenE,UAAUyS,IAAM,SAAaplB,GAC1C,MAAqB,iBAAVA,EAA2B1C,KAAK+b,KAAKrZ,GACzC1C,KAAK+nB,KAAKrlB,EACnB,EAEA8W,EAAenE,UAAU0G,KAAO,SAAcrZ,GAC5C,IAAK,IAAInE,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAKyD,GAGpC,OAAO1C,IACT,EAEAwZ,EAAenE,UAAU0S,KAAO,SAAcnpB,GAE5C,GADAA,EAAS2oB,EAAOpN,YAAYvb,GACxBoB,KAAKyL,OAAS7M,EAAO6M,MACvBzL,KAAKuX,UAAY3Y,EAAO2Y,QACxB,MAAM,IAAIb,WAAW,qCAEvB,IAAK,IAAInY,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAKL,EAAOuQ,IAAI5Q,EAAGU,IAGlD,OAAOe,IACT,EAEAwZ,EAAesO,IAAM,SAAalpB,EAAQ8D,GAExC,OADkB,IAAI6kB,EAAO3oB,GACZkpB,IAAIplB,EACvB,EACA8W,EAAenE,UAAU2S,SAAWxO,EAAenE,UAAUyS,IAC7DtO,EAAenE,UAAU4S,UAAYzO,EAAenE,UAAU0G,KAC9DvC,EAAenE,UAAU6S,UAAY1O,EAAenE,UAAU0S,KAC9DvO,EAAewO,SAAWxO,EAAesO,IAEzCtO,EAAenE,UAAU8S,IAAM,SAAazlB,GAC1C,MAAqB,iBAAVA,EAA2B1C,KAAKooB,KAAK1lB,GACzC1C,KAAKqoB,KAAK3lB,EACnB,EAEA8W,EAAenE,UAAU+S,KAAO,SAAc1lB,GAC5C,IAAK,IAAInE,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAKyD,GAGpC,OAAO1C,IACT,EAEAwZ,EAAenE,UAAUgT,KAAO,SAAczpB,GAE5C,GADAA,EAAS2oB,EAAOpN,YAAYvb,GACxBoB,KAAKyL,OAAS7M,EAAO6M,MACvBzL,KAAKuX,UAAY3Y,EAAO2Y,QACxB,MAAM,IAAIb,WAAW,qCAEvB,IAAK,IAAInY,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAKL,EAAOuQ,IAAI5Q,EAAGU,IAGlD,OAAOe,IACT,EAEAwZ,EAAe2O,IAAM,SAAavpB,EAAQ8D,GAExC,OADkB,IAAI6kB,EAAO3oB,GACZupB,IAAIzlB,EACvB,EACA8W,EAAenE,UAAUiT,OAAS9O,EAAenE,UAAU8S,IAC3D3O,EAAenE,UAAUkT,QAAU/O,EAAenE,UAAU+S,KAC5D5O,EAAenE,UAAUmT,QAAUhP,EAAenE,UAAUgT,KAC5D7O,EAAe8O,OAAS9O,EAAe2O,IAEvC3O,EAAenE,UAAUoT,IAAM,SAAa/lB,GAC1C,MAAqB,iBAAVA,EAA2B1C,KAAK0oB,KAAKhmB,GACzC1C,KAAK2oB,KAAKjmB,EACnB,EAEA8W,EAAenE,UAAUqT,KAAO,SAAchmB,GAC5C,IAAK,IAAInE,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAKyD,GAGpC,OAAO1C,IACT,EAEAwZ,EAAenE,UAAUsT,KAAO,SAAc/pB,GAE5C,GADAA,EAAS2oB,EAAOpN,YAAYvb,GACxBoB,KAAKyL,OAAS7M,EAAO6M,MACvBzL,KAAKuX,UAAY3Y,EAAO2Y,QACxB,MAAM,IAAIb,WAAW,qCAEvB,IAAK,IAAInY,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAKL,EAAOuQ,IAAI5Q,EAAGU,IAGlD,OAAOe,IACT,EAEAwZ,EAAeiP,IAAM,SAAa7pB,EAAQ8D,GAExC,OADkB,IAAI6kB,EAAO3oB,GACZ6pB,IAAI/lB,EACvB,EACA8W,EAAenE,UAAUuT,QAAUpP,EAAenE,UAAUoT,IAC5DjP,EAAenE,UAAUwT,SAAWrP,EAAenE,UAAUqT,KAC7DlP,EAAenE,UAAUyT,SAAWtP,EAAenE,UAAUsT,KAC7DnP,EAAeoP,QAAUpP,EAAeiP,IAExCjP,EAAenE,UAAU0T,IAAM,SAAarmB,GAC1C,MAAqB,iBAAVA,EAA2B1C,KAAKgpB,KAAKtmB,GACzC1C,KAAKipB,KAAKvmB,EACnB,EAEA8W,EAAenE,UAAU2T,KAAO,SAActmB,GAC5C,IAAK,IAAInE,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAKyD,GAGpC,OAAO1C,IACT,EAEAwZ,EAAenE,UAAU4T,KAAO,SAAcrqB,GAE5C,GADAA,EAAS2oB,EAAOpN,YAAYvb,GACxBoB,KAAKyL,OAAS7M,EAAO6M,MACvBzL,KAAKuX,UAAY3Y,EAAO2Y,QACxB,MAAM,IAAIb,WAAW,qCAEvB,IAAK,IAAInY,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAKL,EAAOuQ,IAAI5Q,EAAGU,IAGlD,OAAOe,IACT,EAEAwZ,EAAeuP,IAAM,SAAanqB,EAAQ8D,GAExC,OADkB,IAAI6kB,EAAO3oB,GACZmqB,IAAIrmB,EACvB,EAEA8W,EAAenE,UAAU6T,GAAK,SAAYxmB,GACxC,MAAqB,iBAAVA,EAA2B1C,KAAKmpB,IAAIzmB,GACxC1C,KAAKopB,IAAI1mB,EAClB,EAEA8W,EAAenE,UAAU8T,IAAM,SAAazmB,GAC1C,IAAK,IAAInE,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAKyD,GAGpC,OAAO1C,IACT,EAEAwZ,EAAenE,UAAU+T,IAAM,SAAaxqB,GAE1C,GADAA,EAAS2oB,EAAOpN,YAAYvb,GACxBoB,KAAKyL,OAAS7M,EAAO6M,MACvBzL,KAAKuX,UAAY3Y,EAAO2Y,QACxB,MAAM,IAAIb,WAAW,qCAEvB,IAAK,IAAInY,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAKL,EAAOuQ,IAAI5Q,EAAGU,IAGlD,OAAOe,IACT,EAEAwZ,EAAe0P,GAAK,SAAYtqB,EAAQ8D,GAEtC,OADkB,IAAI6kB,EAAO3oB,GACZsqB,GAAGxmB,EACtB,EAEA8W,EAAenE,UAAUgU,IAAM,SAAa3mB,GAC1C,MAAqB,iBAAVA,EAA2B1C,KAAKspB,KAAK5mB,GACzC1C,KAAKupB,KAAK7mB,EACnB,EAEA8W,EAAenE,UAAUiU,KAAO,SAAc5mB,GAC5C,IAAK,IAAInE,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAKyD,GAGpC,OAAO1C,IACT,EAEAwZ,EAAenE,UAAUkU,KAAO,SAAc3qB,GAE5C,GADAA,EAAS2oB,EAAOpN,YAAYvb,GACxBoB,KAAKyL,OAAS7M,EAAO6M,MACvBzL,KAAKuX,UAAY3Y,EAAO2Y,QACxB,MAAM,IAAIb,WAAW,qCAEvB,IAAK,IAAInY,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,GAAKL,EAAOuQ,IAAI5Q,EAAGU,IAGlD,OAAOe,IACT,EAEAwZ,EAAe6P,IAAM,SAAazqB,EAAQ8D,GAExC,OADkB,IAAI6kB,EAAO3oB,GACZyqB,IAAI3mB,EACvB,EAEA8W,EAAenE,UAAUmU,UAAY,SAAmB9mB,GACtD,MAAqB,iBAAVA,EAA2B1C,KAAKypB,WAAW/mB,GAC/C1C,KAAK0pB,WAAWhnB,EACzB,EAEA8W,EAAenE,UAAUoU,WAAa,SAAoB/mB,GACxD,IAAK,IAAInE,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,IAAMyD,GAGrC,OAAO1C,IACT,EAEAwZ,EAAenE,UAAUqU,WAAa,SAAoB9qB,GAExD,GADAA,EAAS2oB,EAAOpN,YAAYvb,GACxBoB,KAAKyL,OAAS7M,EAAO6M,MACvBzL,KAAKuX,UAAY3Y,EAAO2Y,QACxB,MAAM,IAAIb,WAAW,qCAEvB,IAAK,IAAInY,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,IAAML,EAAOuQ,IAAI5Q,EAAGU,IAGnD,OAAOe,IACT,EAEAwZ,EAAegQ,UAAY,SAAmB5qB,EAAQ8D,GAEpD,OADkB,IAAI6kB,EAAO3oB,GACZ4qB,UAAU9mB,EAC7B,EAEA8W,EAAenE,UAAUsU,0BAA4B,SAAmCjnB,GACtF,MAAqB,iBAAVA,EAA2B1C,KAAK4pB,2BAA2BlnB,GAC/D1C,KAAK6pB,2BAA2BnnB,EACzC,EAEA8W,EAAenE,UAAUuU,2BAA6B,SAAoClnB,GACxF,IAAK,IAAInE,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,IAAMyD,GAGrC,OAAO1C,IACT,EAEAwZ,EAAenE,UAAUwU,2BAA6B,SAAoCjrB,GAExF,GADAA,EAAS2oB,EAAOpN,YAAYvb,GACxBoB,KAAKyL,OAAS7M,EAAO6M,MACvBzL,KAAKuX,UAAY3Y,EAAO2Y,QACxB,MAAM,IAAIb,WAAW,qCAEvB,IAAK,IAAInY,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,IAAML,EAAOuQ,IAAI5Q,EAAGU,IAGnD,OAAOe,IACT,EAEAwZ,EAAemQ,0BAA4B,SAAmC/qB,EAAQ8D,GAEpF,OADkB,IAAI6kB,EAAO3oB,GACZ+qB,0BAA0BjnB,EAC7C,EAEA8W,EAAenE,UAAUyU,WAAa,SAAoBpnB,GACxD,MAAqB,iBAAVA,EAA2B1C,KAAK+pB,YAAYrnB,GAChD1C,KAAKgqB,YAAYtnB,EAC1B,EAEA8W,EAAenE,UAAU0U,YAAc,SAAqBrnB,GAC1D,IAAK,IAAInE,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,KAAOyD,GAGtC,OAAO1C,IACT,EAEAwZ,EAAenE,UAAU2U,YAAc,SAAqBprB,GAE1D,GADAA,EAAS2oB,EAAOpN,YAAYvb,GACxBoB,KAAKyL,OAAS7M,EAAO6M,MACvBzL,KAAKuX,UAAY3Y,EAAO2Y,QACxB,MAAM,IAAIb,WAAW,qCAEvB,IAAK,IAAInY,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGe,KAAKmP,IAAI5Q,EAAGU,KAAOL,EAAOuQ,IAAI5Q,EAAGU,IAGpD,OAAOe,IACT,EAEAwZ,EAAesQ,WAAa,SAAoBlrB,EAAQ8D,GAEtD,OADkB,IAAI6kB,EAAO3oB,GACZkrB,WAAWpnB,EAC9B,EACA8W,EAAenE,UAAU4U,mBAAqBzQ,EAAenE,UAAUyU,WACvEtQ,EAAenE,UAAU6U,oBAAsB1Q,EAAenE,UAAU0U,YACxEvQ,EAAenE,UAAU8U,oBAAsB3Q,EAAenE,UAAU2U,YACxExQ,EAAeyQ,mBAAqBzQ,EAAesQ,WAEnDtQ,EAAenE,UAAU+U,IAAM,WAC7B,IAAK,IAAI7rB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,GAAKe,KAAKmP,IAAI5Q,EAAGU,IAGjC,OAAOe,IACT,EAEAwZ,EAAe4Q,IAAM,SAAaxrB,GAEhC,OADkB,IAAI2oB,EAAO3oB,GACZwrB,KACnB,EAEA5Q,EAAenE,UAAU1M,IAAM,WAC7B,IAAK,IAAIpK,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAKkL,IAAI3I,KAAKmP,IAAI5Q,EAAGU,KAGxC,OAAOe,IACT,EAEAwZ,EAAe7Q,IAAM,SAAa/J,GAEhC,OADkB,IAAI2oB,EAAO3oB,GACZ+J,KACnB,EAEA6Q,EAAenE,UAAUgV,KAAO,WAC9B,IAAK,IAAI9rB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAK4sB,KAAKrqB,KAAKmP,IAAI5Q,EAAGU,KAGzC,OAAOe,IACT,EAEAwZ,EAAe6Q,KAAO,SAAczrB,GAElC,OADkB,IAAI2oB,EAAO3oB,GACZyrB,MACnB,EAEA7Q,EAAenE,UAAUiV,MAAQ,WAC/B,IAAK,IAAI/rB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAK6sB,MAAMtqB,KAAKmP,IAAI5Q,EAAGU,KAG1C,OAAOe,IACT,EAEAwZ,EAAe8Q,MAAQ,SAAe1rB,GAEpC,OADkB,IAAI2oB,EAAO3oB,GACZ0rB,OACnB,EAEA9Q,EAAenE,UAAUkV,KAAO,WAC9B,IAAK,IAAIhsB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAK8sB,KAAKvqB,KAAKmP,IAAI5Q,EAAGU,KAGzC,OAAOe,IACT,EAEAwZ,EAAe+Q,KAAO,SAAc3rB,GAElC,OADkB,IAAI2oB,EAAO3oB,GACZ2rB,MACnB,EAEA/Q,EAAenE,UAAUmV,MAAQ,WAC/B,IAAK,IAAIjsB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAK+sB,MAAMxqB,KAAKmP,IAAI5Q,EAAGU,KAG1C,OAAOe,IACT,EAEAwZ,EAAegR,MAAQ,SAAe5rB,GAEpC,OADkB,IAAI2oB,EAAO3oB,GACZ4rB,OACnB,EAEAhR,EAAenE,UAAUoV,KAAO,WAC9B,IAAK,IAAIlsB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAKgtB,KAAKzqB,KAAKmP,IAAI5Q,EAAGU,KAGzC,OAAOe,IACT,EAEAwZ,EAAeiR,KAAO,SAAc7rB,GAElC,OADkB,IAAI2oB,EAAO3oB,GACZ6rB,MACnB,EAEAjR,EAAenE,UAAUqV,MAAQ,WAC/B,IAAK,IAAInsB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAKitB,MAAM1qB,KAAKmP,IAAI5Q,EAAGU,KAG1C,OAAOe,IACT,EAEAwZ,EAAekR,MAAQ,SAAe9rB,GAEpC,OADkB,IAAI2oB,EAAO3oB,GACZ8rB,OACnB,EAEAlR,EAAenE,UAAUsV,KAAO,WAC9B,IAAK,IAAIpsB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAKktB,KAAK3qB,KAAKmP,IAAI5Q,EAAGU,KAGzC,OAAOe,IACT,EAEAwZ,EAAemR,KAAO,SAAc/rB,GAElC,OADkB,IAAI2oB,EAAO3oB,GACZ+rB,MACnB,EAEAnR,EAAenE,UAAU8N,KAAO,WAC9B,IAAK,IAAI5kB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAK0lB,KAAKnjB,KAAKmP,IAAI5Q,EAAGU,KAGzC,OAAOe,IACT,EAEAwZ,EAAe2J,KAAO,SAAcvkB,GAElC,OADkB,IAAI2oB,EAAO3oB,GACZukB,MACnB,EAEA3J,EAAenE,UAAUuV,MAAQ,WAC/B,IAAK,IAAIrsB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAKmtB,MAAM5qB,KAAKmP,IAAI5Q,EAAGU,KAG1C,OAAOe,IACT,EAEAwZ,EAAeoR,MAAQ,SAAehsB,GAEpC,OADkB,IAAI2oB,EAAO3oB,GACZgsB,OACnB,EAEApR,EAAenE,UAAUwV,IAAM,WAC7B,IAAK,IAAItsB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAKotB,IAAI7qB,KAAKmP,IAAI5Q,EAAGU,KAGxC,OAAOe,IACT,EAEAwZ,EAAeqR,IAAM,SAAajsB,GAEhC,OADkB,IAAI2oB,EAAO3oB,GACZisB,KACnB,EAEArR,EAAenE,UAAUyV,KAAO,WAC9B,IAAK,IAAIvsB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAKqtB,KAAK9qB,KAAKmP,IAAI5Q,EAAGU,KAGzC,OAAOe,IACT,EAEAwZ,EAAesR,KAAO,SAAclsB,GAElC,OADkB,IAAI2oB,EAAO3oB,GACZksB,MACnB,EAEAtR,EAAenE,UAAUiD,IAAM,WAC7B,IAAK,IAAI/Z,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAK6a,IAAItY,KAAKmP,IAAI5Q,EAAGU,KAGxC,OAAOe,IACT,EAEAwZ,EAAelB,IAAM,SAAa1Z,GAEhC,OADkB,IAAI2oB,EAAO3oB,GACZ0Z,KACnB,EAEAkB,EAAenE,UAAU0V,MAAQ,WAC/B,IAAK,IAAIxsB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAKstB,MAAM/qB,KAAKmP,IAAI5Q,EAAGU,KAG1C,OAAOe,IACT,EAEAwZ,EAAeuR,MAAQ,SAAensB,GAEpC,OADkB,IAAI2oB,EAAO3oB,GACZmsB,OACnB,EAEAvR,EAAenE,UAAU1X,MAAQ,WAC/B,IAAK,IAAIY,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAKE,MAAMqC,KAAKmP,IAAI5Q,EAAGU,KAG1C,OAAOe,IACT,EAEAwZ,EAAe7b,MAAQ,SAAeiB,GAEpC,OADkB,IAAI2oB,EAAO3oB,GACZjB,OACnB,EAEA6b,EAAenE,UAAU2V,OAAS,WAChC,IAAK,IAAIzsB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAKutB,OAAOhrB,KAAKmP,IAAI5Q,EAAGU,KAG3C,OAAOe,IACT,EAEAwZ,EAAewR,OAAS,SAAgBpsB,GAEtC,OADkB,IAAI2oB,EAAO3oB,GACZosB,QACnB,EAEAxR,EAAenE,UAAU4V,IAAM,WAC7B,IAAK,IAAI1sB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAKwtB,IAAIjrB,KAAKmP,IAAI5Q,EAAGU,KAGxC,OAAOe,IACT,EAEAwZ,EAAeyR,IAAM,SAAarsB,GAEhC,OADkB,IAAI2oB,EAAO3oB,GACZqsB,KACnB,EAEAzR,EAAenE,UAAU6V,MAAQ,WAC/B,IAAK,IAAI3sB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAKytB,MAAMlrB,KAAKmP,IAAI5Q,EAAGU,KAG1C,OAAOe,IACT,EAEAwZ,EAAe0R,MAAQ,SAAetsB,GAEpC,OADkB,IAAI2oB,EAAO3oB,GACZssB,OACnB,EAEA1R,EAAenE,UAAU8V,MAAQ,WAC/B,IAAK,IAAI5sB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAK0tB,MAAMnrB,KAAKmP,IAAI5Q,EAAGU,KAG1C,OAAOe,IACT,EAEAwZ,EAAe2R,MAAQ,SAAevsB,GAEpC,OADkB,IAAI2oB,EAAO3oB,GACZusB,OACnB,EAEA3R,EAAenE,UAAU+V,KAAO,WAC9B,IAAK,IAAI7sB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAK2tB,KAAKprB,KAAKmP,IAAI5Q,EAAGU,KAGzC,OAAOe,IACT,EAEAwZ,EAAe4R,KAAO,SAAcxsB,GAElC,OADkB,IAAI2oB,EAAO3oB,GACZwsB,MACnB,EAEA5R,EAAenE,UAAU0E,MAAQ,WAC/B,IAAK,IAAIxb,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAKsc,MAAM/Z,KAAKmP,IAAI5Q,EAAGU,KAG1C,OAAOe,IACT,EAEAwZ,EAAeO,MAAQ,SAAenb,GAEpC,OADkB,IAAI2oB,EAAO3oB,GACZmb,OACnB,EAEAP,EAAenE,UAAUgW,KAAO,WAC9B,IAAK,IAAI9sB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAK4tB,KAAKrrB,KAAKmP,IAAI5Q,EAAGU,KAGzC,OAAOe,IACT,EAEAwZ,EAAe6R,KAAO,SAAczsB,GAElC,OADkB,IAAI2oB,EAAO3oB,GACZysB,MACnB,EAEA7R,EAAenE,UAAUiW,IAAM,WAC7B,IAAK,IAAI/sB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAK6tB,IAAItrB,KAAKmP,IAAI5Q,EAAGU,KAGxC,OAAOe,IACT,EAEAwZ,EAAe8R,IAAM,SAAa1sB,GAEhC,OADkB,IAAI2oB,EAAO3oB,GACZ0sB,KACnB,EAEA9R,EAAenE,UAAUkW,KAAO,WAC9B,IAAK,IAAIhtB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAK8tB,KAAKvrB,KAAKmP,IAAI5Q,EAAGU,KAGzC,OAAOe,IACT,EAEAwZ,EAAe+R,KAAO,SAAc3sB,GAElC,OADkB,IAAI2oB,EAAO3oB,GACZ2sB,MACnB,EAEA/R,EAAenE,UAAU/V,KAAO,WAC9B,IAAK,IAAIf,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAK6B,KAAKU,KAAKmP,IAAI5Q,EAAGU,KAGzC,OAAOe,IACT,EAEAwZ,EAAela,KAAO,SAAcV,GAElC,OADkB,IAAI2oB,EAAO3oB,GACZU,MACnB,EAEAka,EAAenE,UAAUmW,IAAM,WAC7B,IAAK,IAAIjtB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAK+tB,IAAIxrB,KAAKmP,IAAI5Q,EAAGU,KAGxC,OAAOe,IACT,EAEAwZ,EAAegS,IAAM,SAAa5sB,GAEhC,OADkB,IAAI2oB,EAAO3oB,GACZ4sB,KACnB,EAEAhS,EAAenE,UAAUoW,KAAO,WAC9B,IAAK,IAAIltB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAKguB,KAAKzrB,KAAKmP,IAAI5Q,EAAGU,KAGzC,OAAOe,IACT,EAEAwZ,EAAeiS,KAAO,SAAc7sB,GAElC,OADkB,IAAI2oB,EAAO3oB,GACZ6sB,MACnB,EAEAjS,EAAenE,UAAUqW,MAAQ,WAC/B,IAAK,IAAIntB,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAKiuB,MAAM1rB,KAAKmP,IAAI5Q,EAAGU,KAG1C,OAAOe,IACT,EAEAwZ,EAAekS,MAAQ,SAAe9sB,GAEpC,OADkB,IAAI2oB,EAAO3oB,GACZ8sB,OACnB,EAEAlS,EAAena,IAAM,SAAaT,EAAQ+sB,GAExC,OADkB,IAAIpE,EAAO3oB,GACZS,IAAIssB,EACvB,EAEAnS,EAAenE,UAAUhW,IAAM,SAAaqD,GAC1C,MAAqB,iBAAVA,EAA2B1C,KAAK4rB,KAAKlpB,GACzC1C,KAAK6rB,KAAKnpB,EACnB,EAEA8W,EAAenE,UAAUuW,KAAO,SAAclpB,GAC5C,IAAK,IAAInE,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAK4B,IAAIW,KAAKmP,IAAI5Q,EAAGU,GAAIyD,IAG5C,OAAO1C,IACT,EAEAwZ,EAAenE,UAAUwW,KAAO,SAAcjtB,GAE5C,GADAA,EAAS2oB,EAAOpN,YAAYvb,GACxBoB,KAAKyL,OAAS7M,EAAO6M,MACvBzL,KAAKuX,UAAY3Y,EAAO2Y,QACxB,MAAM,IAAIb,WAAW,qCAEvB,IAAK,IAAInY,EAAI,EAAGA,EAAIyB,KAAKyL,KAAMlN,IAC7B,IAAK,IAAIU,EAAI,EAAGA,EAAIe,KAAKuX,QAAStY,IAChCe,KAAKuC,IAAIhE,EAAGU,EAAGxB,KAAK4B,IAAIW,KAAKmP,IAAI5Q,EAAGU,GAAIL,EAAOuQ,IAAI5Q,EAAGU,KAG1D,OAAOe,IACT,CACF,CF8zBA8rB,CAAsBtS,GAAgB,IGlnDvB,MAAMuS,WAAwBvS,GAC3C9Z,YAAYyC,GACV2C,QACA9E,KAAKmC,KAAOA,EACZnC,KAAKyL,KAAOtJ,EAAK9D,OACjB2B,KAAKuX,QAAUpV,EAAK,GAAG9D,MACzB,CAEAkE,IAAIiiB,EAAUC,EAAa/hB,GAEzB,OADA1C,KAAKmC,KAAKqiB,GAAUC,GAAe/hB,EAC5B1C,IACT,CAEAmP,IAAIqV,EAAUC,GACZ,OAAOzkB,KAAKmC,KAAKqiB,GAAUC,EAC7B,ECda,MAAMuH,GACnBtsB,YAAYd,GAGV,IAKIL,EAAGU,EAAGoM,EAAGpN,EAAG8gB,EAAGkN,EAAGthB,EAClBuhB,EAAQC,EANRC,GAFJxtB,EAASmtB,GAAgB5R,YAAYvb,IAErByc,QACZ5P,EAAO2gB,EAAG3gB,KACV8L,EAAU6U,EAAG7U,QACb8U,EAAc,IAAIvN,aAAarT,GAC/B6gB,EAAY,EAIhB,IAAK/tB,EAAI,EAAGA,EAAIkN,EAAMlN,IACpB8tB,EAAY9tB,GAAKA,EAKnB,IAFA2tB,EAAS,IAAIpN,aAAarT,GAErBxM,EAAI,EAAGA,EAAIsY,EAAStY,IAAK,CAC5B,IAAKV,EAAI,EAAGA,EAAIkN,EAAMlN,IACpB2tB,EAAO3tB,GAAK6tB,EAAGjd,IAAI5Q,EAAGU,GAGxB,IAAKV,EAAI,EAAGA,EAAIkN,EAAMlN,IAAK,CAGzB,IAFA4tB,EAAO1uB,KAAKwD,IAAI1C,EAAGU,GACnB8f,EAAI,EACC1T,EAAI,EAAGA,EAAI8gB,EAAM9gB,IACpB0T,GAAKqN,EAAGjd,IAAI5Q,EAAG8M,GAAK6gB,EAAO7gB,GAE7B6gB,EAAO3tB,IAAMwgB,EACbqN,EAAG7pB,IAAIhE,EAAGU,EAAGitB,EAAO3tB,GACtB,CAGA,IADAN,EAAIgB,EACCV,EAAIU,EAAI,EAAGV,EAAIkN,EAAMlN,IACpBd,KAAKkL,IAAIujB,EAAO3tB,IAAMd,KAAKkL,IAAIujB,EAAOjuB,MACxCA,EAAIM,GAIR,GAAIN,IAAMgB,EAAG,CACX,IAAKoM,EAAI,EAAGA,EAAIkM,EAASlM,IACvB4gB,EAAIG,EAAGjd,IAAIlR,EAAGoN,GACd+gB,EAAG7pB,IAAItE,EAAGoN,EAAG+gB,EAAGjd,IAAIlQ,EAAGoM,IACvB+gB,EAAG7pB,IAAItD,EAAGoM,EAAG4gB,GAGfthB,EAAI0hB,EAAYpuB,GAChBouB,EAAYpuB,GAAKouB,EAAYptB,GAC7BotB,EAAYptB,GAAK0L,EAEjB2hB,GAAaA,CACf,CAEA,GAAIrtB,EAAIwM,GAAyB,IAAjB2gB,EAAGjd,IAAIlQ,EAAGA,GACxB,IAAKV,EAAIU,EAAI,EAAGV,EAAIkN,EAAMlN,IACxB6tB,EAAG7pB,IAAIhE,EAAGU,EAAGmtB,EAAGjd,IAAI5Q,EAAGU,GAAKmtB,EAAGjd,IAAIlQ,EAAGA,GAG5C,CAEAe,KAAKusB,GAAKH,EACVpsB,KAAKqsB,YAAcA,EACnBrsB,KAAKssB,UAAYA,CACnB,CAEAE,aACE,IAAIrqB,EAAOnC,KAAKusB,GACZ5gB,EAAMxJ,EAAKoV,QACf,IAAK,IAAItY,EAAI,EAAGA,EAAI0M,EAAK1M,IACvB,GAAuB,IAAnBkD,EAAKgN,IAAIlQ,EAAGA,GACd,OAAO,EAGX,OAAO,CACT,CAEAwtB,MAAM/pB,GACJA,EAAQ,GAAOyX,YAAYzX,GAE3B,IAAI0pB,EAAKpsB,KAAKusB,GAGd,GAFWH,EAAG3gB,OAED/I,EAAM+I,KACjB,MAAM,IAAI1N,MAAM,6BAElB,GAAIiC,KAAKwsB,aACP,MAAM,IAAIzuB,MAAM,yBAGlB,IAGIQ,EAAGU,EAAGoM,EAHNK,EAAQhJ,EAAM6U,QACdmV,EAAIhqB,EAAMuhB,aAAajkB,KAAKqsB,YAAa,EAAG3gB,EAAQ,GACpD6L,EAAU6U,EAAG7U,QAGjB,IAAKlM,EAAI,EAAGA,EAAIkM,EAASlM,IACvB,IAAK9M,EAAI8M,EAAI,EAAG9M,EAAIgZ,EAAShZ,IAC3B,IAAKU,EAAI,EAAGA,EAAIyM,EAAOzM,IACrBytB,EAAEnqB,IAAIhE,EAAGU,EAAGytB,EAAEvd,IAAI5Q,EAAGU,GAAKytB,EAAEvd,IAAI9D,EAAGpM,GAAKmtB,EAAGjd,IAAI5Q,EAAG8M,IAIxD,IAAKA,EAAIkM,EAAU,EAAGlM,GAAK,EAAGA,IAAK,CACjC,IAAKpM,EAAI,EAAGA,EAAIyM,EAAOzM,IACrBytB,EAAEnqB,IAAI8I,EAAGpM,EAAGytB,EAAEvd,IAAI9D,EAAGpM,GAAKmtB,EAAGjd,IAAI9D,EAAGA,IAEtC,IAAK9M,EAAI,EAAGA,EAAI8M,EAAG9M,IACjB,IAAKU,EAAI,EAAGA,EAAIyM,EAAOzM,IACrBytB,EAAEnqB,IAAIhE,EAAGU,EAAGytB,EAAEvd,IAAI5Q,EAAGU,GAAKytB,EAAEvd,IAAI9D,EAAGpM,GAAKmtB,EAAGjd,IAAI5Q,EAAG8M,GAGxD,CACA,OAAOqhB,CACT,CAEIC,kBACF,IAAIxqB,EAAOnC,KAAKusB,GAChB,IAAKpqB,EAAK2Y,WACR,MAAM,IAAI/c,MAAM,yBAElB,IAAI4uB,EAAc3sB,KAAKssB,UACnB3gB,EAAMxJ,EAAKoV,QACf,IAAK,IAAItY,EAAI,EAAGA,EAAI0M,EAAK1M,IACvB0tB,GAAexqB,EAAKgN,IAAIlQ,EAAGA,GAE7B,OAAO0tB,CACT,CAEIC,4BACF,IAAIzqB,EAAOnC,KAAKusB,GACZ9gB,EAAOtJ,EAAKsJ,KACZ8L,EAAUpV,EAAKoV,QACfmV,EAAI,IAAI,GAAOjhB,EAAM8L,GACzB,IAAK,IAAIhZ,EAAI,EAAGA,EAAIkN,EAAMlN,IACxB,IAAK,IAAIU,EAAI,EAAGA,EAAIsY,EAAStY,IACvBV,EAAIU,EACNytB,EAAEnqB,IAAIhE,EAAGU,EAAGkD,EAAKgN,IAAI5Q,EAAGU,IACfV,IAAMU,EACfytB,EAAEnqB,IAAIhE,EAAGU,EAAG,GAEZytB,EAAEnqB,IAAIhE,EAAGU,EAAG,GAIlB,OAAOytB,CACT,CAEIG,4BACF,IAAI1qB,EAAOnC,KAAKusB,GACZ9gB,EAAOtJ,EAAKsJ,KACZ8L,EAAUpV,EAAKoV,QACfmV,EAAI,IAAI,GAAOjhB,EAAM8L,GACzB,IAAK,IAAIhZ,EAAI,EAAGA,EAAIkN,EAAMlN,IACxB,IAAK,IAAIU,EAAI,EAAGA,EAAIsY,EAAStY,IACvBV,GAAKU,EACPytB,EAAEnqB,IAAIhE,EAAGU,EAAGkD,EAAKgN,IAAI5Q,EAAGU,IAExBytB,EAAEnqB,IAAIhE,EAAGU,EAAG,GAIlB,OAAOytB,CACT,CAEII,6BACF,OAAOhuB,MAAM6Q,KAAK3P,KAAKqsB,YACzB,ECzKK,SAASU,GAAWxhB,EAAGC,GAC5B,IAAI/G,EAAI,EACR,OAAIhH,KAAKkL,IAAI4C,GAAK9N,KAAKkL,IAAI6C,IACzB/G,EAAI+G,EAAID,EACD9N,KAAKkL,IAAI4C,GAAK9N,KAAK6B,KAAK,EAAImF,EAAIA,IAE/B,IAAN+G,GACF/G,EAAI8G,EAAIC,EACD/N,KAAKkL,IAAI6C,GAAK/N,KAAK6B,KAAK,EAAImF,EAAIA,IAElC,CACT,CCNe,MAAMuoB,GACnBttB,YAAYgD,GAGV,IAIInE,EAAGU,EAAGoM,EAAG0T,EAJTkO,GAFJvqB,EAAQqpB,GAAgB5R,YAAYzX,IAErB2Y,QACXxK,EAAInO,EAAM+I,KACVvG,EAAIxC,EAAM6U,QACV2V,EAAQ,IAAIpO,aAAa5Z,GAG7B,IAAKmG,EAAI,EAAGA,EAAInG,EAAGmG,IAAK,CACtB,IAAI8hB,EAAM,EACV,IAAK5uB,EAAI8M,EAAG9M,EAAIsS,EAAGtS,IACjB4uB,EAAMJ,GAAWI,EAAKF,EAAG9d,IAAI5Q,EAAG8M,IAElC,GAAY,IAAR8hB,EAAW,CAIb,IAHIF,EAAG9d,IAAI9D,EAAGA,GAAK,IACjB8hB,GAAOA,GAEJ5uB,EAAI8M,EAAG9M,EAAIsS,EAAGtS,IACjB0uB,EAAG1qB,IAAIhE,EAAG8M,EAAG4hB,EAAG9d,IAAI5Q,EAAG8M,GAAK8hB,GAG9B,IADAF,EAAG1qB,IAAI8I,EAAGA,EAAG4hB,EAAG9d,IAAI9D,EAAGA,GAAK,GACvBpM,EAAIoM,EAAI,EAAGpM,EAAIiG,EAAGjG,IAAK,CAE1B,IADA8f,EAAI,EACCxgB,EAAI8M,EAAG9M,EAAIsS,EAAGtS,IACjBwgB,GAAKkO,EAAG9d,IAAI5Q,EAAG8M,GAAK4hB,EAAG9d,IAAI5Q,EAAGU,GAGhC,IADA8f,GAAKA,EAAIkO,EAAG9d,IAAI9D,EAAGA,GACd9M,EAAI8M,EAAG9M,EAAIsS,EAAGtS,IACjB0uB,EAAG1qB,IAAIhE,EAAGU,EAAGguB,EAAG9d,IAAI5Q,EAAGU,GAAK8f,EAAIkO,EAAG9d,IAAI5Q,EAAG8M,GAE9C,CACF,CACA6hB,EAAM7hB,IAAM8hB,CACd,CAEAntB,KAAKotB,GAAKH,EACVjtB,KAAKqtB,MAAQH,CACf,CAEAT,MAAM/pB,GACJA,EAAQ,GAAOyX,YAAYzX,GAE3B,IAAIuqB,EAAKjtB,KAAKotB,GACVvc,EAAIoc,EAAGxhB,KAEX,GAAI/I,EAAM+I,OAASoF,EACjB,MAAM,IAAI9S,MAAM,oCAElB,IAAKiC,KAAKstB,aACR,MAAM,IAAIvvB,MAAM,4BAGlB,IAGIQ,EAAGU,EAAGoM,EAAG0T,EAHTrT,EAAQhJ,EAAM6U,QACdmV,EAAIhqB,EAAM2Y,QACVnW,EAAI+nB,EAAG1V,QAGX,IAAKlM,EAAI,EAAGA,EAAInG,EAAGmG,IACjB,IAAKpM,EAAI,EAAGA,EAAIyM,EAAOzM,IAAK,CAE1B,IADA8f,EAAI,EACCxgB,EAAI8M,EAAG9M,EAAIsS,EAAGtS,IACjBwgB,GAAKkO,EAAG9d,IAAI5Q,EAAG8M,GAAKqhB,EAAEvd,IAAI5Q,EAAGU,GAG/B,IADA8f,GAAKA,EAAIkO,EAAG9d,IAAI9D,EAAGA,GACd9M,EAAI8M,EAAG9M,EAAIsS,EAAGtS,IACjBmuB,EAAEnqB,IAAIhE,EAAGU,EAAGytB,EAAEvd,IAAI5Q,EAAGU,GAAK8f,EAAIkO,EAAG9d,IAAI5Q,EAAG8M,GAE5C,CAEF,IAAKA,EAAInG,EAAI,EAAGmG,GAAK,EAAGA,IAAK,CAC3B,IAAKpM,EAAI,EAAGA,EAAIyM,EAAOzM,IACrBytB,EAAEnqB,IAAI8I,EAAGpM,EAAGytB,EAAEvd,IAAI9D,EAAGpM,GAAKe,KAAKqtB,MAAMhiB,IAEvC,IAAK9M,EAAI,EAAGA,EAAI8M,EAAG9M,IACjB,IAAKU,EAAI,EAAGA,EAAIyM,EAAOzM,IACrBytB,EAAEnqB,IAAIhE,EAAGU,EAAGytB,EAAEvd,IAAI5Q,EAAGU,GAAKytB,EAAEvd,IAAI9D,EAAGpM,GAAKguB,EAAG9d,IAAI5Q,EAAG8M,GAGxD,CAEA,OAAOqhB,EAAE9J,UAAU,EAAG1d,EAAI,EAAG,EAAGwG,EAAQ,EAC1C,CAEA4hB,aACE,IAAI/V,EAAUvX,KAAKotB,GAAG7V,QACtB,IAAK,IAAIhZ,EAAI,EAAGA,EAAIgZ,EAAShZ,IAC3B,GAAsB,IAAlByB,KAAKqtB,MAAM9uB,GACb,OAAO,EAGX,OAAO,CACT,CAEIsuB,4BACF,IAGItuB,EAAGU,EAHHguB,EAAKjtB,KAAKotB,GACVloB,EAAI+nB,EAAG1V,QACPmV,EAAI,IAAI,GAAOxnB,EAAGA,GAEtB,IAAK3G,EAAI,EAAGA,EAAI2G,EAAG3G,IACjB,IAAKU,EAAI,EAAGA,EAAIiG,EAAGjG,IACbV,EAAIU,EACNytB,EAAEnqB,IAAIhE,EAAGU,EAAGguB,EAAG9d,IAAI5Q,EAAGU,IACbV,IAAMU,EACfytB,EAAEnqB,IAAIhE,EAAGU,EAAGe,KAAKqtB,MAAM9uB,IAEvBmuB,EAAEnqB,IAAIhE,EAAGU,EAAG,GAIlB,OAAOytB,CACT,CAEIa,uBACF,IAIIhvB,EAAGU,EAAGoM,EAAG0T,EAJTkO,EAAKjtB,KAAKotB,GACV3hB,EAAOwhB,EAAGxhB,KACV8L,EAAU0V,EAAG1V,QACbmV,EAAI,IAAI,GAAOjhB,EAAM8L,GAGzB,IAAKlM,EAAIkM,EAAU,EAAGlM,GAAK,EAAGA,IAAK,CACjC,IAAK9M,EAAI,EAAGA,EAAIkN,EAAMlN,IACpBmuB,EAAEnqB,IAAIhE,EAAG8M,EAAG,GAGd,IADAqhB,EAAEnqB,IAAI8I,EAAGA,EAAG,GACPpM,EAAIoM,EAAGpM,EAAIsY,EAAStY,IACvB,GAAqB,IAAjBguB,EAAG9d,IAAI9D,EAAGA,GAAU,CAEtB,IADA0T,EAAI,EACCxgB,EAAI8M,EAAG9M,EAAIkN,EAAMlN,IACpBwgB,GAAKkO,EAAG9d,IAAI5Q,EAAG8M,GAAKqhB,EAAEvd,IAAI5Q,EAAGU,GAK/B,IAFA8f,GAAKA,EAAIkO,EAAG9d,IAAI9D,EAAGA,GAEd9M,EAAI8M,EAAG9M,EAAIkN,EAAMlN,IACpBmuB,EAAEnqB,IAAIhE,EAAGU,EAAGytB,EAAEvd,IAAI5Q,EAAGU,GAAK8f,EAAIkO,EAAG9d,IAAI5Q,EAAG8M,GAE5C,CAEJ,CACA,OAAOqhB,CACT,EC9Ia,MAAMc,GACnB9tB,YAAYgD,EAAOK,EAAU,CAAC,GAG5B,IAFAL,EAAQqpB,GAAgB5R,YAAYzX,IAE1B6W,UACR,MAAM,IAAIxb,MAAM,4BAGlB,IAAI8S,EAAInO,EAAM+I,KACVvG,EAAIxC,EAAM6U,QAEd,MAAM,2BACJkW,GAA6B,EAAI,4BACjCC,GAA8B,EAAI,cAClCC,GAAgB,GACd5qB,EAEJ,IAIIwI,EAJAqiB,EAAQC,QAAQJ,GAChBK,EAAQD,QAAQH,GAEhBK,GAAU,EAEd,GAAIld,EAAI3L,EACN,GAAKyoB,EAME,CACLpiB,EAAI7I,EAAMkhB,YACV/S,EAAItF,EAAEE,KACNvG,EAAIqG,EAAEgM,QACNwW,GAAU,EACV,IAAIC,EAAMJ,EACVA,EAAQE,EACRA,EAAQE,CACV,MAbEziB,EAAI7I,EAAM2Y,QAEViH,QAAQC,KACN,+FAYJhX,EAAI7I,EAAM2Y,QAGZ,IAAI4S,EAAKxwB,KAAKwD,IAAI4P,EAAG3L,GACjBgpB,EAAKzwB,KAAKwD,IAAI4P,EAAI,EAAG3L,GACrB6Z,EAAI,IAAID,aAAaoP,GACrBC,EAAI,IAAI,GAAOtd,EAAGod,GAClBG,EAAI,IAAI,GAAOlpB,EAAGA,GAElBtC,EAAI,IAAIkc,aAAa5Z,GACrBmpB,EAAO,IAAIvP,aAAajO,GAExByd,EAAK,IAAIxP,aAAaoP,GAC1B,IAAK,IAAI3vB,EAAI,EAAGA,EAAI2vB,EAAI3vB,IAAK+vB,EAAG/vB,GAAKA,EAErC,IAAIgwB,EAAM9wB,KAAKwD,IAAI4P,EAAI,EAAG3L,GACtBspB,EAAM/wB,KAAKyC,IAAI,EAAGzC,KAAKwD,IAAIiE,EAAI,EAAG2L,IAClC4d,EAAMhxB,KAAKyC,IAAIquB,EAAKC,GAExB,IAAK,IAAInjB,EAAI,EAAGA,EAAIojB,EAAKpjB,IAAK,CAC5B,GAAIA,EAAIkjB,EAAK,CACXxP,EAAE1T,GAAK,EACP,IAAK,IAAI9M,EAAI8M,EAAG9M,EAAIsS,EAAGtS,IACrBwgB,EAAE1T,GAAK0hB,GAAWhO,EAAE1T,GAAIE,EAAE4D,IAAI5Q,EAAG8M,IAEnC,GAAa,IAAT0T,EAAE1T,GAAU,CACVE,EAAE4D,IAAI9D,EAAGA,GAAK,IAChB0T,EAAE1T,IAAM0T,EAAE1T,IAEZ,IAAK,IAAI9M,EAAI8M,EAAG9M,EAAIsS,EAAGtS,IACrBgN,EAAEhJ,IAAIhE,EAAG8M,EAAGE,EAAE4D,IAAI5Q,EAAG8M,GAAK0T,EAAE1T,IAE9BE,EAAEhJ,IAAI8I,EAAGA,EAAGE,EAAE4D,IAAI9D,EAAGA,GAAK,EAC5B,CACA0T,EAAE1T,IAAM0T,EAAE1T,EACZ,CAEA,IAAK,IAAIpM,EAAIoM,EAAI,EAAGpM,EAAIiG,EAAGjG,IAAK,CAC9B,GAAIoM,EAAIkjB,GAAgB,IAATxP,EAAE1T,GAAU,CACzB,IAAI4gB,EAAI,EACR,IAAK,IAAI1tB,EAAI8M,EAAG9M,EAAIsS,EAAGtS,IACrB0tB,GAAK1gB,EAAE4D,IAAI5Q,EAAG8M,GAAKE,EAAE4D,IAAI5Q,EAAGU,GAE9BgtB,GAAKA,EAAI1gB,EAAE4D,IAAI9D,EAAGA,GAClB,IAAK,IAAI9M,EAAI8M,EAAG9M,EAAIsS,EAAGtS,IACrBgN,EAAEhJ,IAAIhE,EAAGU,EAAGsM,EAAE4D,IAAI5Q,EAAGU,GAAKgtB,EAAI1gB,EAAE4D,IAAI5Q,EAAG8M,GAE3C,CACAzI,EAAE3D,GAAKsM,EAAE4D,IAAI9D,EAAGpM,EAClB,CAEA,GAAI2uB,GAASviB,EAAIkjB,EACf,IAAK,IAAIhwB,EAAI8M,EAAG9M,EAAIsS,EAAGtS,IACrB4vB,EAAE5rB,IAAIhE,EAAG8M,EAAGE,EAAE4D,IAAI5Q,EAAG8M,IAIzB,GAAIA,EAAImjB,EAAK,CACX5rB,EAAEyI,GAAK,EACP,IAAK,IAAI9M,EAAI8M,EAAI,EAAG9M,EAAI2G,EAAG3G,IACzBqE,EAAEyI,GAAK0hB,GAAWnqB,EAAEyI,GAAIzI,EAAErE,IAE5B,GAAa,IAATqE,EAAEyI,GAAU,CACVzI,EAAEyI,EAAI,GAAK,IACbzI,EAAEyI,GAAK,EAAIzI,EAAEyI,IAEf,IAAK,IAAI9M,EAAI8M,EAAI,EAAG9M,EAAI2G,EAAG3G,IACzBqE,EAAErE,IAAMqE,EAAEyI,GAEZzI,EAAEyI,EAAI,IAAM,CACd,CAEA,GADAzI,EAAEyI,IAAMzI,EAAEyI,GACNA,EAAI,EAAIwF,GAAc,IAATjO,EAAEyI,GAAU,CAC3B,IAAK,IAAI9M,EAAI8M,EAAI,EAAG9M,EAAIsS,EAAGtS,IACzB8vB,EAAK9vB,GAAK,EAEZ,IAAK,IAAIA,EAAI8M,EAAI,EAAG9M,EAAIsS,EAAGtS,IACzB,IAAK,IAAIU,EAAIoM,EAAI,EAAGpM,EAAIiG,EAAGjG,IACzBovB,EAAK9vB,IAAMqE,EAAE3D,GAAKsM,EAAE4D,IAAI5Q,EAAGU,GAG/B,IAAK,IAAIA,EAAIoM,EAAI,EAAGpM,EAAIiG,EAAGjG,IAAK,CAC9B,IAAIgtB,GAAKrpB,EAAE3D,GAAK2D,EAAEyI,EAAI,GACtB,IAAK,IAAI9M,EAAI8M,EAAI,EAAG9M,EAAIsS,EAAGtS,IACzBgN,EAAEhJ,IAAIhE,EAAGU,EAAGsM,EAAE4D,IAAI5Q,EAAGU,GAAKgtB,EAAIoC,EAAK9vB,GAEvC,CACF,CACA,GAAIuvB,EACF,IAAK,IAAIvvB,EAAI8M,EAAI,EAAG9M,EAAI2G,EAAG3G,IACzB6vB,EAAE7rB,IAAIhE,EAAG8M,EAAGzI,EAAErE,GAGpB,CACF,CAEA,IAAIN,EAAIR,KAAKwD,IAAIiE,EAAG2L,EAAI,GAYxB,GAXI0d,EAAMrpB,IACR6Z,EAAEwP,GAAOhjB,EAAE4D,IAAIof,EAAKA,IAElB1d,EAAI5S,IACN8gB,EAAE9gB,EAAI,GAAK,GAETuwB,EAAM,EAAIvwB,IACZ2E,EAAE4rB,GAAOjjB,EAAE4D,IAAIqf,EAAKvwB,EAAI,IAE1B2E,EAAE3E,EAAI,GAAK,EAEP2vB,EAAO,CACT,IAAK,IAAI3uB,EAAIsvB,EAAKtvB,EAAIgvB,EAAIhvB,IAAK,CAC7B,IAAK,IAAIV,EAAI,EAAGA,EAAIsS,EAAGtS,IACrB4vB,EAAE5rB,IAAIhE,EAAGU,EAAG,GAEdkvB,EAAE5rB,IAAItD,EAAGA,EAAG,EACd,CACA,IAAK,IAAIoM,EAAIkjB,EAAM,EAAGljB,GAAK,EAAGA,IAC5B,GAAa,IAAT0T,EAAE1T,GAAU,CACd,IAAK,IAAIpM,EAAIoM,EAAI,EAAGpM,EAAIgvB,EAAIhvB,IAAK,CAC/B,IAAIgtB,EAAI,EACR,IAAK,IAAI1tB,EAAI8M,EAAG9M,EAAIsS,EAAGtS,IACrB0tB,GAAKkC,EAAEhf,IAAI5Q,EAAG8M,GAAK8iB,EAAEhf,IAAI5Q,EAAGU,GAE9BgtB,GAAKA,EAAIkC,EAAEhf,IAAI9D,EAAGA,GAClB,IAAK,IAAI9M,EAAI8M,EAAG9M,EAAIsS,EAAGtS,IACrB4vB,EAAE5rB,IAAIhE,EAAGU,EAAGkvB,EAAEhf,IAAI5Q,EAAGU,GAAKgtB,EAAIkC,EAAEhf,IAAI5Q,EAAG8M,GAE3C,CACA,IAAK,IAAI9M,EAAI8M,EAAG9M,EAAIsS,EAAGtS,IACrB4vB,EAAE5rB,IAAIhE,EAAG8M,GAAI8iB,EAAEhf,IAAI5Q,EAAG8M,IAExB8iB,EAAE5rB,IAAI8I,EAAGA,EAAG,EAAI8iB,EAAEhf,IAAI9D,EAAGA,IACzB,IAAK,IAAI9M,EAAI,EAAGA,EAAI8M,EAAI,EAAG9M,IACzB4vB,EAAE5rB,IAAIhE,EAAG8M,EAAG,EAEhB,KAAO,CACL,IAAK,IAAI9M,EAAI,EAAGA,EAAIsS,EAAGtS,IACrB4vB,EAAE5rB,IAAIhE,EAAG8M,EAAG,GAEd8iB,EAAE5rB,IAAI8I,EAAGA,EAAG,EACd,CAEJ,CAEA,GAAIyiB,EACF,IAAK,IAAIziB,EAAInG,EAAI,EAAGmG,GAAK,EAAGA,IAAK,CAC/B,GAAIA,EAAImjB,GAAgB,IAAT5rB,EAAEyI,GACf,IAAK,IAAIpM,EAAIoM,EAAI,EAAGpM,EAAIiG,EAAGjG,IAAK,CAC9B,IAAIgtB,EAAI,EACR,IAAK,IAAI1tB,EAAI8M,EAAI,EAAG9M,EAAI2G,EAAG3G,IACzB0tB,GAAKmC,EAAEjf,IAAI5Q,EAAG8M,GAAK+iB,EAAEjf,IAAI5Q,EAAGU,GAE9BgtB,GAAKA,EAAImC,EAAEjf,IAAI9D,EAAI,EAAGA,GACtB,IAAK,IAAI9M,EAAI8M,EAAI,EAAG9M,EAAI2G,EAAG3G,IACzB6vB,EAAE7rB,IAAIhE,EAAGU,EAAGmvB,EAAEjf,IAAI5Q,EAAGU,GAAKgtB,EAAImC,EAAEjf,IAAI5Q,EAAG8M,GAE3C,CAEF,IAAK,IAAI9M,EAAI,EAAGA,EAAI2G,EAAG3G,IACrB6vB,EAAE7rB,IAAIhE,EAAG8M,EAAG,GAEd+iB,EAAE7rB,IAAI8I,EAAGA,EAAG,EACd,CAGF,IAAIqjB,EAAKzwB,EAAI,EACT0wB,EAAO,EACPC,EAAMptB,OAAOqtB,QACjB,KAAO5wB,EAAI,GAAG,CACZ,IAAIoN,EAAGyjB,EACP,IAAKzjB,EAAIpN,EAAI,EAAGoN,IAAM,IACT,IAAPA,EADmBA,IAAK,CAI5B,MAAM0jB,EACJvtB,OAAOC,UAAYmtB,EAAMnxB,KAAKkL,IAAIoW,EAAE1T,GAAK5N,KAAKkL,IAAIoW,EAAE1T,EAAI,KAC1D,GAAI5N,KAAKkL,IAAI/F,EAAEyI,KAAO0jB,GAASvtB,OAAOwtB,MAAMpsB,EAAEyI,IAAK,CACjDzI,EAAEyI,GAAK,EACP,KACF,CACF,CACA,GAAIA,IAAMpN,EAAI,EACZ6wB,EAAO,MACF,CACL,IAAIG,EACJ,IAAKA,EAAKhxB,EAAI,EAAGgxB,GAAM5jB,GACjB4jB,IAAO5jB,EADa4jB,IAAM,CAI9B,IAAIhD,GACDgD,IAAOhxB,EAAIR,KAAKkL,IAAI/F,EAAEqsB,IAAO,IAC7BA,IAAO5jB,EAAI,EAAI5N,KAAKkL,IAAI/F,EAAEqsB,EAAK,IAAM,GACxC,GAAIxxB,KAAKkL,IAAIoW,EAAEkQ,KAAQL,EAAM3C,EAAG,CAC9BlN,EAAEkQ,GAAM,EACR,KACF,CACF,CACIA,IAAO5jB,EACTyjB,EAAO,EACEG,IAAOhxB,EAAI,EACpB6wB,EAAO,GAEPA,EAAO,EACPzjB,EAAI4jB,EAER,CAIA,OAFA5jB,IAEQyjB,GACN,KAAK,EAAG,CACN,IAAII,EAAItsB,EAAE3E,EAAI,GACd2E,EAAE3E,EAAI,GAAK,EACX,IAAK,IAAIgB,EAAIhB,EAAI,EAAGgB,GAAKoM,EAAGpM,IAAK,CAC/B,IAAIgtB,EAAIc,GAAWhO,EAAE9f,GAAIiwB,GACrBC,EAAKpQ,EAAE9f,GAAKgtB,EACZmD,EAAKF,EAAIjD,EAMb,GALAlN,EAAE9f,GAAKgtB,EACHhtB,IAAMoM,IACR6jB,GAAKE,EAAKxsB,EAAE3D,EAAI,GAChB2D,EAAE3D,EAAI,GAAKkwB,EAAKvsB,EAAE3D,EAAI,IAEpB6uB,EACF,IAAK,IAAIvvB,EAAI,EAAGA,EAAI2G,EAAG3G,IACrB0tB,EAAIkD,EAAKf,EAAEjf,IAAI5Q,EAAGU,GAAKmwB,EAAKhB,EAAEjf,IAAI5Q,EAAGN,EAAI,GACzCmwB,EAAE7rB,IAAIhE,EAAGN,EAAI,GAAImxB,EAAKhB,EAAEjf,IAAI5Q,EAAGU,GAAKkwB,EAAKf,EAAEjf,IAAI5Q,EAAGN,EAAI,IACtDmwB,EAAE7rB,IAAIhE,EAAGU,EAAGgtB,EAGlB,CACA,KACF,CACA,KAAK,EAAG,CACN,IAAIiD,EAAItsB,EAAEyI,EAAI,GACdzI,EAAEyI,EAAI,GAAK,EACX,IAAK,IAAIpM,EAAIoM,EAAGpM,EAAIhB,EAAGgB,IAAK,CAC1B,IAAIgtB,EAAIc,GAAWhO,EAAE9f,GAAIiwB,GACrBC,EAAKpQ,EAAE9f,GAAKgtB,EACZmD,EAAKF,EAAIjD,EAIb,GAHAlN,EAAE9f,GAAKgtB,EACPiD,GAAKE,EAAKxsB,EAAE3D,GACZ2D,EAAE3D,GAAKkwB,EAAKvsB,EAAE3D,GACV2uB,EACF,IAAK,IAAIrvB,EAAI,EAAGA,EAAIsS,EAAGtS,IACrB0tB,EAAIkD,EAAKhB,EAAEhf,IAAI5Q,EAAGU,GAAKmwB,EAAKjB,EAAEhf,IAAI5Q,EAAG8M,EAAI,GACzC8iB,EAAE5rB,IAAIhE,EAAG8M,EAAI,GAAI+jB,EAAKjB,EAAEhf,IAAI5Q,EAAGU,GAAKkwB,EAAKhB,EAAEhf,IAAI5Q,EAAG8M,EAAI,IACtD8iB,EAAE5rB,IAAIhE,EAAGU,EAAGgtB,EAGlB,CACA,KACF,CACA,KAAK,EAAG,CACN,MAAMttB,EAAQlB,KAAKyC,IACjBzC,KAAKkL,IAAIoW,EAAE9gB,EAAI,IACfR,KAAKkL,IAAIoW,EAAE9gB,EAAI,IACfR,KAAKkL,IAAI/F,EAAE3E,EAAI,IACfR,KAAKkL,IAAIoW,EAAE1T,IACX5N,KAAKkL,IAAI/F,EAAEyI,KAEPgkB,EAAKtQ,EAAE9gB,EAAI,GAAKU,EAChB2wB,EAAOvQ,EAAE9gB,EAAI,GAAKU,EAClB4wB,EAAO3sB,EAAE3E,EAAI,GAAKU,EAClB6wB,EAAKzQ,EAAE1T,GAAK1M,EACZ8wB,EAAK7sB,EAAEyI,GAAK1M,EACZ6M,IAAM8jB,EAAOD,IAAOC,EAAOD,GAAME,EAAOA,GAAQ,EAChDnN,EAAIiN,EAAKE,GAAQF,EAAKE,GAC5B,IAAIG,EAAQ,EACF,IAANlkB,GAAiB,IAAN4W,IAEXsN,EADElkB,EAAI,EACE,EAAI/N,KAAK6B,KAAKkM,EAAIA,EAAI4W,GAEtB3kB,KAAK6B,KAAKkM,EAAIA,EAAI4W,GAE5BsN,EAAQtN,GAAK5W,EAAIkkB,IAEnB,IAAIR,GAAKM,EAAKH,IAAOG,EAAKH,GAAMK,EAC5BC,EAAIH,EAAKC,EACb,IAAK,IAAIxwB,EAAIoM,EAAGpM,EAAIhB,EAAI,EAAGgB,IAAK,CAC9B,IAAIgtB,EAAIc,GAAWmC,EAAGS,GACZ,IAAN1D,IAASA,EAAIzqB,OAAOC,WACxB,IAAI0tB,EAAKD,EAAIjD,EACTmD,EAAKO,EAAI1D,EAQb,GAPIhtB,IAAMoM,IACRzI,EAAE3D,EAAI,GAAKgtB,GAEbiD,EAAIC,EAAKpQ,EAAE9f,GAAKmwB,EAAKxsB,EAAE3D,GACvB2D,EAAE3D,GAAKkwB,EAAKvsB,EAAE3D,GAAKmwB,EAAKrQ,EAAE9f,GAC1B0wB,EAAIP,EAAKrQ,EAAE9f,EAAI,GACf8f,EAAE9f,EAAI,GAAKkwB,EAAKpQ,EAAE9f,EAAI,GAClB6uB,EACF,IAAK,IAAIvvB,EAAI,EAAGA,EAAI2G,EAAG3G,IACrB0tB,EAAIkD,EAAKf,EAAEjf,IAAI5Q,EAAGU,GAAKmwB,EAAKhB,EAAEjf,IAAI5Q,EAAGU,EAAI,GACzCmvB,EAAE7rB,IAAIhE,EAAGU,EAAI,GAAImwB,EAAKhB,EAAEjf,IAAI5Q,EAAGU,GAAKkwB,EAAKf,EAAEjf,IAAI5Q,EAAGU,EAAI,IACtDmvB,EAAE7rB,IAAIhE,EAAGU,EAAGgtB,GAYhB,GATAA,EAAIc,GAAWmC,EAAGS,GACR,IAAN1D,IAASA,EAAIzqB,OAAOC,WACxB0tB,EAAKD,EAAIjD,EACTmD,EAAKO,EAAI1D,EACTlN,EAAE9f,GAAKgtB,EACPiD,EAAIC,EAAKvsB,EAAE3D,GAAKmwB,EAAKrQ,EAAE9f,EAAI,GAC3B8f,EAAE9f,EAAI,IAAMmwB,EAAKxsB,EAAE3D,GAAKkwB,EAAKpQ,EAAE9f,EAAI,GACnC0wB,EAAIP,EAAKxsB,EAAE3D,EAAI,GACf2D,EAAE3D,EAAI,GAAKkwB,EAAKvsB,EAAE3D,EAAI,GAClB2uB,GAAS3uB,EAAI4R,EAAI,EACnB,IAAK,IAAItS,EAAI,EAAGA,EAAIsS,EAAGtS,IACrB0tB,EAAIkD,EAAKhB,EAAEhf,IAAI5Q,EAAGU,GAAKmwB,EAAKjB,EAAEhf,IAAI5Q,EAAGU,EAAI,GACzCkvB,EAAE5rB,IAAIhE,EAAGU,EAAI,GAAImwB,EAAKjB,EAAEhf,IAAI5Q,EAAGU,GAAKkwB,EAAKhB,EAAEhf,IAAI5Q,EAAGU,EAAI,IACtDkvB,EAAE5rB,IAAIhE,EAAGU,EAAGgtB,EAGlB,CACArpB,EAAE3E,EAAI,GAAKixB,EACXP,GAAc,EACd,KACF,CACA,KAAK,EACH,GAAI5P,EAAE1T,IAAM,IACV0T,EAAE1T,GAAK0T,EAAE1T,GAAK,GAAK0T,EAAE1T,GAAK,EACtByiB,GACF,IAAK,IAAIvvB,EAAI,EAAGA,GAAKmwB,EAAInwB,IACvB6vB,EAAE7rB,IAAIhE,EAAG8M,GAAI+iB,EAAEjf,IAAI5Q,EAAG8M,IAI5B,KAAOA,EAAIqjB,KACL3P,EAAE1T,IAAM0T,EAAE1T,EAAI,KADL,CAIb,IAAI4gB,EAAIlN,EAAE1T,GAGV,GAFA0T,EAAE1T,GAAK0T,EAAE1T,EAAI,GACb0T,EAAE1T,EAAI,GAAK4gB,EACP6B,GAASziB,EAAInG,EAAI,EACnB,IAAK,IAAI3G,EAAI,EAAGA,EAAI2G,EAAG3G,IACrB0tB,EAAImC,EAAEjf,IAAI5Q,EAAG8M,EAAI,GACjB+iB,EAAE7rB,IAAIhE,EAAG8M,EAAI,EAAG+iB,EAAEjf,IAAI5Q,EAAG8M,IACzB+iB,EAAE7rB,IAAIhE,EAAG8M,EAAG4gB,GAGhB,GAAI2B,GAASviB,EAAIwF,EAAI,EACnB,IAAK,IAAItS,EAAI,EAAGA,EAAIsS,EAAGtS,IACrB0tB,EAAIkC,EAAEhf,IAAI5Q,EAAG8M,EAAI,GACjB8iB,EAAE5rB,IAAIhE,EAAG8M,EAAI,EAAG8iB,EAAEhf,IAAI5Q,EAAG8M,IACzB8iB,EAAE5rB,IAAIhE,EAAG8M,EAAG4gB,GAGhB5gB,GACF,CACAsjB,EAAO,EACP1wB,IAKN,CAEA,GAAI8vB,EAAS,CACX,IAAItS,EAAM2S,EACVA,EAAID,EACJA,EAAI1S,CACN,CAEAzb,KAAK6Q,EAAIA,EACT7Q,KAAKkF,EAAIA,EACTlF,KAAK+e,EAAIA,EACT/e,KAAKmuB,EAAIA,EACTnuB,KAAKouB,EAAIA,CACX,CAEA3B,MAAM/pB,GACJ,IAAIktB,EAAIltB,EACJE,EAAI5C,KAAK6vB,UACTC,EAAQ9vB,KAAK+e,EAAE1gB,OACf0xB,EAAK,GAAOnlB,MAAMklB,EAAOA,GAE7B,IAAK,IAAIvxB,EAAI,EAAGA,EAAIuxB,EAAOvxB,IACrBd,KAAKkL,IAAI3I,KAAK+e,EAAExgB,KAAOqE,EACzBmtB,EAAGxtB,IAAIhE,EAAGA,EAAG,GAEbwxB,EAAGxtB,IAAIhE,EAAGA,EAAG,EAAIyB,KAAK+e,EAAExgB,IAI5B,IAAI4vB,EAAInuB,KAAKmuB,EACTC,EAAIpuB,KAAKgwB,qBAETC,EAAK7B,EAAEzP,KAAKoR,GACZG,EAAQ9B,EAAE3iB,KACV0kB,EAAQhC,EAAE1iB,KACV2kB,EAAM,GAAOxlB,MAAMslB,EAAOC,GAE9B,IAAK,IAAI5xB,EAAI,EAAGA,EAAI2xB,EAAO3xB,IACzB,IAAK,IAAIU,EAAI,EAAGA,EAAIkxB,EAAOlxB,IAAK,CAC9B,IAAI8L,EAAM,EACV,IAAK,IAAIM,EAAI,EAAGA,EAAIykB,EAAOzkB,IACzBN,GAAOklB,EAAG9gB,IAAI5Q,EAAG8M,GAAK8iB,EAAEhf,IAAIlQ,EAAGoM,GAEjC+kB,EAAI7tB,IAAIhE,EAAGU,EAAG8L,EAChB,CAGF,OAAOqlB,EAAIzR,KAAKiR,EAClB,CAEAS,iBAAiB3tB,GACf,OAAO1C,KAAKysB,MAAM,GAAOpO,KAAK3b,GAChC,CAEA4tB,UACE,IAAIlC,EAAIpuB,KAAKouB,EACTxrB,EAAI5C,KAAK6vB,UACTK,EAAQ9B,EAAE3iB,KACV8kB,EAAQnC,EAAE7W,QACVmV,EAAI,IAAI,GAAOwD,EAAOlwB,KAAK+e,EAAE1gB,QAEjC,IAAK,IAAIE,EAAI,EAAGA,EAAI2xB,EAAO3xB,IACzB,IAAK,IAAIU,EAAI,EAAGA,EAAIsxB,EAAOtxB,IACrBxB,KAAKkL,IAAI3I,KAAK+e,EAAE9f,IAAM2D,GACxB8pB,EAAEnqB,IAAIhE,EAAGU,EAAGmvB,EAAEjf,IAAI5Q,EAAGU,GAAKe,KAAK+e,EAAE9f,IAKvC,IAAIkvB,EAAInuB,KAAKmuB,EAETgC,EAAQhC,EAAE1iB,KACV+kB,EAAQrC,EAAE5W,QACVqY,EAAI,IAAI,GAAOM,EAAOC,GAE1B,IAAK,IAAI5xB,EAAI,EAAGA,EAAI2xB,EAAO3xB,IACzB,IAAK,IAAIU,EAAI,EAAGA,EAAIkxB,EAAOlxB,IAAK,CAC9B,IAAI8L,EAAM,EACV,IAAK,IAAIM,EAAI,EAAGA,EAAImlB,EAAOnlB,IACzBN,GAAO2hB,EAAEvd,IAAI5Q,EAAG8M,GAAK8iB,EAAEhf,IAAIlQ,EAAGoM,GAEhCukB,EAAErtB,IAAIhE,EAAGU,EAAG8L,EACd,CAGF,OAAO6kB,CACT,CAEI/xB,gBACF,OAAOmC,KAAK+e,EAAE,GAAK/e,KAAK+e,EAAEthB,KAAKwD,IAAIjB,KAAK6Q,EAAG7Q,KAAKkF,GAAK,EACvD,CAEIurB,YACF,OAAOzwB,KAAK+e,EAAE,EAChB,CAEI2R,WACF,IAAIC,EAAMlzB,KAAKyC,IAAIF,KAAK6Q,EAAG7Q,KAAKkF,GAAKlF,KAAK+e,EAAE,GAAKvd,OAAOqtB,QACpDpqB,EAAI,EACJsa,EAAI/e,KAAK+e,EACb,IAAK,IAAIxgB,EAAI,EAAGqyB,EAAK7R,EAAE1gB,OAAQE,EAAIqyB,EAAIryB,IACjCwgB,EAAExgB,GAAKoyB,GACTlsB,IAGJ,OAAOA,CACT,CAEIiiB,eACF,OAAO5nB,MAAM6Q,KAAK3P,KAAK+e,EACzB,CAEI8Q,gBACF,OAAQruB,OAAOqtB,QAAU,EAAKpxB,KAAKyC,IAAIF,KAAK6Q,EAAG7Q,KAAKkF,GAAKlF,KAAK+e,EAAE,EAClE,CAEI8R,0BACF,OAAO7wB,KAAKmuB,CACd,CAEI6B,2BACF,OAAOhwB,KAAKouB,CACd,CAEI0C,qBACF,OAAO,GAAOzS,KAAKre,KAAK+e,EAC1B,EC3ca,SAASza,GACtBnC,EACA4uB,EACAC,EACAC,EACArb,GAEA,IAAIlT,EAAQsuB,EAAUC,EAAqBA,EACvCtK,EAAW,GAAOjD,IAAIqN,EAAO1yB,OAAQ0yB,EAAO1yB,OAAQqE,GAExD,MAAMmT,EAAOD,EAAsBmb,GAEnC,IAAIG,EAAgB,IAAIpS,aAAa3c,EAAKwD,EAAEtH,QAC5C,IAAK,IAAIE,EAAI,EAAGA,EAAI4D,EAAKwD,EAAEtH,OAAQE,IACjC2yB,EAAc3yB,GAAKsX,EAAK1T,EAAKwD,EAAEpH,IAGjC,IAAI4yB,EAvEN,SACEhvB,EACA+uB,EACAH,EACAE,EACAG,GAEA,MAAMlsB,EAAI6rB,EAAO1yB,OACXwS,EAAI1O,EAAKwD,EAAEtH,OAEjB,IAAIgzB,EAAM,IAAIvyB,MAAMoG,GAEpB,IAAK,IAAIosB,EAAQ,EAAGA,EAAQpsB,EAAGosB,IAAS,CACtCD,EAAIC,GAAS,IAAIxyB,MAAM+R,GACvB,IAAI0gB,EAAYR,EAAOvY,QACvB+Y,EAAUD,IAAUL,EACpB,IAAIO,EAAYJ,EAAcG,GAE9B,IAAK,IAAIrc,EAAQ,EAAGA,EAAQrE,EAAGqE,IAC7Bmc,EAAIC,GAAOpc,GAASgc,EAAchc,GAASsc,EAAUrvB,EAAKwD,EAAEuP,GAEhE,CACA,OAAO,IAAI,GAAOmc,EACpB,CAgDqBI,CACjBtvB,EACA+uB,EACAH,EACAE,EACArb,GAEE8b,EA9CN,SAAwBvvB,EAAM+uB,GAC5B,MAAMrgB,EAAI1O,EAAKwD,EAAEtH,OAEjB,IAAIgzB,EAAM,IAAIvyB,MAAM+R,GAEpB,IAAK,IAAIqE,EAAQ,EAAGA,EAAQrE,EAAGqE,IAC7Bmc,EAAInc,GAAS,CAAC/S,EAAKyD,EAAEsP,GAASgc,EAAchc,IAG9C,OAAO,IAAI,GAAOmc,EACpB,CAoCmBM,CAAexvB,EAAM+uB,GAClCU,ECrFC,SAAiBhzB,EAAQizB,GAAS,GAEvC,OADAjzB,EAASmtB,GAAgB5R,YAAYvb,GACjCizB,EACK,IAAIrE,GAA2B5uB,GAAQ0xB,UAM3C,SAAewB,EAAcC,EAAeF,GAAS,GAG1D,OAFAC,EAAe/F,GAAgB5R,YAAY2X,GAC3CC,EAAgBhG,GAAgB5R,YAAY4X,GACxCF,EACK,IAAIrE,GAA2BsE,GAAcrF,MAAMsF,GAEnDD,EAAahX,WAChB,IAAIkR,GAAgB8F,GAAcrF,MAAMsF,GACxC,IAAI/E,GAAgB8E,GAAcrF,MAAMsF,EAEhD,CAdWtF,CAAM7tB,EAAQ,GAAO8kB,IAAI9kB,EAAO6M,MAE3C,CD8EsB6kB,CAClB3J,EAASnW,IAAI2gB,EAAaxS,KAAKwS,EAAavN,eAY9C,OARAmN,GADAA,EAAS,IAAI,GAAO,CAACA,KACLlO,IACd+O,EACGjT,KAAKwS,GACLxS,KAAK+S,GACL5J,IAAImJ,GACJrN,cAGS9K,WAChB,CE3CA,MAAMkZ,GAAqB,KACrBC,GAAmB,KAqBlB,MAAMC,GACLC,gBACA,OAAOnyB,KAAKiN,UAChB,CACAvN,YAAYqxB,EAAS,CAAC,GAClB/wB,KAAKoyB,aAAe,EACpBpyB,KAAKqyB,kBAAoB,EACzBryB,KAAKuO,QAAU,GACfvO,KAAKsyB,YAAc,EACnBtyB,KAAKuyB,QAAU,EACfvyB,KAAKiN,WAAa,GAClBjN,KAAKwyB,mBAAqB,EAC1BxyB,KAAKtC,OAASD,KAAKC,OACnBsC,KAAKyyB,kBAAoB,EACzBzyB,KAAK0yB,cAAgB,EACrB1yB,KAAK2yB,OAAS,EACd3yB,KAAK4yB,mBAAqB,EAE1B5yB,KAAK6yB,aAAe,cACpB7yB,KAAK8yB,aAAe,GACpB9yB,KAAK+yB,iBAAmB/yB,KAAKiN,WAC7BjN,KAAKgzB,WAAaC,GAClBjzB,KAAKkzB,eAAgB,EACrBlzB,KAAKmzB,SAAW,GAEhBnzB,KAAKozB,UAAY,GACjBpzB,KAAKqzB,kBAAoB,IAAIC,GAC7B,MAAMC,EAAYhqB,SAEMiB,IAAhBumB,EAAOxnB,KACPvJ,KAAKuJ,GAAOwnB,EAAOxnB,GAAI,EAE/BgqB,EAAS,cACTA,EAAS,gBACTA,EAAS,qBACTA,EAAS,WACTA,EAAS,eACTA,EAAS,WACTA,EAAS,cACTA,EAAS,sBACTA,EAAS,UACTA,EAAS,qBACTA,EAAS,iBACTA,EAAS,UACTA,EAAS,qBACb,CAIAC,IAAI9G,GAGA,OAFA1sB,KAAKyzB,cAAc/G,GACnB1sB,KAAK0zB,iBACE1zB,KAAKozB,SAChB,CAKA7yB,eAAemsB,EAAGnS,EAAW,MAAM,IAG/B,OAFAva,KAAKyzB,cAAc/G,SACb1sB,KAAK2zB,oBAAoBpZ,GACxBva,KAAKozB,SAChB,CAIAQ,wBAAwBhE,EAAGmB,EAAS,CAAC,GACjC/wB,KAAK4vB,EAAIA,EACT5vB,KAAK6yB,aAAe9B,EAAO8B,cAAgB7yB,KAAK6yB,aAChD7yB,KAAK8yB,aAAe/B,EAAO+B,cAAgB9yB,KAAK8yB,aAChD9yB,KAAK+yB,iBAAmBhC,EAAOgC,kBAAoB/yB,KAAK+yB,gBAC5D,CAIAc,kBAAkBC,EAAYC,GAC1B/zB,KAAK8zB,WAAaA,EAClB9zB,KAAK+zB,aAAeA,CACxB,CAOAN,cAAc/G,GACV,GAAIA,EAAEruB,QAAU2B,KAAKiN,WACjB,MAAM,IAAIlP,MAAM,2BAA2B2uB,EAAEruB,iCAAiC2B,KAAKiN,kEAGvF,GAAIjN,KAAK0sB,IAAMA,GAAK1sB,KAAKkzB,cACrB,OAAOlzB,KAAKg0B,aAGhB,GADAh0B,KAAK0sB,EAAIA,GACJ1sB,KAAK8zB,aAAe9zB,KAAK+zB,aAAc,CACxC,MAAME,EAAaj0B,KAAKk0B,iBAAiBxH,GACzC1sB,KAAK8zB,WAAaG,EAAWH,WAC7B9zB,KAAK+zB,aAAeE,EAAWF,YACnC,CACA/zB,KAAKm0B,MAAQn0B,KAAKo0B,mBAAmB1H,EAAG1sB,KAAKiN,WAAYjN,KAAK0yB,eAE9D1yB,KAAKq0B,gBACLr0B,KAAKs0B,YAAct0B,KAAKu0B,gBAAgB7H,GAExC1sB,KAAKw0B,sCACL,MAAM,KAAEC,EAAI,KAAEC,EAAI,gBAAEC,GAAqB30B,KAAK40B,mCAS9C,OAPA50B,KAAKqzB,kBAAkBoB,KAAOA,EAC9Bz0B,KAAKqzB,kBAAkBqB,KAAOA,EAC9B10B,KAAKqzB,kBAAkBsB,gBAAkBA,EAEzC30B,KAAK60B,yBACL70B,KAAK80B,6BACL90B,KAAKkzB,eAAgB,EACdlzB,KAAKg0B,YAChB,CACAK,gBACI,MAAM,aAAEU,EAAY,eAAEC,IC/EMhC,ED+E2ChzB,KAAKgzB,WCrDzE,CAAEgC,eAzBT,SAAwB/nB,EAAY9K,EAAM8yB,EAAaC,EAAOx3B,GAC1D,IAAK,IAAIa,EAAI,EAAGA,EAAI02B,EAAY52B,OAAQE,IAAK,CACzC,MAAM+N,EAAU,EAAsBW,EAAY9K,EAAK9D,OAAQX,GAC/D,IAAK,IAAIuB,EAAI,EAAGA,EAAIqN,EAAQjO,OAAQY,IAC5BqN,EAAQrN,GAAK,GAIjB,EAAci2B,EAAO32B,EADXy0B,EAAW7wB,EAAKmK,EAAQrN,IAAKg2B,EAAY12B,IACxB+N,EAAQrN,GAAI,EAE/C,CACJ,EAcyB81B,aAbzB,SAAsBI,EAAOhzB,EAAM8yB,EAAaC,EAAOx3B,GACnD,IAAK,IAAIa,EAAI,EAAGA,EAAI02B,EAAY52B,OAAQE,IAAK,CACzC,MAAM+N,EAAU,GAAoB2oB,EAAY12B,GAAI42B,EAAOz3B,GAC3D,IAAK,IAAIuB,EAAI,EAAGA,EAAIqN,EAAQjO,OAAQY,IAAK,CACrC,GAAIqN,EAAQrN,GAAK,EACb,OAGJ,EAAci2B,EAAO32B,EADXy0B,EAAW7wB,EAAKmK,EAAQrN,IAAKg2B,EAAY12B,IACxB+N,EAAQrN,GAAI,EAC3C,CACJ,CAEJ,IAzBG,IAA6B+zB,EDgF5BhzB,KAAK+0B,aAAeA,EACpB/0B,KAAKg1B,eAAiBA,EACtBh1B,KAAKo1B,OCtDN,SAAiCpC,GACpC,OAAO,SAAoB7wB,EAAMgyB,EAAOkB,EAAgBJ,GACpD,MAAM,QAAE3oB,EAAO,OAAEiG,GAAW,GAAc4hB,GAC1C,IAAK,IAAI51B,EAAI,EAAGA,EAAI02B,EAAY52B,OAAQE,IAAK,CACzC,MAAM+2B,EAAQ,IAAIvkB,IAAIskB,EAAe,GAAG92B,IACxC,OAAa,CAET,MAAMg3B,EAAS,EAAqBF,EAAgB92B,GACpD,IAAgB,IAAZg3B,EACA,MAEJ,MAAMC,EAAalpB,EAAQkM,MAAMjG,EAAOgjB,GAAShjB,EAAOgjB,EAAS,IACjE,IAAK,MAAME,KAAaD,EAChBC,IAAcF,IACC,IAAfE,GACAH,EAAMpmB,IAAIumB,KAId,EAAuBJ,EAAgB92B,EAD7By0B,EAAW7wB,EAAKszB,GAAYR,EAAY12B,IACLk3B,EAAW,GACxDH,EAAM9kB,IAAIilB,GAElB,CACJ,CACA,OAAOJ,CACX,CACJ,CD4BsB,CAAkCr1B,KAAKgzB,WACzD,CACAuB,gBAAgB7H,GACZ,MAAMoH,EAAa9zB,KAAK8zB,WAClBC,EAAe/zB,KAAK+zB,aACpBplB,EAAO,CAAC+d,EAAEruB,OAAQquB,EAAEruB,QACpBi2B,EAAc,IAAI,GAAoB,GAAI,GAAI,GAAI3lB,GACxD,IAAK,IAAIpQ,EAAI,EAAGA,EAAIu1B,EAAWz1B,OAAQE,IAAK,CACxC,MAAMm3B,EAAM5B,EAAWv1B,GACjBo3B,EAAY5B,EAAax1B,GAC/B,IAAK,IAAIU,EAAI,EAAGA,EAAIy2B,EAAIr3B,OAAQY,IAAK,CACjC,MAAM22B,EAAWF,EAAIz2B,GACfwE,EAAWkyB,EAAU12B,GACvBwE,EAAW,GACX6wB,EAAY/xB,IAAIhE,EAAGq3B,EAAUnyB,EAErC,CACJ,CAEA,OvB9CG8M,GuB8CmB+jB,EADJ,GAAiBA,IvB7Cd,CAAC3uB,EAAGC,IAAOD,EAAIC,EAAID,EAAIC,GuB+ChD,CAIAiwB,UAAUC,GAEN,MAAMC,EAAU/1B,KAAK0sB,EACrB,QAAgBliB,IAAZurB,GAA4C,IAAnBA,EAAQ13B,OACjC,MAAM,IAAIN,MAAM,yBAEpB,IAAIkP,EAAaxP,KAAKE,MAAMqC,KAAKiN,WAAajN,KAAK4yB,oBACnD3lB,EAAaxP,KAAKwD,IAAI80B,EAAQ13B,OAAQ4O,GACtC,MAAM+oB,EC3DP,SAA0B7iB,EAAQhR,EAAM8yB,EAAahoB,EAAY+nB,EAAgBD,EAAcr3B,GAClG,MAAMu4B,EAAU,EAAchB,EAAY52B,OAAQ4O,GAElD,GADA+nB,EAAe/nB,EAAY9K,EAAM8yB,EAAagB,EAASv4B,GACnDyV,EACA,IAAK,IAAIC,KAAQD,EACb4hB,EAAa3hB,EAAMjR,EAAM8yB,EAAagB,EAASv4B,GAGvD,OAAOu4B,CACX,CDkDqB,CAA2Bj2B,KAAKmzB,SAAU4C,EAASD,EAAa7oB,EAAYjN,KAAKg1B,eAAgBh1B,KAAK+0B,aAAc/0B,KAAKtC,QAChIyB,EAASa,KAAKo1B,OAAOW,EAAS/1B,KAAKs0B,YAAa0B,EAAMF,GAC5D,IAAI,QAAExpB,EAASC,QAASopB,GAAc,EAAgBx2B,GACtDmN,EAAUA,EAAQvN,KAAI4G,GAAKA,EAAE6S,MAAM,EAAGxY,KAAKiN,cAC3C0oB,EAAYA,EAAU52B,KAAI4G,GAAKA,EAAE6S,MAAM,EAAGxY,KAAKiN,cAC/C,MAAMipB,EAA4Bz4B,KAAKyC,IAAI,EAAGF,KAAKqyB,kBAAoB,IACjE,OAAE8D,EAAM,KAAEC,GAASp2B,KAAKq2B,kBAAkBV,EAAW31B,KAAKiN,WAAYipB,IACtE,KAAEzqB,EAAI,KAAEiD,EAAI,KAAEqB,GAAS/P,KAAKs2B,2BAA2BhqB,EAASqpB,EAAWQ,EAAQC,GACnF52B,EAAO,CAACs2B,EAAYz3B,OAAQ03B,EAAQ13B,QAC1C,IAAI81B,EAAQ,IAAI,GAAoB1oB,EAAMiD,EAAMqB,EAAMvQ,GAItD,MACM+2B,EAAY,GADH,GAAiBpC,EAAO,OAEjCtoB,EAAUiqB,EAAYz3B,OAGtB+0B,EAmnBP,SAAuB9mB,EAASC,EAAS6mB,GAC5C,MAAMj0B,EAAS,EACJmN,EAAQjO,QACdU,KAAIy3B,GAAK,EAAYpD,EAAU,GAAG/0B,UACvC,IAAK,IAAIE,EAAI,EAAGA,EAAI+N,EAAQjO,OAAQE,IAChC,IAAK,IAAIU,EAAI,EAAGA,EAAIqN,EAAQ,GAAGjO,OAAQY,IACnC,IAAK,IAAIyF,EAAI,EAAGA,EAAI0uB,EAAU,GAAG/0B,OAAQqG,IAAK,CAC1C,MAAM6G,EAAIe,EAAQ/N,GAAGU,GACrBE,EAAOZ,GAAGmG,IAAM6H,EAAQhO,GAAGU,GAAKm0B,EAAU7nB,GAAG7G,EACjD,CAGR,OAAOvF,CACX,CAhoB0Bs3B,CAFD,EAAgBF,EAAUjqB,QAAST,EAAS7L,KAAKiN,YACjD,EAAgBspB,EAAU/1B,OAAQqL,EAAS7L,KAAKiN,YACbjN,KAAKozB,WACnDb,EAAUvyB,KAAKuyB,QACfvyB,KAAKuyB,QAAU,EACf4B,EAAMrlB,OAAS,IACX,IACA,GACJ4nB,EAAWvC,EACZtkB,YACAxG,QAAO,CAACnJ,EAAKsJ,IAASA,EAAMtJ,EAAMsJ,EAAMtJ,GAAM,GACnDi0B,EAAQA,EAAMp1B,KAAI2D,GAAUA,EAAQg0B,EAAWnE,EAAU,EAAI7vB,IAC7DyxB,EAAQ,GAAsBA,GAC9B,MAAMQ,EAAkB30B,KAAK22B,oBAAoBxC,EAAMtkB,YAAa0iB,GAC9DkC,EAAON,EAAMzkB,UACbglB,EAAOP,EAAMvkB,UAanB,OAXA5P,KAAK42B,kCAAkC,CACnCC,cAAezD,EACf0D,cAAe92B,KAAKozB,UACpBqB,OACAC,OACAqC,aAAc,EACdxE,UACAvlB,UAAWmnB,EAAM1kB,UAAU,GAC3BklB,oBAEJ30B,KAAK80B,6BACE90B,KAAK0zB,gBAChB,CAKAc,sCACI,MAAM,EAAE5E,EAAC,EAAElD,GAAM1sB,KACjB,GAAI4vB,EAAG,CACH,GAAIA,EAAEvxB,SAAWquB,EAAEruB,OACf,MAAM,IAAIN,MAAM,mCAEpB,GAA0B,gBAAtBiC,KAAK6yB,aAA+D,CACpE,MACMmE,EADKh3B,KAAK8yB,aAAe,EACH,GAAO,EAAM9yB,KAAK8yB,cAAzB,IAA0C,KAC/D9yB,KAAKm0B,MAAQn0B,KAAKi3B,qCAAqCj3B,KAAKm0B,MAAOvE,EAAGoH,EAC1E,CAEJ,CACJ,CAIA1yB,OACI,MAAM,aAAEyyB,GAAiB/2B,KAAKqzB,kBAI9B,OAHI0D,EAAe/2B,KAAKg0B,cACpBh0B,KAAKk3B,mBAAmBH,GAErB/2B,KAAKqzB,kBAAkB0D,YAClC,CAIAI,eACI,OAAOn3B,KAAKozB,SAChB,CAMAc,iBAAiBxH,GACb,MAAM,WAAEsG,EAAU,WAAE/lB,GAAejN,KAE7Bo3B,ECrQP,SAAuBpE,EAAYt1B,GACtC,OAAO,SAAmByE,EAAMk1B,EAAWpqB,EAAYqqB,EAAS,GAAIpqB,EAAgB,GAAIqqB,EAAQ,KAAOC,EAAM,GAAKC,GAAa,GAC3H,MAAMzqB,EAAY7K,EAAK9D,OACjB0O,EAAe,EAAc5K,EAAK9D,OAAQ4O,GAChD,IAAK,IAAI1O,EAAI,EAAGA,EAAI4D,EAAK9D,OAAQE,IAAK,CAClC,MAAM+N,EAAU,EAAqBW,EAAY9K,EAAK9D,OAAQX,GAC9D,IAAK,IAAIuB,EAAI,EAAGA,EAAIqN,EAAQjO,OAAQY,IAAK,CACrC,MAAMyF,EAAIsuB,EAAW7wB,EAAK5D,GAAI4D,EAAKmK,EAAQrN,KAC3C,EAAc8N,EAAcxO,EAAGmG,EAAG4H,EAAQrN,GAAI,GAC9C,EAAc8N,EAAcT,EAAQrN,GAAIyF,EAAGnG,EAAG,EAClD,CACJ,CACA,GAAIk5B,EACA,IAAK,IAAIvyB,EAAI,EAAGA,EAAImyB,EAAUh5B,OAAQ6G,IAClC,IAAK,IAAI3G,EAAI,EAAGA,EAAI84B,EAAUnyB,GAAG7G,UACzBg5B,EAAUnyB,GAAG3G,GAAK,GADeA,IAIrC,IAAK,IAAIU,EAAIV,EAAI,EAAGU,EAAIo4B,EAAUnyB,GAAG7G,UAC7Bg5B,EAAUnyB,GAAGjG,GAAK,GADmBA,IAAK,CAI9C,MAAMyF,EAAIsuB,EAAW7wB,EAAKk1B,EAAUnyB,GAAG3G,IAAK4D,EAAKk1B,EAAUnyB,GAAGjG,KAC9D,EAAc8N,EAAcsqB,EAAUnyB,GAAG3G,GAAImG,EAAG2yB,EAAUnyB,GAAGjG,GAAI,GACjE,EAAc8N,EAAcsqB,EAAUnyB,GAAGjG,GAAIyF,EAAG2yB,EAAUnyB,GAAG3G,GAAI,EACrE,CAIZ,IAAK,IAAI2G,EAAI,EAAGA,EAAIoyB,EAAQpyB,IAAK,CAC7B,MAAMiI,EAAqB,EAAqBJ,EAAcC,EAAWC,EAAYC,EAAexP,GACpG,IAAI0kB,EAAI,EACR,IAAK,IAAI7jB,EAAI,EAAGA,EAAIyO,EAAWzO,IAC3B,IAAK,IAAIU,EAAI,EAAGA,EAAIiO,EAAejO,IAAK,CACpC,IAAIhB,EAAIR,KAAKE,MAAMwP,EAAmB,GAAG5O,GAAGU,IAC5C,KAAIhB,EAAI,GAAK,EAAcP,GAAU85B,GAGrC,IAAK,IAAInsB,EAAI,EAAGA,EAAI6B,EAAe7B,IAAK,CACpC,MAAMnN,EAAIT,KAAKE,MAAMwP,EAAmB,GAAG5O,GAAG8M,IACxCqsB,EAAKvqB,EAAmB,GAAG5O,GAAGU,GAC9B04B,EAAKxqB,EAAmB,GAAG5O,GAAG8M,GACpC,GAAInN,EAAI,IAAOw5B,IAAOC,EAClB,SAEJ,MAAMjzB,EAAIsuB,EAAW7wB,EAAKlE,GAAIkE,EAAKjE,IACnCkkB,GAAK,EAAcrV,EAAc9O,EAAGyG,EAAGxG,EAAG,GAC1CkkB,GAAK,EAAcrV,EAAc7O,EAAGwG,EAAGzG,EAAG,EAC9C,CACJ,CAEJ,GAAImkB,GAAKmV,EAAQtqB,EAAa9K,EAAK9D,OAC/B,KAER,CAEA,OADe,EAAgB0O,EAEnC,CACJ,CD2MgC,CAAwBimB,EAAYhzB,KAAKtC,QAK3DoV,EAAS,EAAIrV,KAAKE,MAFP,KADFuH,EAGqBwnB,EAAEruB,QAAU,GAAM,IAF/B,EAAIZ,KAAKsc,MAAM7U,IADxB,IAACA,EAIf,MAAMoyB,EAAS75B,KAAKyC,IAAI,EAAGzC,KAAKE,MAAMF,KAAKsc,MAP9B,CAAC7U,GAAMzH,KAAKwtB,IAAI/lB,GAAKzH,KAAKwtB,IAAI,GAOMG,CAAKsB,EAAEruB,WACxD2B,KAAKmzB,SAAW,GAAgBzG,EAAGzf,EAAY6F,EAAQ9S,KAAKtC,QAC5D,MAAM25B,EtBjGP,SAAuBlE,GAC1B,GAAIA,EAAS90B,OAAS,EAAG,CACrB,MAAMiM,EAAS,GACf,IAAK,IAAI8I,KAAQ+f,EACb7oB,EAAOC,QAAQ6I,EAAK9G,SAExB,OAAOhC,CACX,CAEI,MAAO,CAAC,EAAE,GAElB,CsBsF0B,CAAmBtK,KAAKmzB,WACpC,QAAE7mB,EAAO,QAAEC,GAAY6qB,EAAgB1K,EAAG2K,EAAWpqB,EAAYqqB,GACvE,MAAO,CAAExD,WAAYxnB,EAASynB,aAAcxnB,EAChD,CASA6nB,mBAAmB1H,EAAGzf,EAAYylB,EAAgB,GAC9C,MAAM,WAAEoB,EAAa,GAAE,aAAEC,EAAe,GAAE,kBAAE1B,GAAsBryB,MAC5D,OAAEm2B,EAAM,KAAEC,GAASp2B,KAAKq2B,kBAAkBtC,EAAc9mB,EAAYolB,IACpE,KAAE5mB,EAAI,KAAEiD,EAAI,KAAEqB,GAAS/P,KAAKs2B,2BAA2BxC,EAAYC,EAAcoC,EAAQC,GACzF52B,EAAO,CAACktB,EAAEruB,OAAQquB,EAAEruB,QACpBu5B,EAAe,IAAI,GAAoBnsB,EAAMiD,EAAMqB,EAAMvQ,GACzDokB,EAAY,GAAiBgU,GAC7BC,EAAa,GAAwBD,EAAchU,GACnDrY,EAAI,GAAgB,GAAWqsB,EAAchU,GAAYiU,GAI/D,OADe,GAFL,GAAsBtsB,EAAGmnB,GACzB,GAAsBmF,EAAY,EAAMnF,GAGtD,CAOAuE,qCAAqCa,EAAeC,EAAQf,EAASgB,EAAc,GAC/E,IAAIC,EAqeL,SAA0B9D,EAAO4D,EAAQC,EAAc,EAAKhB,EAAU,GACzE,OAAO7C,EAAMp1B,KAAI,CAAC2D,EAAOyJ,EAAKR,KACL,IAAjBosB,EAAO5rB,KAAgC,IAAjB4rB,EAAOpsB,GACtBjJ,EAAQjF,KAAK6a,KAAK0f,GAEpBD,EAAO5rB,KAAS4rB,EAAOpsB,GACrBjJ,EAAQjF,KAAK6a,KAAK0e,GAGlBt0B,GAGnB,CAjf2Bw1B,CAAiBJ,EAAeC,EAAQC,EAAahB,GAExE,OADAiB,EAAe,GAAsBA,GAuftC,SAAgCH,GAEnC,MAAMlU,EAAY,GADlBkU,EAAgB,GAAiBA,EAAe,QAIhD,OAAO,GADPA,EAAgB,GAAWA,EAAe,GAAgBlU,EADvC,GAAwBA,EAAWkU,KAG1D,CA5feK,CAAuBF,EAClC,CAQA5B,kBAAkBV,EAAWtqB,EAAGgnB,EAAoB,EAAK+F,EAAQ,GAAIC,EAAY,GAC7E,MAAMN,EAAUt6B,KAAKwtB,IAAI5f,GAAK5N,KAAKwtB,IAAI,GAAMoN,EACvCb,EAAM,EAAY7B,EAAUt3B,QAC5Bc,EAAS,EAAYw2B,EAAUt3B,QACrC,IAAK,IAAIE,EAAI,EAAGA,EAAIo3B,EAAUt3B,OAAQE,IAAK,CACvC,IAAI+5B,EAAK,EACLC,EAAKtsB,IACLusB,EAAM,EAEV,MAAMC,EAAe9C,EAAUp3B,GACzBm6B,EAAeD,EAAavnB,QAAOxM,GAAKA,EAAI,IAClD,GAAIg0B,EAAar6B,QAAUg0B,EAAmB,CAC1C,IAAI1vB,EAAQlF,KAAKE,MAAM00B,GACnBsG,EAAgBtG,EAAoB1vB,EACpCA,EAAQ,GACR60B,EAAIj5B,GAAKm6B,EAAa/1B,EAAQ,GAC1Bg2B,EAAgB3G,KAChBwF,EAAIj5B,IACAo6B,GAAiBD,EAAa/1B,GAAS+1B,EAAa/1B,EAAQ,MAIpE60B,EAAIj5B,GAAKo6B,EAAgBD,EAAa,EAE9C,MACSA,EAAar6B,OAAS,IAC3Bm5B,EAAIj5B,GAAK,EAAUm6B,IAEvB,IAAK,IAAIxzB,EAAI,EAAGA,EAAIkzB,EAAOlzB,IAAK,CAC5B,IAAI0zB,EAAO,EACX,IAAK,IAAI35B,EAAI,EAAGA,EAAI02B,EAAUp3B,GAAGF,OAAQY,IAAK,CAC1C,MAAMyF,EAAIixB,EAAUp3B,GAAGU,GAAKu4B,EAAIj5B,GAE5Bq6B,GADAl0B,EAAI,EACIjH,KAAK6a,KAAM5T,EAAI8zB,GAGf,CAEhB,CACA,GAAI/6B,KAAKkL,IAAIiwB,EAAOb,GAAU/F,GAC1B,MAEA4G,EAAOb,GACPQ,EAAKC,EACLA,GAAOF,EAAKC,GAAM,IAGlBD,EAAKE,EACDD,IAAOtsB,IACPusB,GAAO,EAGPA,GAAOF,EAAKC,GAAM,EAG9B,CAGA,GAFAp5B,EAAOZ,GAAKi6B,EAERhB,EAAIj5B,GAAK,EAAK,CACd,MAAMs6B,EAAmB,EAAWJ,GAChCt5B,EAAOZ,GAAK0zB,GAAmB4G,IAC/B15B,EAAOZ,GAAK0zB,GAAmB4G,EAEvC,KACK,CACD,MAAMC,EAAgB,EAAWnD,EAAU52B,IAAI,IAC3CI,EAAOZ,GAAK0zB,GAAmB6G,IAC/B35B,EAAOZ,GAAK0zB,GAAmB6G,EAEvC,CACJ,CACA,MAAO,CAAE3C,OAAQh3B,EAAQi3B,KAAMoB,EACnC,CAOAlB,2BAA2BxC,EAAYC,EAAcoC,EAAQC,GACzD,MAAMnrB,EAAW6oB,EAAWz1B,OACtB4O,EAAa6mB,EAAW,GAAGz1B,OAC3BoN,EAAO,EAAYR,EAAWgC,GAC9ByB,EAAO,EAAYzD,EAAWgC,GAC9B8C,EAAO,EAAY9E,EAAWgC,GACpC,IAAK,IAAI1O,EAAI,EAAGA,EAAI0M,EAAU1M,IAC1B,IAAK,IAAIU,EAAI,EAAGA,EAAIgO,EAAYhO,IAAK,CACjC,IAAIuK,EAAM,GACgB,IAAtBsqB,EAAWv1B,GAAGU,KAIduK,EADAsqB,EAAWv1B,GAAGU,KAAOV,EACf,EAEDw1B,EAAax1B,GAAGU,GAAKm3B,EAAK73B,IAAM,EAC/B,EAGAd,KAAK6a,MAAOyb,EAAax1B,GAAGU,GAAKm3B,EAAK73B,IAAM43B,EAAO53B,IAE7DkN,EAAKlN,EAAI0O,EAAahO,GAAKV,EAC3BmQ,EAAKnQ,EAAI0O,EAAahO,GAAK60B,EAAWv1B,GAAGU,GACzC8Q,EAAKxR,EAAI0O,EAAahO,GAAKuK,EAC/B,CAEJ,MAAO,CAAEiC,OAAMiD,OAAMqB,OACzB,CAOA6kB,mCACI,MAAMrC,EAAUvyB,KAAKg0B,cACf,YAAE1B,GAAgBtyB,KAClB+4B,EAAc/4B,KAAKm0B,MAAMtkB,YAC/B,IAAI6mB,EAAW,EACf,IAAK,IAAIn4B,EAAI,EAAGA,EAAIw6B,EAAY16B,OAAQE,IAAK,CACzC,MAAMmE,EAAQq2B,EAAYx6B,GACtBm4B,EAAWqC,EAAYx6B,KACvBm4B,EAAWh0B,EAEnB,CACA,MAAMyxB,EAAQn0B,KAAKm0B,MAAMp1B,KAAI2D,GACrBA,EAAQg0B,EAAWnE,EACZ,EAGA7vB,IAMf1C,KAAKozB,UAAY,EAAYe,EAAMrlB,OAAO/P,KAAI,IACnC,EAAYuzB,GAAavzB,KAAI,IACI,GAA7B,EAAciB,KAAKtC,QAAgB,OAIlD,MAAM6O,EAAU,GACVkoB,EAAO,GACPC,EAAO,GACPnlB,EAAe4kB,EAAM9kB,SAC3B,IAAK,IAAI9Q,EAAI,EAAGA,EAAIgR,EAAalR,OAAQE,IAAK,CAC1C,MAAMy6B,EAAQzpB,EAAahR,GACvBy6B,EAAMt2B,QACN6J,EAAQhC,KAAKyuB,EAAMt2B,OACnBgyB,EAAKnqB,KAAKyuB,EAAM7sB,KAChBsoB,EAAKlqB,KAAKyuB,EAAMrtB,KAExB,CAEA,MAAO,CAAE8oB,OAAMC,OAAMC,gBADG30B,KAAK22B,oBAAoBpqB,EAASgmB,GAE9D,CAKAoE,oBAAoBpqB,EAASgmB,GACzB,MAAMpzB,EAAS,EAAaoN,EAAQlO,QAAS,GACvC6B,EAAM,EAAUqM,GAChBtB,EAAWsB,EAAQxN,KAAIk6B,GAAMA,EAAI/4B,EAAOqyB,IAK9C,OAJAtnB,EAASxI,SAAQ,CAACyC,EAAG3G,KACb2G,EAAI,IACJ/F,EAAOZ,GAAKg0B,EAAUtnB,EAAS1M,GAAE,IAElCY,CACX,CAIAy3B,kCAAkCsC,GAC9B/vB,OAAOgwB,OAAOn5B,KAAKqzB,kBAAmB6F,EAC1C,CAKApE,6BAEI,MAAM,kBAAErC,EAAiB,aAAEL,EAAY,mBAAEI,GAAuBxyB,MAC1D,gBAAE20B,EAAe,cAAEkC,EAAa,cAAEC,GAAmB92B,KAAKqzB,kBAC1D+F,EAAMvC,EAAc,GAAGx4B,OACvBg7B,EAAYxC,EAAcx4B,SAAWy4B,EAAcz4B,OACnDi7B,EAA0B3E,EAAgB51B,KAAI6D,GAAKA,EAAI4vB,IACvD+G,EAA4B,IAAID,GAChCE,EAAoB,IAAI7E,GAC9B30B,KAAK42B,kCAAkC,CACnC4C,oBACAD,4BACAD,0BACAD,YACAI,aAAcrH,EACdrD,MAAOqD,EACPsH,MAAOjH,EACP2G,OAER,CAIAvE,yBAEI,MAAMgC,EAAgB72B,KAAKozB,UACrB0D,EAAgB92B,KAAKozB,WAErB,KAAEqB,EAAI,KAAEC,EAAI,gBAAEC,GAAoB30B,KAAKqzB,kBACvCd,EAAUvyB,KAAKg0B,aACfhnB,EAAYhN,KAAKm0B,MAAMplB,OACvB,EAAExD,EAAC,EAAEC,GA0OZ,SAAsBmnB,EAAQpkB,GACjC,MAGMorB,EzB5uBH,SAAgBpuB,EAAGC,EAAGpM,GACzB,OAAOiL,EyB4uBoB,KzB5uBTtL,KAAI,CAAC0L,EAAGlM,IyB4uBd,EzB3uBGA,IAAMiN,EyB2uBT,GzB3uBkB,MAElC,CyBwuBe,CACC,EAAY,EAATmnB,GACV5zB,KAAIyK,GAAQA,EAAM+E,EAAU,EAAM/E,IACjCowB,EAAK,EAAYD,EAAGt7B,QAAQU,KAAI,CAACyK,EAAK7G,IAC5Bg3B,EAAGh3B,IAAU4L,EACZ9Q,KAAK6a,MAAMqhB,EAAGh3B,GAAS4L,GAAWokB,GAAUnpB,IAGvDrH,EAAO,CAAEwD,EAAGg0B,EAAI/zB,EAAGg0B,IASnB,gBAAEC,GEvzBG,SACb13B,EACAyT,EACA7S,EAAU,CAAC,GAEX,IAAI,cACF+2B,EAAgB,IAAG,mBACnB7I,EAAqB,GAAK,QAC1BD,EAAU,EAAC,eACX+I,EAAiB,IAAK,UACtBC,EAAS,UACTC,EAAS,cACTC,GACEn3B,EAEJ,GAAIiuB,GAAW,EACb,MAAM,IAAIjzB,MAAM,gDACX,IAAKoE,EAAKwD,IAAMxD,EAAKyD,EAC1B,MAAM,IAAI7H,MAAM,iDACX,IACJ,GAAQoE,EAAKwD,IACdxD,EAAKwD,EAAEtH,OAAS,IACf,GAAQ8D,EAAKyD,IACdzD,EAAKyD,EAAEvH,OAAS,EAEhB,MAAM,IAAIN,MACR,wEAEG,GAAIoE,EAAKwD,EAAEtH,SAAW8D,EAAKyD,EAAEvH,OAClC,MAAM,IAAIN,MAAM,uDAGlB,IAAI4X,EACFukB,GAAiB,IAAIp7B,MAAM8W,EAAsBvX,QAAQQ,KAAK,GAC5Ds7B,EAASxkB,EAAWtX,OAIxB,GAHA47B,EAAYA,GAAa,IAAIn7B,MAAMq7B,GAAQt7B,KAAK2C,OAAO44B,kBACvDJ,EAAYA,GAAa,IAAIl7B,MAAMq7B,GAAQt7B,KAAK2C,OAAO64B,kBAEnDJ,EAAU57B,SAAW27B,EAAU37B,OACjC,MAAM,IAAIN,MAAM,iDAGlB,IAAK,GAAQ4X,GACX,MAAM,IAAI5X,MAAM,kCAGlB,IAIIu8B,EAJAl4B,EAAQsT,GAAiBvT,EAAMwT,EAAYC,GAE3C2kB,EAAYn4B,GAAS23B,EAGzB,IAAKO,EAAY,EAAGA,EAAYR,IAAkBS,EAAWD,IAAa,CACxE3kB,EAAarR,GACXnC,EACAwT,EACAqb,EACAC,EACArb,GAGF,IAAK,IAAIvK,EAAI,EAAGA,EAAI8uB,EAAQ9uB,IAC1BsK,EAAWtK,GAAK5N,KAAKwD,IACnBxD,KAAKyC,IAAI85B,EAAU3uB,GAAIsK,EAAWtK,IAClC4uB,EAAU5uB,IAKd,GADAjJ,EAAQsT,GAAiBvT,EAAMwT,EAAYC,GACvCoZ,MAAM5sB,GAAQ,MAClBm4B,EAAYn4B,GAAS23B,CACvB,CAEA,MAAO,CACLF,gBAAiBlkB,EACjB6kB,eAAgBp4B,EAChBq4B,WAAYH,EAEhB,CF0uBgC,CAAGn4B,GApBjB,EAAEoJ,EAAGC,KAAQ7F,GAChB,GAAO,EAAM4F,EAAI5F,IAAM,EAAI6F,KAYtB,CACZwlB,QAAS,IACTkJ,cALkB,CAAC,GAAK,IAMxBjJ,mBAAoB,GACpB6I,cAAe,IACfC,eAAgB,OAGbxuB,EAAGC,GAAKquB,EACf,MAAO,CAAEtuB,IAAGC,IAChB,CAlQyBkvB,CAAa16B,KAAK2yB,OAAQ3yB,KAAKuO,SAChDvO,KAAK42B,kCAAkC,CACnCC,gBACAC,gBACArC,OACAC,OACAC,kBACAppB,IACAC,IACA+mB,UACAvlB,aAER,CAQAkqB,mBAAmBhyB,GACf,MAAM,kBAAEmuB,GAAsBrzB,MACxB,KAAEy0B,EAAI,KAAEC,EAAI,cAAEmC,EAAa,cAAEC,EAAa,gBAAEnC,EAAe,kBAAE6E,EAAiB,0BAAED,EAAyB,wBAAED,EAAuB,UAAED,EAAS,aAAEI,EAAY,MAAE1K,EAAK,MAAE2K,EAAK,EAAEnuB,EAAC,EAAEC,EAAC,IAAE4tB,EAAG,QAAE7G,EAAO,UAAEvlB,GAAeqmB,EAEpN,IAAK,IAAI90B,EAAI,EAAGA,EAAIo2B,EAAgBt2B,OAAQE,IAAK,CAC7C,GAAIi7B,EAAkBj7B,GAAK2G,EACvB,SAEJ,MAAMjG,EAAIw1B,EAAKl2B,GACT8M,EAAIqpB,EAAKn2B,GACTo8B,EAAU9D,EAAc53B,GACxB2f,EAAQkY,EAAczrB,GACtBuvB,EAAcC,GAAMF,EAAS/b,GACnC,IAAIkc,EAAY,EACZF,EAAc,IACdE,GAAa,EAAMvvB,EAAIC,EAAI/N,KAAK4B,IAAIu7B,EAAapvB,EAAI,GACrDsvB,GAAavvB,EAAI9N,KAAK4B,IAAIu7B,EAAapvB,GAAK,GAEhD,IAAK,IAAI9G,EAAI,EAAGA,EAAI00B,EAAK10B,IAAK,CAC1B,MAAMq2B,EAAQC,GAAKF,GAAaH,EAAQj2B,GAAKka,EAAMla,IAhBzC,GAiBVi2B,EAAQj2B,IAAMq2B,EAAQhM,EAClBsK,IACAza,EAAMla,KAAOq2B,EAAQhM,EAE7B,CACAyK,EAAkBj7B,IAAMo2B,EAAgBp2B,GACxC,MAAM08B,EAAcx9B,KAAKE,OAAOuH,EAAIq0B,EAA0Bh7B,IAAM+6B,EAAwB/6B,IAC5F,IAAK,IAAIN,EAAI,EAAGA,EAAIg9B,EAAah9B,IAAK,CAClC,MAAMoN,EAAI,EAAiB2B,EAAWhN,KAAKtC,QACrCkhB,EAAQkY,EAAczrB,GACtBuvB,EAAcC,GAAMF,EAAS/b,GACnC,IAAIkc,EAAY,EAChB,GAAIF,EAAc,EACdE,EAAY,EAAMpB,EAAQluB,EAC1BsvB,IACK,KAAQF,IAAgBrvB,EAAI9N,KAAK4B,IAAIu7B,EAAapvB,GAAK,QAE3D,GAAIvM,IAAMoM,EACX,SAEJ,IAAK,IAAI3G,EAAI,EAAGA,EAAI00B,EAAK10B,IAAK,CAC1B,IAAIq2B,EAAQ,EACRD,EAAY,IACZC,EAAQC,GAAKF,GAAaH,EAAQj2B,GAAKka,EAAMla,IAxC3C,IA0CNi2B,EAAQj2B,IAAMq2B,EAAQhM,CAC1B,CACJ,CACAwK,EAA0Bh7B,IAAM08B,EAAc3B,EAAwB/6B,EAC1E,CAGA,OAFA80B,EAAkBtE,MAAQ0K,GAAgB,EAAMv0B,EAAIqtB,GACpDc,EAAkB0D,cAAgB,EAC3BF,CACX,CAQAlD,oBAAoBuH,EAAgB,MAAM,IACtC,OAAO,IAAIt6B,SAAQ,CAACC,EAASC,KACzB,MAAMwD,EAAO/D,UACT,IACI,MAAM,QAAEgyB,EAAO,aAAEwE,GAAiB/2B,KAAKqzB,kBACvCrzB,KAAKozB,UAAYpzB,KAAKk3B,mBAAmBH,GACzC,MAAMoE,EAAiBn7B,KAAKqzB,kBAAkB0D,aACxCqE,GAA+C,IAAlCF,EAAcC,GAC3BE,EAAaF,IAAmB5I,EACtC,GAAK6I,GAAeC,EAIhB,OAAOx6B,EAAQw6B,GAHfC,YAAW,IAAMh3B,KAAQ,EAKjC,CACA,MAAOi3B,GACHz6B,EAAOy6B,EACX,GAEJD,YAAW,IAAMh3B,KAAQ,EAAE,GAEnC,CAQAovB,eAAewH,EAAgB,MAAM,IACjC,IAAIG,GAAa,EACbjI,EAAY,GAChB,MAAQiI,GAAY,CAChB,MAAM,QAAE9I,EAAO,aAAEwE,GAAiB/2B,KAAKqzB,kBACvCD,EAAYpzB,KAAKk3B,mBAAmBH,GACpC,MAAMoE,EAAiBn7B,KAAKqzB,kBAAkB0D,aACxCqE,GAA+C,IAAlCF,EAAcC,GACjCE,EAAaF,IAAmB5I,GAAW6I,CAC/C,CACA,OAAOhI,CACX,CAKAY,aACI,MAAMG,EAAQn0B,KAAKm0B,MACnB,GAAIn0B,KAAKuyB,QAAU,EACf,OAAOvyB,KAAKuyB,QAEhB,IAAK4B,EACD,OAAO,IAEX,MAAM91B,EAAS81B,EAAMrlB,MACrB,OAAIzQ,GAAU,KACH,IAEFA,GAAU,IACR,IAEFA,GAAU,KACR,IAGA,GAEf,EASG,SAAS40B,GAAQttB,EAAGC,GAEvB,OADenI,KAAKkL,IAAIhD,EAAIC,EAEhC,CAwBA,MAAM0tB,GACF5zB,cACIM,KAAK+2B,aAAe,EAEpB/2B,KAAK62B,cAAgB,GACrB72B,KAAK82B,cAAgB,GACrB92B,KAAKy0B,KAAO,GACZz0B,KAAK00B,KAAO,GACZ10B,KAAK20B,gBAAkB,GACvB30B,KAAKw5B,kBAAoB,GACzBx5B,KAAKu5B,0BAA4B,GACjCv5B,KAAKs5B,wBAA0B,GAC/Bt5B,KAAKq5B,WAAY,EACjBr5B,KAAKy5B,aAAe,EACpBz5B,KAAK+uB,MAAQ,EACb/uB,KAAK05B,MAAQ,EACb15B,KAAKuL,EAAI,mBACTvL,KAAKwL,EAAI,kBACTxL,KAAKo5B,IAAM,EACXp5B,KAAKuyB,QAAU,IACfvyB,KAAKgN,UAAY,CACrB,EAKJ,SAASguB,GAAKr1B,EAAG61B,GACb,OAAI71B,EAAI61B,EACGA,EACF71B,GAAK61B,GACFA,EAED71B,CACf,CAIA,SAASk1B,GAAMl1B,EAAGC,GACd,IAAIzG,EAAS,EACb,IAAK,IAAIZ,EAAI,EAAGA,EAAIoH,EAAEtH,OAAQE,IAC1BY,GAAU1B,KAAK4B,IAAIsG,EAAEpH,GAAKqH,EAAErH,GAAI,GAEpC,OAAOY,CACX,CG9yBO,MAAMs8B,GAAS91B,GAAMA,QACrB,SAAS+1B,GAAcC,EAAaC,EAAS7jB,EAAKpV,GACrD,GAAIoV,EAAM4jB,EAAYA,EAAYt9B,OAAS,GACvC,OAEJ,MAAMw9B,EAAcF,EAAYG,WAAWnxB,GAAMoN,EAAMpN,IAAK,EAC5DgxB,EAAYI,MACZJ,EAAY7mB,OAAO+mB,EAAa,EAAG9jB,GACnC6jB,EAAQG,MACRH,EAAQ9mB,OAAO+mB,EAAa,EAAGl5B,EACnC,CCRO,MAAMq5B,GACL75B,WAAS,OAAOnC,KAAKi8B,KAAO,CAC5Bz8B,WAAS,OAAOQ,KAAKk8B,KAAO,CAKhCx8B,YAAYyC,EAAM3C,GACd,GAAYgL,MAARhL,EAAmB,CACnB,GAAYgL,MAARrI,EACA,MAAM,IAAIpE,MAAM,8CAGpB,GAFAiC,KAAKi8B,MAAQ95B,EACbnC,KAAKk8B,OAAS,EAAIz+B,KAAK6B,KAAK,EAAI,EAAQU,KAAKi8B,MAAM59B,SAAW,EAC1D2B,KAAKk8B,OAASz+B,KAAKE,MAAMqC,KAAKk8B,OAC9B,MAAM,IAAIn+B,MAAM,uBAAuBiC,KAAKi8B,MAAM59B,oCAAoC2B,KAAKk8B,QACnG,KACK,CACDl8B,KAAKk8B,MAAQ18B,EACb,MAAM28B,EAAa38B,GAAQA,EAAO,GAAK,EACvC,GAAI2C,EAAM,CACN,GAAIA,EAAK9D,QAAU89B,EACf,MAAM,IAAIp+B,MAAM,0CAA0CyB,0BAA6B28B,MAC3Fn8B,KAAKi8B,MAAQ95B,CACjB,MAEInC,KAAKi8B,MAAQ,IAAI3+B,aAAa6+B,EAEtC,CACJ,CACAC,aAAa79B,EAAGU,GACZ,KAAMV,EAAIU,GACN,MAAM,IAAIlB,MAAM,yBACpB,OAAOiC,KAAKk8B,MAAQ39B,EAAIU,EAAIxB,KAAKE,OAAQY,EAAI,IAAMA,EAAI,GAAM,EACjE,CACA4Q,IAAI5Q,EAAGU,GACH,OAAIV,GAAKU,EACE,EACFV,EAAIU,EACFe,KAAKi8B,MAAMj8B,KAAKo8B,aAAa79B,EAAGU,IAEhCe,KAAKi8B,MAAMj8B,KAAKo8B,aAAan9B,EAAGV,GAC/C,CACAgE,IAAIhE,EAAGU,EAAGyD,GACN1C,KAAKi8B,MAAMj8B,KAAKo8B,aAAa79B,EAAGU,IAAMyD,CAC1C,CACAuH,YAAYoyB,EAAM3yB,GACd,MAAMlK,EAAO68B,EAAKh+B,OACZ2W,EAAM,IAAIgnB,QAAexxB,EAAWhL,GAC1C,IAAK,IAAIjB,EAAI,EAAGA,EAAIiB,EAAMjB,IACtB,IAAK,IAAIU,EAAIV,EAAI,EAAGU,EAAIO,EAAMP,IAE1B+V,EAAIzS,IAAIhE,EAAGU,EAAIw8B,GAAMY,EAAK99B,KAAQk9B,GAAMY,EAAKp9B,IAAiC,EAA3ByK,EAAO2yB,EAAK99B,GAAI89B,EAAKp9B,KAGhF,OAAO+V,CACX,CAEAsnB,SACI,IAAK,IAAI/9B,EAAI,EAAGA,EAAIyB,KAAKi8B,MAAM59B,OAAQE,IACnCyB,KAAKi8B,MAAM19B,GAAKyB,KAAKi8B,MAAM19B,IAAM,CACzC,CAEAiS,IAAIoO,GACA,GAAI5e,KAAKk8B,QAAUtd,EAAMsd,MACrB,MAAM,IAAIn+B,MAAM,gDAAgDiC,KAAKk8B,sBAAsBtd,EAAMsd,SACrG,IAAK,IAAI39B,EAAI,EAAGA,EAAIyB,KAAKi8B,MAAM59B,OAAQE,IACnCyB,KAAKi8B,MAAM19B,IAAMqgB,EAAMqd,MAAM19B,EACrC,CAEAe,OACI,IAAK,IAAIf,EAAI,EAAGA,EAAIyB,KAAKi8B,MAAM59B,OAAQE,IACnCyB,KAAKi8B,MAAM19B,GAAKd,KAAK6B,KAAKU,KAAKi8B,MAAM19B,GAC7C,CAEAmC,YACI,IAAIO,EAAM,EACNf,EAAMF,KAAKi8B,MAAM,GACrB,IAAK,IAAI19B,EAAI,EAAGA,EAAIyB,KAAKi8B,MAAM59B,OAAQE,IAC/ByB,KAAKi8B,MAAM19B,GAAK0C,IAChBA,EAAMjB,KAAKi8B,MAAM19B,IACjByB,KAAKi8B,MAAM19B,GAAK2B,IAChBA,EAAMF,KAAKi8B,MAAM19B,IAEzB,MAAMf,EAAQ0C,EAAMe,EACpB,IAAK,IAAI1C,EAAI,EAAGA,EAAIyB,KAAKi8B,MAAM59B,OAAQE,IACnCyB,KAAKi8B,MAAM19B,GAAe,IAAVf,EAAcwC,KAAKi8B,MAAM19B,GAAK0C,GAAOjB,KAAKi8B,MAAM19B,GAAK0C,IAAQf,EAAMe,EAC3F,ECrFG,MAAMs7B,GACT78B,cACIM,KAAKC,aAAexC,KAAKyC,IAAIJ,UAAUC,oBAAsB,EAAG,EACpE,CACAQ,WAAWC,EAAQC,EAAQovB,EAAWlvB,EAAO,CAAC,GAE1C,MAAM67B,EAAUh8B,EAAOnC,QAAUmC,EAAOnC,OAAS,GAAK,EAChD6C,EAAYzD,KAAKE,MAAM6+B,EAAUx8B,KAAKC,cACtCw8B,EAAej8B,EAAOnC,OAAS,UAAc2B,KAAK08B,oBAAoBl8B,EAAQC,EAAQE,GAAQ,EAChGkvB,EAAY4M,IACZna,QAAQ2I,IAAI,mBAAmBwR,KAC/B5M,EAAY4M,GAEhB97B,EAAgB,UAAIkvB,EACpB,MAAM9uB,EAAW,IAAIjC,MAAMkB,KAAKC,cAC1B08B,EAAU,IAAI79B,MAAMkB,KAAKC,cAAcpB,KAAK,MAAME,KAAI,IAAM,IAAIqB,OAAO,IAAIC,IAAI,oBACrF,IAAK,IAAI+M,EAAM,EAAGA,EAAMpN,KAAKC,aAAcmN,IACvCrM,EAASqM,GAAO,IAAIxM,SAAQ,CAACoB,EAAeC,KACxC,MAAM26B,EAAWxvB,EAAMlM,EACjB27B,EAASzvB,IAAQpN,KAAKC,aAAe,EAAIu8B,GAAWpvB,EAAM,GAAKlM,EACjE27B,GAAUD,GACV56B,EAAc,CAAEzD,EAAG,IAAI8R,WAAW,GAAIpR,EAAG,IAAIoR,WAAW,GAAI5M,SAAU,IAAInG,aAAa,GAAI8P,QAC/FuvB,EAAQvvB,GAAKtL,YAAY,CAAEtB,SAAQo8B,WAAUC,SAAQhN,YAAWpvB,SAAQE,SACxEg8B,EAAQvvB,GAAKlL,UAAY,EAAGC,MAAQC,QAAO7D,IAAGU,IAAGwE,gBACzCrB,GACAu6B,EAAQvvB,GAAK9K,YACbL,EAAaG,KAGbu6B,EAAQvvB,GAAK9K,YACbN,EAAc,CAAEzD,IAAGU,IAAGwE,WAAU2J,QACpC,CACH,IAGT,MAAM6oB,QAAgBr1B,QAAQ4B,IAAIzB,GAC5B+7B,EAAW7G,EAAQ5sB,QAAO,CAAC0zB,EAAKvzB,IAAQuzB,EAAMvzB,EAAIjL,EAAEF,QAAQ,GAC5DE,EAAI,IAAI8R,WAAWysB,GACnB79B,EAAI,IAAIoR,WAAWysB,GACnBr5B,EAAW,IAAInG,aAAaw/B,GAClC,IAAIroB,EAAS,EAEb,IAAK,MAAMO,KAAOihB,EACd13B,EAAEgE,IAAIyS,EAAIzW,EAAGkW,GACbxV,EAAEsD,IAAIyS,EAAI/V,EAAGwV,GACbhR,EAASlB,IAAIyS,EAAIvR,SAAUgR,GAC3BA,GAAUO,EAAIzW,EAAEF,OAEpB,MAAO,CAAEE,IAAGU,IAAGwE,WACnB,CACAlD,aAAaC,EAAQC,EAAQu8B,EAAc,GAAIr8B,EAAO,CAAC,GACnD,MAAM67B,EAAUh8B,EAAOnC,QAAUmC,EAAOnC,OAAS,GAAK,EAChD6C,EAAYzD,KAAKE,MAAM6+B,EAAUx8B,KAAKC,cACtCc,EAAW,IAAIjC,MAAMkB,KAAKC,cAC1B08B,EAAU,IAAI79B,MAAMkB,KAAKC,cAAcpB,KAAK,MAAME,KAAI,IAAM,IAAIqB,OAAO,IAAIC,IAAI,qBACrF,IAAK,IAAI+M,EAAM,EAAGA,EAAMpN,KAAKC,aAAcmN,IACvCrM,EAASqM,GAAO,IAAIxM,SAAQ,CAACoB,EAAeC,KACxC,MAAM26B,EAAWxvB,EAAMlM,EACjB27B,EAASzvB,IAAQpN,KAAKC,aAAe,EAAIu8B,GAAWpvB,EAAM,GAAKlM,EACjE27B,GAAUD,GACV56B,EAAc,CAAE+xB,aAAc,IAAIj1B,MAAM,GAAIm+B,WAAY,IAAIn+B,MAAM,KACtE69B,EAAQvvB,GAAKtL,YAAY,CAAEtB,SAAQo8B,WAAUC,SAAQp8B,SAAQE,OAAMq8B,gBACnEL,EAAQvvB,GAAKlL,UAAY,EAAGC,MAAQC,QAAO2xB,eAAckJ,kBACjD76B,GACAu6B,EAAQvvB,GAAK9K,YACbL,EAAaG,KAGbu6B,EAAQvvB,GAAK9K,YACbN,EAAc,CAAE+xB,eAAckJ,eAClC,CACH,IAGT,MAAMhH,QAAgBr1B,QAAQ4B,IAAIzB,GAC5Bm8B,EAAS,CAAEnJ,aAAc,IAAIj1B,MAAM0B,EAAOnC,QAAQQ,KAAK,MAAME,KAAI,IAAM,IAAID,MAAMk+B,GAAan+B,KAAK,SACrGo+B,WAAY,IAAIn+B,MAAM0B,EAAOnC,QAAQQ,KAAK,MAAME,KAAI,IAAM,IAAID,MAAMk+B,GAAan+B,MAAM,MAC3F,IAAK,MAAMmW,KAAOihB,EACd,IAAK,IAAI13B,EAAI,EAAGA,EAAIiC,EAAOnC,SAAUE,EACjC,IAAK,IAAIU,EAAI,EAAGA,EAAI+V,EAAI+e,aAAax1B,IAAIF,SAAeY,EACpDy8B,GAAcwB,EAAOnJ,aAAax1B,GAAI2+B,EAAOD,WAAW1+B,GAAIyW,EAAI+e,aAAax1B,GAAGU,GAAI+V,EAAIioB,WAAW1+B,GAAGU,IAIlH,OAAOi+B,CACX,CACA38B,yBAAyBC,EAAQC,EAAQE,EAAO,CAAC,GAC7C,MAAMw8B,EAAmB,IAAIr+B,MAAMkB,KAAKC,cAAcpB,KAAK,MACtDE,KAAI,IAAM,IAAIqB,OAAO,IAAIC,IAAI,oBAG5B+8B,EAAiB58B,EAAOgY,QAC9B,IAAK,IAAIja,EAAI6+B,EAAe/+B,OAAS,EAAGE,EAAI,EAAGA,IAAK,CAChD,MAAMU,EAAIxB,KAAKE,MAAMF,KAAKC,UAAYa,EAAI,KACzC6+B,EAAe7+B,GAAI6+B,EAAen+B,IAAM,CAACm+B,EAAen+B,GAAIm+B,EAAe7+B,GAChF,CACA,IACI,MAAMi+B,EAAUh8B,EAAOnC,QAAUmC,EAAOnC,OAAS,GAAK,EAChD6C,EAAYzD,KAAKE,MAAM6+B,EAAUx8B,KAAKC,cACtCo9B,EAAgB,IAChBC,EAAa7/B,KAAKyC,IAAIzC,KAAKwD,IAAIu7B,EAAU,IAAMa,GAAgB5/B,KAAKwD,IAAIu7B,EAASa,IACjFE,EAAuB9/B,KAAKE,MAAM2/B,EAAat9B,KAAKC,cACpDu9B,EAAY,IAAI1+B,MAAMkB,KAAKC,cACjC,IAAK,IAAImN,EAAM,EAAGA,EAAMpN,KAAKC,aAAcmN,IACvCowB,EAAUpwB,GAAO,IAAIxM,SAAQ,CAACoB,EAAeC,KACzC,MAAM26B,EAAWxvB,EAAMlM,EACjB27B,EAASzvB,IAAQpN,KAAKC,aAAe,EAAIu8B,GAAWpvB,EAAM,GAAKlM,EACrEi8B,EAAiB/vB,GAAKtL,YAAY,CAAEtB,OAAQ48B,EAAgBR,WAAUC,SAAQY,aAAcF,EAAsB98B,SAAQE,SAC1Hw8B,EAAiB/vB,GAAKlL,UAAY,EAAGC,MAAQC,QAAOqB,gBAChD05B,EAAiB/vB,GAAK9K,YAClBF,EACAH,EAAaG,GAGbJ,EAAc,CAAEyB,YACpB,CACH,IAGT,MAAMwyB,QAAgBr1B,QAAQ4B,IAAIg7B,GAC5BV,EAAW7G,EAAQ5sB,QAAO,CAAC0zB,EAAKvzB,IAAQuzB,EAAMvzB,EAAI/F,SAASpF,QAAQ,GACnEoF,EAAW,IAAInG,aAAaw/B,GAClC,IAAIroB,EAAS,EACb,IAAK,MAAMO,KAAOihB,EACdxyB,EAASlB,IAAIyS,EAAIvR,SAAUgR,GAC3BA,GAAUO,EAAIvR,SAASpF,OAG3B,OADAoF,EAAS+L,OACF/L,CACX,CACA,MAAOb,GAGH,OAFAu6B,GAAkB16B,SAASw2B,GAAMA,GAAG32B,cACpCggB,QAAQlgB,MAAMQ,GACP,IAAItF,aAAa,GAAGuB,KAAK,GACpC,CACJ,CACA0B,0BAA0BC,EAAQC,EAAQE,EAAO,CAAC,GAK9C,IACI,MAAM67B,EAAUh8B,EAAOnC,QAAUmC,EAAOnC,OAAS,GAAK,EAChDoF,QAAiBzD,KAAK09B,mBAAmBl9B,EAAQC,EAAQE,GAI/D,OAFgB,EAAI8C,EADEhG,KAAKE,MAJA,IAI+B6+B,EAAU/4B,EAASpF,QAIjF,CACA,MAAOuE,GAEH,OADA0f,QAAQlgB,MAAMQ,GACP,EACX,CACJ,CACAqH,gBAAgBzJ,EAAQC,EAAQuyB,EAAYnD,GACxC,MAAMtxB,EAAI,GACJU,EAAI,GACJ02B,EAAY,GAClB,IAAIgI,EAAM,EACNC,EAAK,EACLC,EAAK,EACT,MAAMf,EAAWt8B,EAAOnC,QAAUmC,EAAOnC,OAAS,GAAK,EACvD,KAAOs/B,EAAMb,GAAU,CAEnB,MAAMp6B,EAAS+4B,GAAMj7B,EAAOo9B,KAASnC,GAAMj7B,EAAOq9B,IACT,EAArC7K,EAAWxyB,EAAOo9B,GAAKp9B,EAAOq9B,KACf10B,OAAO3I,OAAO8E,GAAsBw4B,MAAMvyB,GAAMA,IAAM9K,IhCD1E,GAAK,EgCCyGiC,GAAS,EAAIA,IACxGmtB,IACdtxB,EAAEgM,KAAKqzB,GACP3+B,EAAEsL,KAAKszB,GACPlI,EAAUprB,KAAK7H,IAEnBi7B,IACAE,IACIA,IAAOr9B,EAAOnC,SACdu/B,IACAC,EAAKD,EAAK,EAElB,CAIA,MAAO,CAAEr/B,EAHM,IAAI8R,WAAW9R,GAGVU,EAFL,IAAIoR,WAAWpR,GAECwE,SADT,IAAInG,aAAaq4B,GAE3C,EChLG,IAAIoI,IACX,SAAWA,GACPA,EAA0B,KAAI,OAC9BA,EAA2B,MAAI,OAClC,CAHD,CAGGA,KAAwBA,GAAsB,CAAC,IAyBlD,MAAMC,GACFt+B,YAAYqD,GACR/C,KAAKmC,KAAOY,EAAQZ,IACxB,EAkMJ,MAAM87B,GAAoB,CACtB,KAnJJ,cAA0BD,GAMtBt+B,YAAYqD,GACR+B,MAAM/B,GACNnF,EAAO,kBAAmBmF,GAC1BnF,EAAO,eAAgBmF,GACvB/C,KAAKk+B,eAAiBn7B,GAASm7B,eAC/Bl+B,KAAKgzB,WAAajwB,EAAQiwB,WAC1BhzB,KAAKm+B,aAAep7B,EAAQo7B,aAC5Bn+B,KAAKo+B,cAAgBr7B,EAAQq7B,cAC7Bp+B,KAAKq+B,YAAc9+B,EAAcS,KAAKmC,KAAK9D,QAE3C2B,KAAK2D,QAAU,IAAI7E,MAAMkB,KAAKmC,KAAK9D,QAAQQ,KAAK,GAAGE,KAAI,CAAC0L,EAAGlM,IAAMA,IACjEwE,EAAQiwB,WAAahzB,KAAKs+B,iBAAiBC,KAAKv+B,MAC5CA,KAAKmC,KAAK9D,OAAS,KACnB0E,EAAQkK,WAAajN,KAAKmC,KAAK9D,OAAS,GAC5C2B,KAAKw+B,QAAU,IAAItM,GAAKnvB,EAE5B,CAiBA07B,qBAAqBlzB,EAAGC,GACpB,OAAOxL,KAAK43B,aAAazoB,IAAI5D,IAAI4D,IAAI3D,IAAMxL,KAAK43B,aAAazoB,IAAI3D,IAAI2D,IAAI5D,IAAM,CACnF,CACA+yB,iBAAiB/yB,EAAGC,GAChB,OAAOxL,KAAKgzB,WAAWhzB,KAAKmC,KAAKoJ,GAAIvL,KAAKmC,KAAKqJ,GACnD,CAMAjL,gBAAgBm+B,GACZpc,QAAQqc,KAAK,aACb,MAAMzB,QAAe,IAAIX,IAAsBqC,OAAO5+B,KAAKmC,KAAMnC,KAAKo+B,cAAep+B,KAAKw+B,QAAQrM,UAAWnyB,KAAKk+B,gBAClH5b,QAAQuc,QAAQ,aAChB7+B,KAAKw+B,QAAQ3K,kBAAkBqJ,EAAOD,WAAYC,EAAOnJ,oBAEnD,IAAInzB,SAASC,IACfy6B,YAAW,KACPz6B,GAAS,GACV,IAAI,IAEX,MAAMuyB,QAAkBpzB,KAAKw+B,QAAQM,SAAS9+B,KAAK2D,SAAUo7B,IACrD/+B,KAAKm+B,cACLn+B,KAAKm+B,aAAaY,EAAM/+B,KAAKw+B,QAAQxK,aAAch0B,KAAKw+B,QAAQrH,eAAe,IAKvF,MAAO,CAAE/D,WAHsBjxB,EAGWixB,EAF/B,IAAIt0B,MAAMqD,EAAK9D,QAAQQ,KAAK,GAAGE,KAAI,CAAC0L,EAAGlM,IAAO,EAAOoR,KAAKxN,EAAK5D,UAEhByB,KAAKmB,eAAiB,CAAEsC,SAAUzD,KAAKmB,gBAAmB,CAAC,GAHrH,IAA+BgB,CAInC,GA+EA,QAjMJ,cAA0B67B,GAMtBt+B,YAAYqD,GACR+B,MAAM/B,GACN/C,KAAKw+B,QAAU,IAAI,IAAKz7B,GACxB/C,KAAKy6B,WAAa13B,GAAS03B,YAAc,IACzCz6B,KAAKo+B,cAAgBr7B,EAAQq7B,cAC7Bp+B,KAAKgzB,WAAajwB,EAAQiwB,UAC9B,CAMAzyB,gBAAgBy+B,GACZ,MAAMv7B,EAAWu7B,OAAgC,WAC7C,MAAMn7B,EAAgB,IAAIpE,GAAsB,GAAM,GACtD,IACI,MAAMgI,QAAa5D,EAAcC,KAAK9D,KAAKmC,KAAMnC,KAAKo+B,eAEtD,OADAv6B,EAAcvB,YACPmF,CACX,CACA,MAAO7E,GAEH,MADAiB,EAAcvB,YACRM,CACV,CACH,EAXgD,GAY7C,MAAS,MAAM0G,EAAM0yB,GAAel4B,KAAK9D,KAAKmC,MAAM,CAACoJ,EAAGC,IAAMxL,KAAKgzB,WAAWznB,EAAGC,KAAsB,OAAjBlC,EAAI5I,YAAoB4I,EAAInH,IAAO,EAAzH,GACE88B,ErCtEP,SAA6BC,EAAgB1/B,GAChD,MAAM2/B,EAAa5/B,EAAcC,GACjC,SAAS4/B,EAAY7gC,EAAGU,GACpB,MAAMogC,EAAO79B,OAAOjD,GACd+gC,EAAO99B,OAAOvC,GACpB,OAAOkgC,EAAWE,EAAMC,EAC5B,CAWA,MAAMC,EAAc,CAChBpwB,IAAG,CAAC4oB,EAAQyH,EAAMC,IACD,WAATD,EACOhgC,EACJ,IAAIkgC,MAAM3H,EAdzB,SAAqByH,GACjB,MAAO,CACHrwB,IAAG,CAAC4oB,EAAQ4H,EAAMF,IACVD,IAASG,EACF,EAEJ5H,EADWv2B,OAAOg+B,GAAQh+B,OAAOm+B,GAAQP,EAAYO,EAAMH,GAAQJ,EAAYI,EAAMG,IAIxG,CAKiCC,CAAYJ,KAG7C,OAAO,IAAIE,MAAMR,EAAgBK,EACrC,CqC6C4BM,CAAoBp8B,EAAUzD,KAAKmC,KAAK9D,QAC5D2B,KAAKw+B,QAAQsB,aAAab,GAC1B,IAAK,IAAI1gC,EAAI,EAAGA,EAAIyB,KAAKy6B,aAAcl8B,EACnCyB,KAAKw+B,QAAQl6B,OACjB,MAAO,CAAEb,SAAUA,EAAU2vB,UAAWpzB,KAAKw+B,QAAQuB,cACzD,GA6JA,IAxEJ,cAAyB/B,GAMrBt+B,YAAYqD,GACR+B,MAAM/B,GACN/C,KAAKw+B,QAAU,IAAI17B,EAAQC,EAC/B,CAKAxC,kBACI,MAAMy/B,QAAYhgC,KAAKw+B,QAAQtc,MAAMliB,KAAKmC,MAC1C,MAAO,CAAEsB,SAAUzD,KAAKw+B,QAAQ/6B,SAAU2vB,UAAW4M,EACzD,GAwDA,KAhDJ,cAA0BhC,GAMtBt+B,YAAYqD,GACR+B,MAAM/B,GACN/C,KAAKw+B,QAAU,IAAI55B,EAAS7B,EAChC,CAKAxC,kBACI,MAAMy/B,QAAYhgC,KAAKw+B,QAAQtc,MAAMliB,KAAKmC,MAC1C,MAAO,CAAEsB,SAAUzD,KAAKw+B,QAAQ/6B,SAAU2vB,UAAW4M,EACzD,GAgCA,YAxBJ,cAAiChC,GAM7Bt+B,YAAYqD,GACR+B,MAAM/B,GACN/C,KAAKw+B,QAAU,IAAI35B,EAAY9B,EACnC,CAKAxC,kBACI,MAAMy/B,QAAYhgC,KAAKw+B,QAAQtc,MAAMliB,KAAKmC,MAC1C,MAAO,CAAEsB,SAAUzD,KAAKw+B,QAAQ/6B,SAAU2vB,UAAW4M,EACzD,IAeG,MAAMC,GASTvgC,YAAYyC,EAAMuH,EAAQw2B,EAAQn9B,GAC9B,MAAMo9B,EAAU,IAAI12B,EAAQy2B,GAAQt2B,WAAW7G,GAASm7B,gBACxD,IAAIkC,EAAc,CAAC,EACfC,EAAiB,KACrB,IAAK,IAAI9hC,EAAI,EAAGA,EAAI4D,EAAK9D,SAAUE,EAC/B,GAAI4D,EAAK5D,IAAM4D,EAAK5D,GAAG+hC,QAAS,CAC5BD,EAAiBl+B,EAAK5D,GAAG+hC,QACzB,KACJ,CAEJ,GhC9L6B,YAA1Bp3B,EgC8LkBg3B,GACjB,IAAK,IAAI3hC,EAAI,EAAGA,EAAI4D,EAAK9D,SAAUE,EAC3B4D,EAAK5D,IAAM4D,EAAK5D,GAAG09B,MACnB95B,EAAK5D,GAAK,IAAI,IAAS4D,EAAK5D,GAAG09B,MAAO95B,EAAK5D,GAAG+hC,SAE9Cn+B,EAAK5D,GAAK,IAAI,IAAS8hC,GAI/BD,EADU,QAAV12B,EACc,CACLvH,KAAMA,EACN6wB,WAAYmN,EACZ/B,cAAe8B,EACf3N,QAASxvB,GAASE,UACpBF,GAGQ,SAAV2G,EACS,CACLvH,KAAMA,EACN6wB,WAAYmN,EACZ/B,cAAe8B,EACfzF,WAAY13B,GAASE,aAAUuH,KACjCzH,GAIO,CAAOZ,KAAMA,EAAasB,SAAU08B,EAAWz8B,qBAAsBw8B,KAAWn9B,GAKlG/C,KAAKw+B,QAAU,IAAIP,GAAkBv0B,GAAQ02B,EACjD,CAUA7/B,gBAAgBqjB,GAAY,EAAOob,GAC/B,QAAqBx0B,IAAjBxK,KAAKw+B,QACL,MAAM,IAAIzgC,MAAM,4BACpB,IAAI,UAAEq1B,EAAS,SAAE3vB,SAAmBzD,KAAKw+B,QAAQ3I,UAAUmJ,GtCxR5D,IAAyBpgC,EsC2RxB,OAFIglB,ItCzRoBhlB,EsC0RQw0B,EAA5BA,EtCzRD,IAAIt0B,MAAMF,EAAO,GAAGP,QAAQQ,KAAK,GACnCE,KAAI,CAAC0L,EAAGlM,IAAO,IAAI,EAAOK,EAAOP,QAAQQ,KAAK,GAAGE,KAAI,CAAC0L,EAAGxL,IAAOL,EAAOK,GAAGV,QsCyRpE,CAAEkF,SAAUA,EAAU2vB,UAAWA,EAC5C,CAQAnpB,8BAA8Bs2B,GAC1B,OAAOp3B,OAAOC,KAAKR,EAAiB23B,GACxC,CAOWC,8BACP,OAAOr3B,OAAOC,KAAK60B,GACvB,CAOWwC,8BACP,IAAIpP,EAAM,GAKV,OAJAloB,OAAO3I,OAAOoI,GAAkBnG,SAASi+B,IACrC,MAAMrnB,EAAQlQ,OAAO3I,OAAOkgC,GAC5BrP,EAAM,IAAIA,KAAQhY,EAAM,IAErBgY,CACX,EChVJ9wB,eAAe49B,GAAawC,EAAUC,EAAcxN,GAC5CuN,EAAW,GAAM,GACjBE,KAAK/+B,YAAY,CAAE6+B,WAAUC,eAAcxN,aACnD,CACAyN,KAAK3+B,UAAY3B,OAAS4B,MAAQ2+B,aAAYp3B,SAAQy2B,UAASp9B,UAASi8B,+BACpE,IAAI78B,EACJ,IACIA,QAXR5B,eAAyBugC,EAAYp3B,EAAQy2B,EAASp9B,EAASi8B,GAC3D,MAAMR,EAAU,IAAIyB,GAAsBa,EAAYp3B,EAAQy2B,EAAS,IAAKp9B,EAASo7B,kBACrF,aAAaK,EAAQ3I,WAAU,EAAMmJ,EACzC,CAQqB+B,CAAUD,EAAYp3B,EAAQy2B,EAASp9B,EAASi8B,EACjE,CACA,MAAOp8B,GACHT,EAAO,CAAEC,MAAOQ,EACpB,CACAi+B,KAAK/+B,YAAY,CACbM,MAAOD,EAAKC,MACZqB,SAAUtB,EAAKsB,SACf2vB,UAAWjxB,EAAKixB,WAClB,kBC7BN4N,EAAQ,OAAO,EACf,IAAIC,EAAS,EAAQ,MACrB93B,OAAO+3B,eAAeF,EAAS,IAA/B,CAAyCG,YAAY,EAAMhyB,IAAK,WAAc,OAAO8xB,EAAOG,IAAM,kBCHlGj4B,OAAO+3B,eAAeF,EAAS,aAAc,CAAEt+B,OAAO,IACtDs+B,EAAQI,UAAO,EA0VfJ,EAAQI,KAzVR,MACI1hC,YAAY2hC,GAERrhC,KAAKshC,SAAU,EACfthC,KAAKuhC,OAAS,EACdvhC,KAAK2uB,KAAO,EACZ0S,EAAMA,GAAO,CAAC,EACdrhC,KAAKwhC,WAAaxhC,KAAKyhC,OAAOJ,EAAK,aAAc,IACjDrhC,KAAKo5B,IAAMp5B,KAAKyhC,OAAOJ,EAAK,MAAO,GACnCrhC,KAAKuD,QAAUvD,KAAKyhC,OAAOJ,EAAK,UAAW,GAC/C,CACAzjC,OAAOC,EAAWC,GACd,IAAKD,EACD,MAAMC,GAAW,kBAEzB,CAEA2jC,OAAOJ,EAAKK,EAAOC,GACf,OAAIN,EAAIv3B,eAAe43B,GACZL,EAAIK,GAGJC,CAEf,CACAC,cACI,GAAI5hC,KAAKshC,QAEL,OADAthC,KAAKshC,SAAU,EACRthC,KAAKuhC,OAEhB,MAAMM,EAAI,EAAIpkC,KAAKC,SAAW,EACxBiN,EAAI,EAAIlN,KAAKC,SAAW,EACxB+G,EAAIo9B,EAAIA,EAAIl3B,EAAIA,EACtB,GAAU,IAANlG,GAAWA,EAAI,EACf,OAAOzE,KAAK4hC,cAEhB,MAAMxf,EAAI3kB,KAAK6B,MAAM,EAAI7B,KAAKwtB,IAAIxmB,GAAKA,GAGvC,OAFAzE,KAAKuhC,OAAS52B,EAAIyX,EAClBpiB,KAAKshC,SAAU,EACRO,EAAIzf,CACf,CAEA0f,MAAMC,EAAIC,GAAO,OAAOD,EAAK/hC,KAAK4hC,cAAgBI,CAAK,CAEvDp3B,MAAM1F,GACF,QAAmB,IAAR,GAAuB8pB,MAAM9pB,GACpC,MAAO,GAEX,GAA2B,oBAAhB+8B,YAA6B,CAEpC,MAAMC,EAAM,IAAIpjC,MAAMoG,GACtB,IAAK,IAAI3G,EAAI,EAAGA,EAAI2G,EAAG3G,IACnB2jC,EAAI3jC,GAAK,EAEb,OAAO2jC,CACX,CAEI,OAAO,IAAIpjB,aAAa5Z,EAEhC,CAGAi9B,QAAQj9B,EAAGR,EAAGqa,GACV,MAAMqjB,OAAoB,IAANrjB,EACdpZ,EAAI,GACV,IAAK,IAAIpH,EAAI,EAAGA,EAAI2G,EAAG3G,IAAK,CACxB,MAAM8jC,EAAQ,GACd,IAAK,IAAIpjC,EAAI,EAAGA,EAAIyF,EAAGzF,IACfmjC,EACAC,EAAM93B,KAAKwU,GAGXsjB,EAAM93B,KAAKvK,KAAK8hC,MAAM,EAAK,OAGnCn8B,EAAE4E,KAAK83B,EACX,CACA,OAAO18B,CACX,CAEA28B,GAAGC,EAAIC,GACH,MAAMC,EAAIF,EAAGlkC,OACb,IAAIqG,EAAI,EACR,IAAK,IAAInG,EAAI,EAAGA,EAAIkkC,EAAGlkC,IAAK,CACxB,MAAMmkC,EAAMH,EAAGhkC,GACTokC,EAAMH,EAAGjkC,GACfmG,IAAMg+B,EAAMC,IAAQD,EAAMC,EAC9B,CACA,OAAOj+B,CACX,CAEAk+B,KAAKlW,GACD,MAAMmW,EAAInW,EAAEruB,OACNoJ,EAAOzH,KAAK4K,MAAMi4B,EAAIA,GAC5B,IAAK,IAAItkC,EAAI,EAAGA,EAAIskC,EAAGtkC,IACnB,IAAK,IAAIU,EAAIV,EAAI,EAAGU,EAAI4jC,EAAG5jC,IAAK,CAC5B,MAAMyF,EAAI1E,KAAKsiC,GAAG5V,EAAEnuB,GAAImuB,EAAEztB,IAC1BwI,EAAKlJ,EAAIskC,EAAI5jC,GAAKyF,EAClB+C,EAAKxI,EAAI4jC,EAAItkC,GAAKmG,CACtB,CAEJ,OAAO+C,CACX,CAEAq7B,IAAIL,EAAGjB,EAAY7Q,GACf,MAAMoS,EAAKtlC,KAAK6B,KAAKmjC,EAAEpkC,QACjB6G,EAAIzH,KAAKE,MAAMolC,GACrB/iC,KAAKpC,OAAOsH,IAAM69B,EAAI,4CACtB,MAAMC,EAAUvlC,KAAKwtB,IAAIuW,GACnByB,EAAIjjC,KAAK4K,MAAM1F,EAAIA,GACnBg+B,EAAOljC,KAAK4K,MAAM1F,GACxB,IAAK,IAAI3G,EAAI,EAAGA,EAAI2G,EAAG3G,IAAK,CACxB,IAAI4kC,GAAU,IACVC,EAAUn3B,IACVo3B,EAAO,EACPC,GAAO,EACX,MAAMC,EAAW,GAGjB,IAAIxrB,EAAM,EACV,MAAQurB,GAAM,CAGV,IAAI1K,EAAO,EACX,IAAK,IAAI35B,EAAI,EAAGA,EAAIiG,EAAGjG,IAAK,CACxB,IAAIukC,EAAK/lC,KAAK6a,KAAKmqB,EAAElkC,EAAI2G,EAAIjG,GAAKokC,GAC9B9kC,IAAMU,IACNukC,EAAK,GAETN,EAAKjkC,GAAKukC,EACV5K,GAAQ4K,CACZ,CAEA,IAAIC,EAAQ,EACZ,IAAK,IAAIxkC,EAAI,EAAGA,EAAIiG,EAAGjG,IAAK,CACxB,IAAIukC,EAEAA,EADS,IAAT5K,EACK,EAGAsK,EAAKjkC,GAAK25B,EAEnBsK,EAAKjkC,GAAKukC,EACNA,EAAK,OACLC,GAASD,EAAK/lC,KAAKwtB,IAAIuY,GAE/B,CAEIC,EAAQT,GAGRG,EAAUE,EACND,IAAYn3B,IACZo3B,GAAc,EAGdA,GAAQA,EAAOD,GAAW,IAK9BA,EAAUC,EACNF,KAAY,IACZE,GAAc,EAGdA,GAAQA,EAAOF,GAAW,GAIlCprB,IACIta,KAAKkL,IAAI86B,EAAQT,GAAWrS,IAC5B2S,GAAO,GAEPvrB,GAAOwrB,IACPD,GAAO,EAEf,CAGA,IAAK,IAAIrkC,EAAI,EAAGA,EAAIiG,EAAGjG,IACnBgkC,EAAE1kC,EAAI2G,EAAIjG,GAAKikC,EAAKjkC,EAE5B,CAEA,MAAMykC,EAAO1jC,KAAK4K,MAAM1F,EAAIA,GACtBy+B,EAAS,EAAJz+B,EACX,IAAK,IAAI3G,EAAI,EAAGA,EAAI2G,EAAG3G,IACnB,IAAK,IAAIU,EAAI,EAAGA,EAAIiG,EAAGjG,IACnBykC,EAAKnlC,EAAI2G,EAAIjG,GAAKxB,KAAKyC,KAAK+iC,EAAE1kC,EAAI2G,EAAIjG,GAAKgkC,EAAEhkC,EAAIiG,EAAI3G,IAAMolC,EAAI,QAGvE,OAAOD,CACX,CAEArY,KAAK1lB,GAAK,OAAOA,EAAI,EAAI,EAAIA,EAAI,GAAK,EAAI,CAAG,CAG7Ci+B,YAAYlX,GACR,MAAMmW,EAAInW,EAAEruB,OACNokC,EAAI/V,EAAE,GAAGruB,OACf2B,KAAKpC,OAAOilC,EAAI,EAAG,yCACnB7iC,KAAKpC,OAAO6kC,EAAI,EAAG,sCACnB,MAAMoB,EAAQ7jC,KAAK4iC,KAAKlW,GACxB1sB,KAAKijC,EAAIjjC,KAAK8iC,IAAIe,EAAO7jC,KAAKwhC,WAAY,MAC1CxhC,KAAK6iC,EAAIA,EACT7iC,KAAK8jC,cACT,CAIAhE,aAAa2C,GACT,MAAMI,EAAIJ,EAAEpkC,OACZ2B,KAAKpC,OAAOilC,EAAI,EAAG,yCAEnB,MAAMgB,EAAQ7jC,KAAK4K,MAAMi4B,EAAIA,GAC7B,IAAK,IAAItkC,EAAI,EAAGA,EAAIskC,EAAGtkC,IACnB,IAAK,IAAIU,EAAIV,EAAI,EAAGU,EAAI4jC,EAAG5jC,IAAK,CAC5B,MAAMyF,EAAI+9B,EAAElkC,GAAGU,GACf4kC,EAAMtlC,EAAIskC,EAAI5jC,GAAKyF,EACnBm/B,EAAM5kC,EAAI4jC,EAAItkC,GAAKmG,CACvB,CAEJ1E,KAAKijC,EAAIjjC,KAAK8iC,IAAIe,EAAO7jC,KAAKwhC,WAAY,MAC1CxhC,KAAK6iC,EAAIA,EACT7iC,KAAK8jC,cACT,CAEAA,eAEI9jC,KAAK4vB,EAAI5vB,KAAKmiC,QAAQniC,KAAK6iC,EAAG7iC,KAAKo5B,KACnCp5B,KAAK+jC,MAAQ/jC,KAAKmiC,QAAQniC,KAAK6iC,EAAG7iC,KAAKo5B,IAAK,GAC5Cp5B,KAAKgkC,MAAQhkC,KAAKmiC,QAAQniC,KAAK6iC,EAAG7iC,KAAKo5B,IAAK,GAC5Cp5B,KAAK2uB,KAAO,CAChB,CAEAoR,cACI,OAAO//B,KAAK4vB,CAChB,CAEAtrB,OACItE,KAAK2uB,MAAQ,EACb,MAAMkU,EAAI7iC,KAAK6iC,EACToB,EAAKjkC,KAAKkkC,SAASlkC,KAAK4vB,GACxBuU,EAAOF,EAAGE,KACVC,EAAOH,EAAGG,KAEVC,EAAQrkC,KAAK4K,MAAM5K,KAAKo5B,KAC9B,IAAK,IAAI76B,EAAI,EAAGA,EAAIskC,EAAGtkC,IACnB,IAAK,IAAImG,EAAI,EAAGA,EAAI1E,KAAKo5B,IAAK10B,IAAK,CAC/B,MAAM4/B,EAAMF,EAAK7lC,GAAGmG,GACd6/B,EAAMvkC,KAAKgkC,MAAMzlC,GAAGmG,GACpB8/B,EAASxkC,KAAK+jC,MAAMxlC,GAAGmG,GAE7B,IAAI+/B,EAAUzkC,KAAKqrB,KAAKiZ,KAAStkC,KAAKqrB,KAAKkZ,GAAgB,GAATC,EAAeA,EAAS,GACtEC,EAAU,MACVA,EAAU,KAEdzkC,KAAK+jC,MAAMxlC,GAAGmG,GAAK+/B,EAEnB,MACMC,GADS1kC,KAAK2uB,KAAO,IAAM,GAAM,IACf4V,EAAMvkC,KAAKuD,QAAUkhC,EAAUL,EAAK7lC,GAAGmG,GAC/D1E,KAAKgkC,MAAMzlC,GAAGmG,GAAKggC,EAEnB1kC,KAAK4vB,EAAErxB,GAAGmG,IAAMggC,EAChBL,EAAM3/B,IAAM1E,KAAK4vB,EAAErxB,GAAGmG,EAC1B,CAGJ,IAAK,IAAInG,EAAI,EAAGA,EAAIskC,EAAGtkC,IACnB,IAAK,IAAImG,EAAI,EAAGA,EAAI1E,KAAKo5B,IAAK10B,IAC1B1E,KAAK4vB,EAAErxB,GAAGmG,IAAM2/B,EAAM3/B,GAAKm+B,EAInC,OAAOsB,CACX,CAEAQ,YACI,MAAM9B,EAAI7iC,KAAK6iC,EACToB,EAAKjkC,KAAKkkC,SAASlkC,KAAK4vB,GAExBwU,GADOH,EAAGE,KACHF,EAAGG,MACVxhC,EAAI,KACV,IAAK,IAAIrE,EAAI,EAAGA,EAAIskC,EAAGtkC,IACnB,IAAK,IAAImG,EAAI,EAAGA,EAAI1E,KAAKo5B,IAAK10B,IAAK,CAC/B,MAAMkgC,EAAO5kC,KAAK4vB,EAAErxB,GAAGmG,GACvB1E,KAAK4vB,EAAErxB,GAAGmG,GAAKkgC,EAAOhiC,EACtB,MAAMiiC,EAAM7kC,KAAKkkC,SAASlkC,KAAK4vB,GAC/B5vB,KAAK4vB,EAAErxB,GAAGmG,GAAKkgC,EAAOhiC,EACtB,MAAMkiC,EAAM9kC,KAAKkkC,SAASlkC,KAAK4vB,GACzBmV,EAAWX,EAAK7lC,GAAGmG,GACnBsgC,GAAaH,EAAIV,KAAOW,EAAIX,OAAS,EAAIvhC,GAC/C0f,QAAQ2I,IAAI1sB,EAAI,IAAMmG,EAAI,yBAA2BqgC,EAAW,mBAAqBC,GACrFhlC,KAAK4vB,EAAErxB,GAAGmG,GAAKkgC,CACnB,CAER,CAEAV,SAAStU,GACL,MAAMiT,EAAI7iC,KAAK6iC,EACTzJ,EAAMp5B,KAAKo5B,IACX6J,EAAIjjC,KAAKijC,EACTgC,EAAOjlC,KAAK2uB,KAAO,IAAM,EAAI,EAE7BuW,EAAQllC,KAAK4K,MAAMi4B,EAAIA,GAC7B,IAAIsC,EAAO,EACX,IAAK,IAAI5mC,EAAI,EAAGA,EAAIskC,EAAGtkC,IACnB,IAAK,IAAIU,EAAIV,EAAI,EAAGU,EAAI4jC,EAAG5jC,IAAK,CAC5B,IAAImmC,EAAO,EACX,IAAK,IAAI1gC,EAAI,EAAGA,EAAI00B,EAAK10B,IAAK,CAC1B,MAAM2gC,EAAQzV,EAAErxB,GAAGmG,GAAKkrB,EAAE3wB,GAAGyF,GAC7B0gC,GAAQC,EAAQA,CACpB,CACA,MAAMC,EAAK,GAAO,EAAMF,GACxBF,EAAM3mC,EAAIskC,EAAI5jC,GAAKqmC,EACnBJ,EAAMjmC,EAAI4jC,EAAItkC,GAAK+mC,EACnBH,GAAQ,EAAIG,CAChB,CAGJ,MAAMC,EAAK1C,EAAIA,EACT2C,EAAIxlC,KAAK4K,MAAM26B,GACrB,IAAK,IAAIrnC,EAAI,EAAGA,EAAIqnC,EAAIrnC,IACpBsnC,EAAEtnC,GAAKT,KAAKyC,IAAIglC,EAAMhnC,GAAKinC,EAAM,QAErC,IAAIhB,EAAO,EACX,MAAMC,EAAO,GACb,IAAK,IAAI7lC,EAAI,EAAGA,EAAIskC,EAAGtkC,IAAK,CACxB,MAAMknC,EAAO,IAAI3mC,MAAMs6B,GACvB,IAAK,IAAI10B,EAAI,EAAGA,EAAI00B,EAAK10B,IACrB+gC,EAAK/gC,GAAK,EAEd,IAAK,IAAIzF,EAAI,EAAGA,EAAI4jC,EAAG5jC,IAAK,CACxBklC,IAASlB,EAAE1kC,EAAIskC,EAAI5jC,GAAKxB,KAAKwtB,IAAIua,EAAEjnC,EAAIskC,EAAI5jC,IAC3C,MAAMymC,EAAU,GAAKT,EAAOhC,EAAE1kC,EAAIskC,EAAI5jC,GAAKumC,EAAEjnC,EAAIskC,EAAI5jC,IAAMimC,EAAM3mC,EAAIskC,EAAI5jC,GACzE,IAAK,IAAIyF,EAAI,EAAGA,EAAI00B,EAAK10B,IACrB+gC,EAAK/gC,IAAMghC,GAAW9V,EAAErxB,GAAGmG,GAAKkrB,EAAE3wB,GAAGyF,GAE7C,CACA0/B,EAAK75B,KAAKk7B,EACd,CACA,MAAO,CAAEtB,OAAMC,OACnB,KCzVAuB,EAA2B,CAAC,EAGhC,SAASC,EAAoBC,GAE5B,IAAIC,EAAeH,EAAyBE,GAC5C,QAAqBr7B,IAAjBs7B,EACH,OAAOA,EAAa9E,QAGrB,IAAI+E,EAASJ,EAAyBE,GAAY,CAGjD7E,QAAS,CAAC,GAOX,OAHAgF,EAAoBH,GAAUE,EAAQA,EAAO/E,QAAS4E,GAG/CG,EAAO/E,OACf,CAGA4E,EAAoB/0B,EAAIm1B,EAGxBJ,EAAoBjgC,EAAI,KAGvB,IAAIsgC,EAAsBL,EAAoBM,OAAE17B,EAAW,CAAC,IAAI,KAAK,IAAOo7B,EAAoB,QAEhG,OADsBA,EAAoBM,EAAED,EAClB,E9CjCvB7oC,EAAW,GACfwoC,EAAoBM,EAAI,CAAC/mC,EAAQgnC,EAAUr2B,EAAIs2B,KAC9C,IAAGD,EAAH,CAMA,IAAIE,EAAep6B,IACnB,IAAS1N,EAAI,EAAGA,EAAInB,EAASiB,OAAQE,IAAK,CAGzC,IAFA,IAAK4nC,EAAUr2B,EAAIs2B,GAAYhpC,EAASmB,GACpC+nC,GAAY,EACPrnC,EAAI,EAAGA,EAAIknC,EAAS9nC,OAAQY,MACpB,EAAXmnC,GAAsBC,GAAgBD,IAAaj9B,OAAOC,KAAKw8B,EAAoBM,GAAGlf,OAAOzd,GAASq8B,EAAoBM,EAAE38B,GAAK48B,EAASlnC,MAC9IknC,EAASrxB,OAAO7V,IAAK,IAErBqnC,GAAY,EACTF,EAAWC,IAAcA,EAAeD,IAG7C,GAAGE,EAAW,CACblpC,EAAS0X,OAAOvW,IAAK,GACrB,IAAIkG,EAAIqL,SACEtF,IAAN/F,IAAiBtF,EAASsF,EAC/B,CACD,CACA,OAAOtF,CAnBP,CAJCinC,EAAWA,GAAY,EACvB,IAAI,IAAI7nC,EAAInB,EAASiB,OAAQE,EAAI,GAAKnB,EAASmB,EAAI,GAAG,GAAK6nC,EAAU7nC,IAAKnB,EAASmB,GAAKnB,EAASmB,EAAI,GACrGnB,EAASmB,GAAK,CAAC4nC,EAAUr2B,EAAIs2B,EAqBjB,E+CzBdR,EAAoBlhC,EAAI,CAACs8B,EAASuF,KACjC,IAAI,IAAIh9B,KAAOg9B,EACXX,EAAoBY,EAAED,EAAYh9B,KAASq8B,EAAoBY,EAAExF,EAASz3B,IAC5EJ,OAAO+3B,eAAeF,EAASz3B,EAAK,CAAE43B,YAAY,EAAMhyB,IAAKo3B,EAAWh9B,IAE1E,ECNDq8B,EAAoB1W,EAAI,CAAC,EAGzB0W,EAAoBhjC,EAAK6jC,GACjB7lC,QAAQ4B,IAAI2G,OAAOC,KAAKw8B,EAAoB1W,GAAG7lB,QAAO,CAACtI,EAAUwI,KACvEq8B,EAAoB1W,EAAE3lB,GAAKk9B,EAAS1lC,GAC7BA,IACL,KCNJ6kC,EAAoB/D,EAAK4E,GAEZA,EAAU,MCHvBb,EAAoBjW,EAAI,WACvB,GAA0B,iBAAf+W,WAAyB,OAAOA,WAC3C,IACC,OAAO1mC,MAAQ,IAAI2mC,SAAS,cAAb,EAChB,CAAE,MAAO/jC,GACR,GAAsB,iBAAXgkC,OAAqB,OAAOA,MACxC,CACA,CAPuB,GCAxBhB,EAAoBY,EAAI,CAAC9F,EAAKmG,IAAU19B,OAAOkM,UAAUvL,eAAe0L,KAAKkrB,EAAKmG,SCAlF,IAAIC,EACAlB,EAAoBjW,EAAEoX,gBAAeD,EAAYlB,EAAoBjW,EAAEqX,SAAW,IACtF,IAAIC,EAAWrB,EAAoBjW,EAAEsX,SACrC,IAAKH,GAAaG,IACbA,EAASC,gBACZJ,EAAYG,EAASC,cAAcC,MAC/BL,GAAW,CACf,IAAIM,EAAUH,EAASI,qBAAqB,UAC5C,GAAGD,EAAQ/oC,OAEV,IADA,IAAIE,EAAI6oC,EAAQ/oC,OAAS,EAClBE,GAAK,IAAMuoC,GAAWA,EAAYM,EAAQ7oC,KAAK4oC,GAExD,CAID,IAAKL,EAAW,MAAM,IAAI/oC,MAAM,yDAChC+oC,EAAYA,EAAUQ,QAAQ,OAAQ,IAAIA,QAAQ,QAAS,IAAIA,QAAQ,YAAa,KACpF1B,EAAoB3nC,EAAI6oC,YClBxBlB,EAAoBp6B,EAAIq1B,KAAKmG,SAAW,GAIxC,IAAIO,EAAkB,CACrB,IAAK,GAgBN3B,EAAoB1W,EAAE3wB,EAAI,CAACkoC,EAAS1lC,KAE/BwmC,EAAgBd,IAElBM,cAAcnB,EAAoB3nC,EAAI2nC,EAAoB/D,EAAE4E,GAE9D,EAGD,IAAIe,EAAqB3G,KAAsB,gBAAIA,KAAsB,iBAAK,GAC1E4G,EAA6BD,EAAmBj9B,KAAKg0B,KAAKiJ,GAC9DA,EAAmBj9B,KAvBCpI,IACnB,IAAKgkC,EAAUuB,EAAaC,GAAWxlC,EACvC,IAAI,IAAI0jC,KAAY6B,EAChB9B,EAAoBY,EAAEkB,EAAa7B,KACrCD,EAAoB/0B,EAAEg1B,GAAY6B,EAAY7B,IAIhD,IADG8B,GAASA,EAAQ/B,GACdO,EAAS9nC,QACdkpC,EAAgBpB,EAASpK,OAAS,EACnC0L,EAA2BtlC,EAAK,MpDnB7B9E,EAAOuoC,EAAoBjgC,EAC/BigC,EAAoBjgC,EAAI,IAChB/E,QAAQ4B,IAAI,CAClBojC,EAAoBhjC,EAAE,KACtBgjC,EAAoBhjC,EAAE,MACpBglC,KAAKvqC,GqDJT,IAAI4oC,EAAsBL,EAAoBjgC","sources":["webpack://bio/webpack/runtime/chunk loaded","webpack://bio/webpack/runtime/startup chunk dependencies","webpack://bio/./node_modules/@datagrok-libraries/utils/src/type-declarations.js","webpack://bio/./node_modules/@datagrok-libraries/utils/src/random.js","webpack://bio/./node_modules/@datagrok-libraries/utils/src/vector-operations.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-matrix/proxy.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-matrix/distance-matrix-service.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/spe.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/typed-metrics/consts.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-metrics-methods.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/typed-metrics/typed-metrics.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/utils.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/heap.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/matrix.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/tree.js","webpack://bio/./node_modules/is-any-array/src/index.js","webpack://bio/./node_modules/ml-levenberg-marquardt/src/errorCalculation.js","webpack://bio/./node_modules/ml-matrix/node_modules/is-any-array/lib-esm/index.js","webpack://bio/./node_modules/ml-array-rescale/node_modules/is-any-array/lib-esm/index.js","webpack://bio/./node_modules/ml-array-max/node_modules/is-any-array/lib-esm/index.js","webpack://bio/./node_modules/ml-array-min/node_modules/is-any-array/lib-esm/index.js","webpack://bio/./node_modules/ml-array-rescale/lib-es6/index.js","webpack://bio/./node_modules/ml-array-min/lib-es6/index.js","webpack://bio/./node_modules/ml-array-max/lib-es6/index.js","webpack://bio/./node_modules/ml-matrix/src/inspect.js","webpack://bio/./node_modules/ml-matrix/src/util.js","webpack://bio/./node_modules/ml-matrix/src/matrix.js","webpack://bio/./node_modules/ml-matrix/src/stat.js","webpack://bio/./node_modules/ml-matrix/src/mathOperations.js","webpack://bio/./node_modules/ml-matrix/src/wrap/WrapperMatrix2D.js","webpack://bio/./node_modules/ml-matrix/src/dc/lu.js","webpack://bio/./node_modules/ml-matrix/src/dc/util.js","webpack://bio/./node_modules/ml-matrix/src/dc/qr.js","webpack://bio/./node_modules/ml-matrix/src/dc/svd.js","webpack://bio/./node_modules/ml-levenberg-marquardt/src/step.js","webpack://bio/./node_modules/ml-matrix/src/decompositions.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/umap.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/umap/nn_descent.js","webpack://bio/./node_modules/ml-levenberg-marquardt/src/index.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-matrix/utils.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-matrix/distance-matrix.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/distance-matrix/sparse-matrix-service.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/reduce-dimensionality.js","webpack://bio/./node_modules/@datagrok-libraries/ml/src/workers/dimensionality-reducer.js","webpack://bio/./node_modules/@keckelt/tsne/lib/index.js","webpack://bio/./node_modules/@keckelt/tsne/lib/tsne.js","webpack://bio/webpack/bootstrap","webpack://bio/webpack/runtime/define property getters","webpack://bio/webpack/runtime/ensure chunk","webpack://bio/webpack/runtime/get javascript chunk filename","webpack://bio/webpack/runtime/global","webpack://bio/webpack/runtime/hasOwnProperty shorthand","webpack://bio/webpack/runtime/publicPath","webpack://bio/webpack/runtime/importScripts chunk loading","webpack://bio/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","var next = __webpack_require__.x;\n__webpack_require__.x = () => {\n\treturn Promise.all([\n\t\t__webpack_require__.e(562),\n\t\t__webpack_require__.e(44)\n\t]).then(next);\n};","/**\n * Denotes a vector of floating poit values.\n *\n * @export\n * @class Vector\n * @extends {Float32Array}\n */\nexport class Vector extends Float32Array {\n}\n/**\n * Denotes a two-dimensional matrix.\n *\n * @export\n * @class Matrix\n * @extends {Array<Vector>}\n */\nexport class Matrix extends Array {\n}\n/**\n * Denotes cartesian coordinates.\n *\n * @export\n * @class Coordinates\n * @extends {Matrix}\n */\nexport class Coordinates extends Matrix {\n}\n/**\n * Denotes an array of arbitrary-typed vectors.\n *\n * @export\n * @class Vectors\n * @extends {Array<any>}\n */\nexport class Vectors extends Array {\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS1kZWNsYXJhdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0eXBlLWRlY2xhcmF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sTUFBTyxTQUFRLFlBQVk7Q0FBRztBQUUzQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sTUFBTyxTQUFRLEtBQWE7Q0FBRztBQUU1Qzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sV0FBWSxTQUFRLE1BQU07Q0FBRztBQUUxQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sT0FBUSxTQUFRLEtBQVU7Q0FBRyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIERHIGZyb20gJ2RhdGFncm9rLWFwaS9kZyc7XG5cbi8qKlxuICogRGVub3RlcyBhIHZlY3RvciBvZiBmbG9hdGluZyBwb2l0IHZhbHVlcy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgVmVjdG9yXG4gKiBAZXh0ZW5kcyB7RmxvYXQzMkFycmF5fVxuICovXG5leHBvcnQgY2xhc3MgVmVjdG9yIGV4dGVuZHMgRmxvYXQzMkFycmF5IHt9XG5cbi8qKlxuICogRGVub3RlcyBhIHR3by1kaW1lbnNpb25hbCBtYXRyaXguXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIE1hdHJpeFxuICogQGV4dGVuZHMge0FycmF5PFZlY3Rvcj59XG4gKi9cbmV4cG9ydCBjbGFzcyBNYXRyaXggZXh0ZW5kcyBBcnJheTxWZWN0b3I+IHt9XG5cbi8qKlxuICogRGVub3RlcyBjYXJ0ZXNpYW4gY29vcmRpbmF0ZXMuXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIENvb3JkaW5hdGVzXG4gKiBAZXh0ZW5kcyB7TWF0cml4fVxuICovXG5leHBvcnQgY2xhc3MgQ29vcmRpbmF0ZXMgZXh0ZW5kcyBNYXRyaXgge31cblxuLyoqXG4gKiBEZW5vdGVzIGFuIGFycmF5IG9mIGFyYml0cmFyeS10eXBlZCB2ZWN0b3JzLlxuICpcbiAqIEBleHBvcnRcbiAqIEBjbGFzcyBWZWN0b3JzXG4gKiBAZXh0ZW5kcyB7QXJyYXk8YW55Pn1cbiAqL1xuZXhwb3J0IGNsYXNzIFZlY3RvcnMgZXh0ZW5kcyBBcnJheTxhbnk+IHt9XG5cbi8qKlxuICogRGVub3RlcyBhIGRpY3Rpb25hcnkgY29udGFpbmluZyBmdW5jdGlvbiBvcHRpb25zLlxuICpcbiAqIEBleHBvcnRcbiAqIEB0eXBlIE9wdGlvbnNcbiAqL1xuZXhwb3J0IHR5cGUgT3B0aW9ucyA9IHtbbmFtZTogc3RyaW5nXTogYW55fTtcblxuLyoqXG4gKiBEZW5vdGVzIGN1c3RvbSBkaXN0YW5jZSBtZXRyaWMgYmV0d2VlbiB0aGUgdHdvIGdpdmVuIHZlY3RvcnMuXG4gKlxuICogQGV4cG9ydFxuICogQHR5cGUgRGlzdGFuY2VNZXRyaWNcbiAqIEBwYXJhbSB7YW55fSB2MSBUaGUgZmlyc3QgdmVjdG9yLlxuICogQHBhcmFtIHthbnl9IHYyIFRoZSBzZWNvbmQgdmVjdG9yLlxuICogQHJldHVybiB7bnVtYmVyfSBEaXN0YW5jZSBiZXR3ZWVuIHRoZXNlIHR3byB2ZWN0b3JzLlxuICovXG5leHBvcnQgdHlwZSBEaXN0YW5jZU1ldHJpYyA9ICh2MTogYW55LCB2MjogYW55KSA9PiAobnVtYmVyKTtcblxuLyoqXG4gKiBEZW5vdGVzIGEgc2ltcGxlIHN0cmluZyB0byBzdHJpbmcgZGljdGlvbmFyeS5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAdHlwZSBTdHJpbmdEaWN0aW9uYXJ5XG4gKi9cbmV4cG9ydCB0eXBlIFN0cmluZ0RpY3Rpb25hcnkgPSB7W2tleTogc3RyaW5nXTogc3RyaW5nfTtcblxuXG5leHBvcnQgdHlwZSBDb2x1bW5JbnB1dE9wdGlvbnMgPSB7XG4gICAgZmlsdGVyPzogKGNvbDogREcuQ29sdW1uKSA9PiBib29sZWFuIHwgbnVsbDtcbn07XG4iXX0=","/**\n * Generates single random float from 0 to range.\n *\n * @export\n * @param {number} range Max generating value.\n * @return {number} A random float generated.\n */\nexport function randomFloat(range) {\n return Math.random() * range;\n}\n/**\n * Generates single random integer from 0 to range.\n *\n * @export\n * @param {number} range Max generating value.\n * @return {number} A random integer generated.\n */\nexport function randomInt(range) {\n return Math.floor(randomFloat(range));\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFuZG9tLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicmFuZG9tLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUMsS0FBYTtJQUN2QyxPQUFPLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUM7QUFDL0IsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQUMsS0FBYTtJQUNyQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDeEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVzIHNpbmdsZSByYW5kb20gZmxvYXQgZnJvbSAwIHRvIHJhbmdlLlxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7bnVtYmVyfSByYW5nZSBNYXggZ2VuZXJhdGluZyB2YWx1ZS5cbiAqIEByZXR1cm4ge251bWJlcn0gQSByYW5kb20gZmxvYXQgZ2VuZXJhdGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmFuZG9tRmxvYXQocmFuZ2U6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiBNYXRoLnJhbmRvbSgpICogcmFuZ2U7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIHNpbmdsZSByYW5kb20gaW50ZWdlciBmcm9tIDAgdG8gcmFuZ2UuXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IHJhbmdlIE1heCBnZW5lcmF0aW5nIHZhbHVlLlxuICogQHJldHVybiB7bnVtYmVyfSBBIHJhbmRvbSBpbnRlZ2VyIGdlbmVyYXRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJhbmRvbUludChyYW5nZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IocmFuZG9tRmxvYXQocmFuZ2UpKTtcbn1cbiJdfQ==","import { Vector } from './type-declarations';\nimport { randomFloat, randomInt } from './random';\n/**\n * Asserts a condition by throwing an Error.\n *\n * @export\n * @param {boolean} [condition=false] Condition to assert.\n * @param {string} [message='Assertion error.'] Message to output.\n * @throws {Error}\n */\nexport function assert(condition = false, message = 'Assertion error.') {\n if (!condition)\n throw new Error(message);\n}\n/**\n * Creates new two-dimensional array and fills it with the value given.\n *\n * @param {number} dimension1 The first dimension of the coordinates (number of rows).\n * @param {number} dimension2 The second dimension of the coordinates (number of columns).\n * @param {number} [fill=0] A value to fill the coordinates with.\n * @return {Coordinates} A two-dimensional filled with the value given.\n * @todo Might be slow since used Array.map. Probably needs performance revision.\n */\nexport function initCoordinates(dimension1, dimension2, fill = 0) {\n return new Array(dimension1).fill(fill).map(() => (new Vector(dimension2).fill(fill)));\n}\n/**\n * Transpose matrix.\n *\n * @export\n * @param {Matrix} matrix The matrix to be transposed.\n * @return {Matrix} Transposed matrix.\n * @todo Might be slow since used Array.map. Probably needs performance revision.\n */\nexport function transposeMatrix(matrix) {\n return new Array(matrix[0].length).fill(0)\n .map((_, i) => (new Vector(matrix.length).fill(0).map((_, j) => (matrix[j][i]))));\n}\n/**\n * Adds two vectors with the second one to be multiplied by the given ratio.\n *\n * @export\n * @param {Vector} p The first vector to add.\n * @param {Vector} q The second vector to add.\n * @param {number} [multiplier=1] A multiplier to be used before the second vector is added.\n * @return {Vector} New vector contained the result of operation p+multiplier*q.\n */\nexport function vectorAdd(p, q, multiplier = 1) {\n const nItems = p.length;\n assert(nItems == q.length, 'Vector lengths do not match.');\n const total = new Vector(nItems);\n for (let i = 0; i < p.length; ++i)\n total[i] = p[i] + multiplier * q[i];\n return total;\n}\n/**\n * Sums the vector's items.\n *\n * @param {Vector} v The vector to be summed.\n * @return {number} The vector's items sum.\n */\nfunction itemsSum(v) {\n let total = 0;\n for (let i = 0; i < v.length; ++i)\n total += v[i];\n return total;\n}\n/**\n * Suqares the vector's items.\n *\n * @param {Vector} v The vector to square.\n * @return {Vector} A new vector containing the original's items squared.\n */\nfunction vectorSquare(v) {\n const nItems = v.length;\n const total = new Vector(nItems);\n for (let i = 0; i < v.length; ++i)\n total[i] = v[i] * v[i];\n return total;\n}\nexport function vectorLength(v) {\n let sqrSum = 0;\n for (let i = 0; i < v.length; i++)\n sqrSum += v[i] * v[i];\n return Math.sqrt(sqrSum);\n}\nexport function vectorDotProduct(v1, v2) {\n if (v1.length != v2.length)\n throw new Error('The dimensionality of the vectors must match');\n let prod = 0;\n for (let i = 0; i < v1.length; i++)\n prod += v1[i] * v2[i];\n return prod;\n}\n/**\n * Creates a matrix filled with random floating point values.\n *\n * @export\n * @param {number} dimension1 The first dimension of the matrix.\n * @param {number} dimension2 The second dimension of the matrix.\n * @param {number} [scale=1.] Max value given by random generator.\n * @return {Matrix} A new matrix filled with random floating point values.\n */\nexport function fillRandomMatrix(dimension1, dimension2, scale = 1.) {\n const matrix = initCoordinates(dimension1, dimension2);\n for (let i = 0; i < dimension1; ++i) {\n for (let j = 0; j < dimension2; ++j)\n matrix[i][j] = randomFloat(scale);\n }\n return matrix;\n}\n/**\n * Calculates Euclidean distance between two vectors.\n *\n * @export\n * @param {Vector} p The first vector.\n * @param {Vector} q The second vector.\n * @return {number} Euclidean distance between the given vectors.\n */\nexport function calculateEuclideanDistance(p, q) {\n let result = 0;\n const len = p.length;\n if (len !== q.length)\n throw new Error('The dimensionality of the vectors must match');\n for (let i = 0; i < len; ++i)\n result += Math.pow((p[i] - q[i]), 2);\n return Math.sqrt(result);\n}\n/**\n * Creates a distance matrix using a custom distance function.\n *\n * @export\n * @param {Vectors} data Input vectors to calculate distances.\n * @param {DistanceMetric} distance Custom distance function.\n * @return {Matrix} Calculated custom distance matrix.\n */\nexport function calcDistanceMatrix(data, distance) {\n const nItems = data.length;\n const matrix = initCoordinates(nItems, nItems, 0);\n for (let i = 0; i < nItems; ++i) {\n for (let j = i + 1; j < nItems; ++j) {\n const d = (data[i] == null) || (data[j] == null) ? 0 : distance(data[i], data[j]);\n matrix[i][j] = matrix[j][i] = d;\n }\n }\n return matrix;\n}\n/**\n * Creates a distance matrix using a custom distance function.\n *\n * @export\n * @param {Vectors} data Input vectors to calculate distances.\n * @param {DistanceMetric} distance Custom distance function.\n * @return {Matrix} Calculated custom distance matrix.\n */\nexport function calcNormalizedDistanceMatrix(data, distance) {\n const nItems = data.length;\n const matrix = initCoordinates(nItems, nItems, 0);\n let max = Number.MIN_VALUE;\n let min = Number.MAX_VALUE;\n for (let i = 0; i < nItems; ++i) {\n for (let j = i; j < nItems; ++j) {\n const d = (data[i] == null) || (data[j] == null || i === j) ? 0 : distance(data[i], data[j]);\n matrix[i][j] = matrix[j][i] = d;\n if (d > max)\n max = d;\n if (d < min)\n min = d;\n }\n }\n for (let i = 0; i < nItems; ++i) {\n for (let j = i + 1; j < nItems; ++j)\n matrix[i][j] = matrix[j][i] = (matrix[i][j] - min) / (max - min);\n }\n return matrix;\n}\n/** Generates array from a range [begin; end] or [begin; end) if endExclusive. **/\nexport function genRange(begin, end, endExclusive = false) {\n const nItems = end - begin + (endExclusive ? 0 : 1);\n const series = new Int32Array(nItems);\n for (let i = 0; i < nItems; ++i)\n series[i] = begin + i;\n return series;\n}\n/**\n * Returns order of values as if they are sorted.\n *\n * @export\n * @param {any[]} values Input array.\n * @param {boolean} [reverse=false] Whether to return reversed order.\n * @return {number[]} The order computed.\n */\nexport function argSort(values, reverse = false) {\n const sortfn = reverse ? (a, b) => (b[0] - a[0]) : (a, b) => (a[0] - b[0]);\n const decor = (v, i) => [v, i]; // set index to value\n const undecor = (a) => a[1]; // leave only index\n const _argsort = (arr) => arr.map(decor).sort(sortfn).map(undecor);\n return _argsort(values);\n}\n/**\n * Returns the indexes of the most diverse objects according to the dist function\n * @param {number} length total number of objects\n * @param {number} n number of diverse elements to find\n * @param {(i1: number, i2: number) => number} dist a function which calculates distance between\n * two objects using their indexes\n * @returns {number[]} The indexes of the most diverse objects\n */\nexport function getDiverseSubset(length, n, dist) {\n function maxBy(values, orderBy) {\n let maxValue = null;\n let maxOrderBy = null;\n for (const element of values) {\n const elementOrderBy = orderBy(element);\n if (maxOrderBy == null || elementOrderBy > maxOrderBy) {\n maxValue = element;\n maxOrderBy = elementOrderBy;\n }\n }\n return maxValue;\n }\n const subset = [randomInt(length - 1)];\n const complement = new Set();\n for (let i = 0; i < length; ++i) {\n if (!subset.includes(i))\n complement.add(i);\n }\n while (subset.length < n) {\n const idx = maxBy(complement.values(), (i) => Math.min.apply(Math, subset.map(function (val, index) {\n return dist(i, val);\n })));\n if (idx) {\n subset.push(idx);\n complement.delete(idx);\n }\n }\n return subset;\n}\n/**\n * Returns normalized vector.\n *\n * @export\n * @param {Vector} data numerical array\n */\nexport function normalize(data) {\n const len = data.length;\n let sum = 0;\n let sumOfSquares = 0;\n for (let i = 0; i < len; ++i) {\n sum += data[i];\n sumOfSquares += Math.pow(data[i], 2);\n }\n const mean = sum / len;\n const stdDevInverse = 1.0 / Math.sqrt(sumOfSquares / len - Math.pow(mean, 2));\n for (let i = 0; i < len; ++i)\n data[i] = (data[i] - mean) * stdDevInverse;\n return data;\n}\n/**\n * Finds set difference between two lists.\n * @param {any[]} a The first list.\n * @param {any[]} b The second list.\n * @return {any[]}\n */\nexport function setDifference(a, b) {\n const bSet = new Set(b);\n return Array.from(new Set(a.filter((x) => !bSet.has(x))).values());\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVjdG9yLW9wZXJhdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ2ZWN0b3Itb3BlcmF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQVMsTUFBTSxFQUF1QyxNQUFNLHFCQUFxQixDQUFDO0FBQ3pGLE9BQU8sRUFBQyxXQUFXLEVBQUUsU0FBUyxFQUFDLE1BQU0sVUFBVSxDQUFDO0FBRWhEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsTUFBTSxDQUFDLFlBQXFCLEtBQUssRUFBRSxVQUFrQixrQkFBa0I7SUFDckYsSUFBSSxDQUFDLFNBQVM7UUFDWixNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsVUFBa0IsRUFBRSxVQUFrQixFQUFFLE9BQWUsQ0FBQztJQUN0RixPQUFPLElBQUksS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pGLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FBQyxNQUFjO0lBQzVDLE9BQU8sSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7U0FDdkMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENB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QUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztBQUNyRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtNYXRyaXgsIFZlY3RvciwgQ29vcmRpbmF0ZXMsIFZlY3RvcnMsIERpc3RhbmNlTWV0cmljfSBmcm9tICcuL3R5cGUtZGVjbGFyYXRpb25zJztcbmltcG9ydCB7cmFuZG9tRmxvYXQsIHJhbmRvbUludH0gZnJvbSAnLi9yYW5kb20nO1xuXG4vKipcbiAqIEFzc2VydHMgYSBjb25kaXRpb24gYnkgdGhyb3dpbmcgYW4gRXJyb3IuXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtib29sZWFufSBbY29uZGl0aW9uPWZhbHNlXSBDb25kaXRpb24gdG8gYXNzZXJ0LlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlPSdBc3NlcnRpb24gZXJyb3IuJ10gTWVzc2FnZSB0byBvdXRwdXQuXG4gKiBAdGhyb3dzIHtFcnJvcn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydChjb25kaXRpb246IGJvb2xlYW4gPSBmYWxzZSwgbWVzc2FnZTogc3RyaW5nID0gJ0Fzc2VydGlvbiBlcnJvci4nKSB7XG4gIGlmICghY29uZGl0aW9uKVxuICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIG5ldyB0d28tZGltZW5zaW9uYWwgYXJyYXkgYW5kIGZpbGxzIGl0IHdpdGggdGhlIHZhbHVlIGdpdmVuLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBkaW1lbnNpb24xIFRoZSBmaXJzdCBkaW1lbnNpb24gb2YgdGhlIGNvb3JkaW5hdGVzIChudW1iZXIgb2Ygcm93cykuXG4gKiBAcGFyYW0ge251bWJlcn0gZGltZW5zaW9uMiBUaGUgc2Vjb25kIGRpbWVuc2lvbiBvZiB0aGUgY29vcmRpbmF0ZXMgKG51bWJlciBvZiBjb2x1bW5zKS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbZmlsbD0wXSBBIHZhbHVlIHRvIGZpbGwgdGhlIGNvb3JkaW5hdGVzIHdpdGguXG4gKiBAcmV0dXJuIHtDb29yZGluYXRlc30gQSB0d28tZGltZW5zaW9uYWwgZmlsbGVkIHdpdGggdGhlIHZhbHVlIGdpdmVuLlxuICogQHRvZG8gTWlnaHQgYmUgc2xvdyBzaW5jZSB1c2VkIEFycmF5Lm1hcC4gUHJvYmFibHkgbmVlZHMgcGVyZm9ybWFuY2UgcmV2aXNpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbml0Q29vcmRpbmF0ZXMoZGltZW5zaW9uMTogbnVtYmVyLCBkaW1lbnNpb24yOiBudW1iZXIsIGZpbGw6IG51bWJlciA9IDApOiBDb29yZGluYXRlcyB7XG4gIHJldHVybiBuZXcgQXJyYXkoZGltZW5zaW9uMSkuZmlsbChmaWxsKS5tYXAoKCkgPT4gKG5ldyBWZWN0b3IoZGltZW5zaW9uMikuZmlsbChmaWxsKSkpO1xufVxuXG4vKipcbiAqIFRyYW5zcG9zZSBtYXRyaXguXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtNYXRyaXh9IG1hdHJpeCBUaGUgbWF0cml4IHRvIGJlIHRyYW5zcG9zZWQuXG4gKiBAcmV0dXJuIHtNYXRyaXh9IFRyYW5zcG9zZWQgbWF0cml4LlxuICogQHRvZG8gTWlnaHQgYmUgc2xvdyBzaW5jZSB1c2VkIEFycmF5Lm1hcC4gUHJvYmFibHkgbmVlZHMgcGVyZm9ybWFuY2UgcmV2aXNpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc3Bvc2VNYXRyaXgobWF0cml4OiBNYXRyaXgpOiBNYXRyaXgge1xuICByZXR1cm4gbmV3IEFycmF5KG1hdHJpeFswXS5sZW5ndGgpLmZpbGwoMClcbiAgICAubWFwKChfLCBpKSA9PiAobmV3IFZlY3RvcihtYXRyaXgubGVuZ3RoKS5maWxsKDApLm1hcCgoXywgaikgPT4gKG1hdHJpeFtqXVtpXSkpKSk7XG59XG5cbi8qKlxuICogQWRkcyB0d28gdmVjdG9ycyB3aXRoIHRoZSBzZWNvbmQgb25lIHRvIGJlIG11bHRpcGxpZWQgYnkgdGhlIGdpdmVuIHJhdGlvLlxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7VmVjdG9yfSBwIFRoZSBmaXJzdCB2ZWN0b3IgdG8gYWRkLlxuICogQHBhcmFtIHtWZWN0b3J9IHEgVGhlIHNlY29uZCB2ZWN0b3IgdG8gYWRkLlxuICogQHBhcmFtIHtudW1iZXJ9IFttdWx0aXBsaWVyPTFdIEEgbXVsdGlwbGllciB0byBiZSB1c2VkIGJlZm9yZSB0aGUgc2Vjb25kIHZlY3RvciBpcyBhZGRlZC5cbiAqIEByZXR1cm4ge1ZlY3Rvcn0gTmV3IHZlY3RvciBjb250YWluZWQgdGhlIHJlc3VsdCBvZiBvcGVyYXRpb24gcCttdWx0aXBsaWVyKnEuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZWN0b3JBZGQocDogVmVjdG9yLCBxOiBWZWN0b3IsIG11bHRpcGxpZXI6IG51bWJlciA9IDEpOiBWZWN0b3Ige1xuICBjb25zdCBuSXRlbXMgPSBwLmxlbmd0aDtcblxuICBhc3NlcnQobkl0ZW1zID09IHEubGVuZ3RoLCAnVmVjdG9yIGxlbmd0aHMgZG8gbm90IG1hdGNoLicpO1xuXG4gIGNvbnN0IHRvdGFsID0gbmV3IFZlY3RvcihuSXRlbXMpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcC5sZW5ndGg7ICsraSlcbiAgICB0b3RhbFtpXSA9IHBbaV0gKyBtdWx0aXBsaWVyICogcVtpXTtcblxuICByZXR1cm4gdG90YWw7XG59XG5cbi8qKlxuICogU3VtcyB0aGUgdmVjdG9yJ3MgaXRlbXMuXG4gKlxuICogQHBhcmFtIHtWZWN0b3J9IHYgVGhlIHZlY3RvciB0byBiZSBzdW1tZWQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSB2ZWN0b3IncyBpdGVtcyBzdW0uXG4gKi9cbmZ1bmN0aW9uIGl0ZW1zU3VtKHY6IFZlY3Rvcik6IG51bWJlciB7XG4gIGxldCB0b3RhbCA9IDA7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB2Lmxlbmd0aDsgKytpKVxuICAgIHRvdGFsICs9IHZbaV07XG5cbiAgcmV0dXJuIHRvdGFsO1xufVxuXG4vKipcbiAqIFN1cWFyZXMgdGhlIHZlY3RvcidzIGl0ZW1zLlxuICpcbiAqIEBwYXJhbSB7VmVjdG9yfSB2IFRoZSB2ZWN0b3IgdG8gc3F1YXJlLlxuICogQHJldHVybiB7VmVjdG9yfSBBIG5ldyB2ZWN0b3IgY29udGFpbmluZyB0aGUgb3JpZ2luYWwncyBpdGVtcyBzcXVhcmVkLlxuICovXG5mdW5jdGlvbiB2ZWN0b3JTcXVhcmUodjogVmVjdG9yKTogVmVjdG9yIHtcbiAgY29uc3Qgbkl0ZW1zID0gdi5sZW5ndGg7XG4gIGNvbnN0IHRvdGFsID0gbmV3IFZlY3RvcihuSXRlbXMpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdi5sZW5ndGg7ICsraSlcbiAgICB0b3RhbFtpXSA9IHZbaV0gKiB2W2ldO1xuXG4gIHJldHVybiB0b3RhbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHZlY3Rvckxlbmd0aCh2OiBWZWN0b3IpOiBudW1iZXIge1xuICBsZXQgc3FyU3VtOiBudW1iZXIgPSAwO1xuICBmb3IgKGxldCBpOiBudW1iZXIgPSAwOyBpIDwgdi5sZW5ndGg7IGkrKylcbiAgICBzcXJTdW0gKz0gdltpXSAqIHZbaV07XG4gIHJldHVybiBNYXRoLnNxcnQoc3FyU3VtKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHZlY3RvckRvdFByb2R1Y3QodjE6IFZlY3RvciwgdjI6IFZlY3Rvcik6IG51bWJlciB7XG4gIGlmICh2MS5sZW5ndGggIT0gdjIubGVuZ3RoKVxuICAgIHRocm93IG5ldyBFcnJvcignVGhlIGRpbWVuc2lvbmFsaXR5IG9mIHRoZSB2ZWN0b3JzIG11c3QgbWF0Y2gnKTtcbiAgbGV0IHByb2Q6IG51bWJlciA9IDA7XG4gIGZvciAobGV0IGk6IG51bWJlciA9IDA7IGkgPCB2MS5sZW5ndGg7IGkrKylcbiAgICBwcm9kICs9IHYxW2ldICogdjJbaV07XG4gIHJldHVybiBwcm9kO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBtYXRyaXggZmlsbGVkIHdpdGggcmFuZG9tIGZsb2F0aW5nIHBvaW50IHZhbHVlcy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge251bWJlcn0gZGltZW5zaW9uMSBUaGUgZmlyc3QgZGltZW5zaW9uIG9mIHRoZSBtYXRyaXguXG4gKiBAcGFyYW0ge251bWJlcn0gZGltZW5zaW9uMiBUaGUgc2Vjb25kIGRpbWVuc2lvbiBvZiB0aGUgbWF0cml4LlxuICogQHBhcmFtIHtudW1iZXJ9IFtzY2FsZT0xLl0gTWF4IHZhbHVlIGdpdmVuIGJ5IHJhbmRvbSBnZW5lcmF0b3IuXG4gKiBAcmV0dXJuIHtNYXRyaXh9IEEgbmV3IG1hdHJpeCBmaWxsZWQgd2l0aCByYW5kb20gZmxvYXRpbmcgcG9pbnQgIHZhbHVlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbGxSYW5kb21NYXRyaXgoZGltZW5zaW9uMTogbnVtYmVyLCBkaW1lbnNpb24yOiBudW1iZXIsIHNjYWxlOiBudW1iZXIgPSAxLik6IE1hdHJpeCB7XG4gIGNvbnN0IG1hdHJpeCA9IGluaXRDb29yZGluYXRlcyhkaW1lbnNpb24xLCBkaW1lbnNpb24yKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGRpbWVuc2lvbjE7ICsraSkge1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgZGltZW5zaW9uMjsgKytqKVxuICAgICAgbWF0cml4W2ldW2pdID0gcmFuZG9tRmxvYXQoc2NhbGUpO1xuICB9XG4gIHJldHVybiBtYXRyaXg7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyBFdWNsaWRlYW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gdmVjdG9ycy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge1ZlY3Rvcn0gcCBUaGUgZmlyc3QgdmVjdG9yLlxuICogQHBhcmFtIHtWZWN0b3J9IHEgVGhlIHNlY29uZCB2ZWN0b3IuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEV1Y2xpZGVhbiBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBnaXZlbiB2ZWN0b3JzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlRXVjbGlkZWFuRGlzdGFuY2UocDogVmVjdG9yLCBxOiBWZWN0b3IpOiBudW1iZXIge1xuICBsZXQgcmVzdWx0ID0gMDtcbiAgY29uc3QgbGVuID0gcC5sZW5ndGg7XG5cbiAgaWYgKGxlbiAhPT0gcS5sZW5ndGgpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgZGltZW5zaW9uYWxpdHkgb2YgdGhlIHZlY3RvcnMgbXVzdCBtYXRjaCcpO1xuICBcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICByZXN1bHQgKz0gKHBbaV0gLSBxW2ldKSAqKiAyO1xuICBcbiAgcmV0dXJuIE1hdGguc3FydChyZXN1bHQpO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBkaXN0YW5jZSBtYXRyaXggdXNpbmcgYSBjdXN0b20gZGlzdGFuY2UgZnVuY3Rpb24uXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtWZWN0b3JzfSBkYXRhIElucHV0IHZlY3RvcnMgdG8gY2FsY3VsYXRlIGRpc3RhbmNlcy5cbiAqIEBwYXJhbSB7RGlzdGFuY2VNZXRyaWN9IGRpc3RhbmNlIEN1c3RvbSBkaXN0YW5jZSBmdW5jdGlvbi5cbiAqIEByZXR1cm4ge01hdHJpeH0gQ2FsY3VsYXRlZCBjdXN0b20gZGlzdGFuY2UgbWF0cml4LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY0Rpc3RhbmNlTWF0cml4KGRhdGE6IFZlY3RvcnMsIGRpc3RhbmNlOiBEaXN0YW5jZU1ldHJpYyk6IE1hdHJpeCB7XG4gIGNvbnN0IG5JdGVtcyA9IGRhdGEubGVuZ3RoO1xuICBjb25zdCBtYXRyaXggPSBpbml0Q29vcmRpbmF0ZXMobkl0ZW1zLCBuSXRlbXMsIDApO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbkl0ZW1zOyArK2kpIHtcbiAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCBuSXRlbXM7ICsraikge1xuICAgICAgY29uc3QgZDogbnVtYmVyID0gKGRhdGFbaV0gPT0gbnVsbCkgfHwgKGRhdGFbal0gPT0gbnVsbCkgPyAwIDogZGlzdGFuY2UoZGF0YVtpXSwgZGF0YVtqXSk7XG4gICAgICBtYXRyaXhbaV1bal0gPSBtYXRyaXhbal1baV0gPSBkO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbWF0cml4O1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBkaXN0YW5jZSBtYXRyaXggdXNpbmcgYSBjdXN0b20gZGlzdGFuY2UgZnVuY3Rpb24uXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtWZWN0b3JzfSBkYXRhIElucHV0IHZlY3RvcnMgdG8gY2FsY3VsYXRlIGRpc3RhbmNlcy5cbiAqIEBwYXJhbSB7RGlzdGFuY2VNZXRyaWN9IGRpc3RhbmNlIEN1c3RvbSBkaXN0YW5jZSBmdW5jdGlvbi5cbiAqIEByZXR1cm4ge01hdHJpeH0gQ2FsY3VsYXRlZCBjdXN0b20gZGlzdGFuY2UgbWF0cml4LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsY05vcm1hbGl6ZWREaXN0YW5jZU1hdHJpeChkYXRhOiBWZWN0b3JzLCBkaXN0YW5jZTogRGlzdGFuY2VNZXRyaWMpOiBNYXRyaXgge1xuICBjb25zdCBuSXRlbXMgPSBkYXRhLmxlbmd0aDtcbiAgY29uc3QgbWF0cml4ID0gaW5pdENvb3JkaW5hdGVzKG5JdGVtcywgbkl0ZW1zLCAwKTtcbiAgbGV0IG1heCA9IE51bWJlci5NSU5fVkFMVUU7XG4gIGxldCBtaW4gPSBOdW1iZXIuTUFYX1ZBTFVFO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG5JdGVtczsgKytpKSB7XG4gICAgZm9yIChsZXQgaiA9IGk7IGogPCBuSXRlbXM7ICsraikge1xuICAgICAgY29uc3QgZDogbnVtYmVyID0gKGRhdGFbaV0gPT0gbnVsbCkgfHwgKGRhdGFbal0gPT0gbnVsbCB8fCBpID09PSBqKSA/IDAgOiBkaXN0YW5jZShkYXRhW2ldLCBkYXRhW2pdKTtcbiAgICAgIG1hdHJpeFtpXVtqXSA9IG1hdHJpeFtqXVtpXSA9IGQ7XG4gICAgICBpZiAoZCA+IG1heCkgbWF4ID0gZDtcbiAgICAgIGlmIChkIDwgbWluKSBtaW4gPSBkO1xuICAgIH1cbiAgfVxuICBmb3IgKGxldCBpID0gMDsgaSA8IG5JdGVtczsgKytpKSB7XG4gICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgbkl0ZW1zOyArK2opXG4gICAgICBtYXRyaXhbaV1bal0gPSBtYXRyaXhbal1baV0gPSAobWF0cml4W2ldW2pdIC0gbWluKSAvIChtYXggLSBtaW4pO1xuICB9XG4gIHJldHVybiBtYXRyaXg7XG59XG5cbi8qKiBHZW5lcmF0ZXMgYXJyYXkgZnJvbSBhIHJhbmdlIFtiZWdpbjsgZW5kXSBvciBbYmVnaW47IGVuZCkgaWYgZW5kRXhjbHVzaXZlLiAqKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5SYW5nZShiZWdpbjogbnVtYmVyLCBlbmQ6IG51bWJlciwgZW5kRXhjbHVzaXZlID0gZmFsc2UpOiBJbnQzMkFycmF5IHtcbiAgY29uc3Qgbkl0ZW1zID0gZW5kIC0gYmVnaW4gKyAoZW5kRXhjbHVzaXZlID8gMCA6IDEpO1xuICBjb25zdCBzZXJpZXMgPSBuZXcgSW50MzJBcnJheShuSXRlbXMpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbkl0ZW1zOyArK2kpXG4gICAgc2VyaWVzW2ldID0gYmVnaW4gKyBpO1xuXG4gIHJldHVybiBzZXJpZXM7XG59XG5cbi8qKlxuICogUmV0dXJucyBvcmRlciBvZiB2YWx1ZXMgYXMgaWYgdGhleSBhcmUgc29ydGVkLlxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7YW55W119IHZhbHVlcyBJbnB1dCBhcnJheS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JldmVyc2U9ZmFsc2VdIFdoZXRoZXIgdG8gcmV0dXJuIHJldmVyc2VkIG9yZGVyLlxuICogQHJldHVybiB7bnVtYmVyW119IFRoZSBvcmRlciBjb21wdXRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFyZ1NvcnQodmFsdWVzOiBhbnlbXSwgcmV2ZXJzZSA9IGZhbHNlKTogbnVtYmVyW10ge1xuICBjb25zdCBzb3J0Zm4gPSByZXZlcnNlID8gKGE6IGFueVtdLCBiOiBhbnlbXSkgPT4gKGJbMF0gLSBhWzBdKSA6IChhOiBhbnlbXSwgYjogYW55W10pID0+IChhWzBdIC0gYlswXSk7XG4gIGNvbnN0IGRlY29yID0gKHY6IGFueSwgaTogbnVtYmVyKSA9PiBbdiwgaV07IC8vIHNldCBpbmRleCB0byB2YWx1ZVxuICBjb25zdCB1bmRlY29yID0gKGE6IGFueVtdKSA9PiBhWzFdOyAvLyBsZWF2ZSBvbmx5IGluZGV4XG4gIGNvbnN0IF9hcmdzb3J0ID0gKGFycjogYW55W10pID0+IGFyci5tYXAoZGVjb3IpLnNvcnQoc29ydGZuKS5tYXAodW5kZWNvcik7XG4gIHJldHVybiBfYXJnc29ydCh2YWx1ZXMpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGluZGV4ZXMgb2YgdGhlIG1vc3QgZGl2ZXJzZSBvYmplY3RzIGFjY29yZGluZyB0byB0aGUgZGlzdCBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCB0b3RhbCBudW1iZXIgb2Ygb2JqZWN0c1xuICogQHBhcmFtIHtudW1iZXJ9IG4gbnVtYmVyIG9mIGRpdmVyc2UgZWxlbWVudHMgdG8gZmluZFxuICogQHBhcmFtIHsoaTE6IG51bWJlciwgaTI6IG51bWJlcikgPT4gbnVtYmVyfSBkaXN0IGEgZnVuY3Rpb24gd2hpY2ggY2FsY3VsYXRlcyBkaXN0YW5jZSBiZXR3ZWVuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHdvIG9iamVjdHMgdXNpbmcgdGhlaXIgaW5kZXhlc1xuICogQHJldHVybnMge251bWJlcltdfSBUaGUgaW5kZXhlcyBvZiB0aGUgbW9zdCBkaXZlcnNlIG9iamVjdHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERpdmVyc2VTdWJzZXQobGVuZ3RoOiBudW1iZXIsIG46IG51bWJlciwgZGlzdDogKGkxOiBudW1iZXIsIGkyOiBudW1iZXIpID0+IG51bWJlcik6IG51bWJlcltdIHtcbiAgZnVuY3Rpb24gbWF4QnkodmFsdWVzOiBJdGVyYWJsZUl0ZXJhdG9yPG51bWJlcj4sIG9yZGVyQnk6IChpOiBudW1iZXIpID0+IG51bWJlcikge1xuICAgIGxldCBtYXhWYWx1ZSA9IG51bGw7XG4gICAgbGV0IG1heE9yZGVyQnkgPSBudWxsO1xuXG4gICAgZm9yIChjb25zdCBlbGVtZW50IG9mIHZhbHVlcykge1xuICAgICAgY29uc3QgZWxlbWVudE9yZGVyQnkgPSBvcmRlckJ5KGVsZW1lbnQpO1xuICAgICAgaWYgKG1heE9yZGVyQnkgPT0gbnVsbCB8fCBlbGVtZW50T3JkZXJCeSA+IG1heE9yZGVyQnkpIHtcbiAgICAgICAgbWF4VmFsdWUgPSBlbGVtZW50O1xuICAgICAgICBtYXhPcmRlckJ5ID0gZWxlbWVudE9yZGVyQnk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtYXhWYWx1ZTtcbiAgfVxuXG4gIGNvbnN0IHN1YnNldCA9IFtyYW5kb21JbnQobGVuZ3RoIC0gMSldO1xuICBjb25zdCBjb21wbGVtZW50ID0gbmV3IFNldCgpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoIXN1YnNldC5pbmNsdWRlcyhpKSlcbiAgICAgIGNvbXBsZW1lbnQuYWRkKGkpO1xuICB9XG5cbiAgd2hpbGUgKHN1YnNldC5sZW5ndGggPCBuKSB7XG4gICAgY29uc3QgaWR4ID0gbWF4QnkoXG4gICAgICBjb21wbGVtZW50LnZhbHVlcygpIGFzIEl0ZXJhYmxlSXRlcmF0b3I8bnVtYmVyPixcbiAgICAgIChpKSA9PiBNYXRoLm1pbi5hcHBseShNYXRoLCBzdWJzZXQubWFwKGZ1bmN0aW9uKHZhbCwgaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIGRpc3QoaSwgdmFsKTtcbiAgICAgIH0pKSk7XG4gICAgaWYgKGlkeCkge1xuICAgICAgc3Vic2V0LnB1c2goaWR4KTtcbiAgICAgIGNvbXBsZW1lbnQuZGVsZXRlKGlkeCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBzdWJzZXQ7XG59XG5cbi8qKlxuICogUmV0dXJucyBub3JtYWxpemVkIHZlY3Rvci5cbiAqIFxuICogQGV4cG9ydFxuICogQHBhcmFtIHtWZWN0b3J9IGRhdGEgbnVtZXJpY2FsIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemUoZGF0YTogVmVjdG9yKTogVmVjdG9yIHtcbiAgY29uc3QgbGVuID0gZGF0YS5sZW5ndGg7XG4gIGxldCBzdW0gPSAwO1xuICBsZXQgc3VtT2ZTcXVhcmVzID0gMDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgc3VtICs9IGRhdGFbaV07XG4gICAgc3VtT2ZTcXVhcmVzICs9IGRhdGFbaV0gKiogMjtcbiAgfVxuXG4gIGNvbnN0IG1lYW4gPSBzdW0gLyBsZW47XG4gIGNvbnN0IHN0ZERldkludmVyc2UgPSAxLjAgLyBNYXRoLnNxcnQoc3VtT2ZTcXVhcmVzIC8gbGVuIC0gbWVhbiAqKiAyKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgIGRhdGFbaV0gPSAoZGF0YVtpXSAtIG1lYW4pICogc3RkRGV2SW52ZXJzZTtcblxuICByZXR1cm4gZGF0YTtcbn1cblxuLyoqXG4gKiBGaW5kcyBzZXQgZGlmZmVyZW5jZSBiZXR3ZWVuIHR3byBsaXN0cy5cbiAqIEBwYXJhbSB7YW55W119IGEgVGhlIGZpcnN0IGxpc3QuXG4gKiBAcGFyYW0ge2FueVtdfSBiIFRoZSBzZWNvbmQgbGlzdC5cbiAqIEByZXR1cm4ge2FueVtdfVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0RGlmZmVyZW5jZShhOiBhbnlbXSwgYjogYW55W10pOiBhbnlbXSB7XG4gIGNvbnN0IGJTZXQgPSBuZXcgU2V0KGIpO1xuICByZXR1cm4gQXJyYXkuZnJvbShuZXcgU2V0KGEuZmlsdGVyKCh4KSA9PiAhYlNldC5oYXMoeCkpKS52YWx1ZXMoKSk7XG59XG4iXX0=","/** Proxy for DistanceMatrix class. Allows to index matrix as matrix[i][j]\n * Note: much slower than direct indexing, but still much faster than recalculating distances.\n * will be used for T-SNE mainly.\n * @param {Float32Array}condensedArray - array of distances between all pairs of objects\n * @param {number}size - number of comparebles in matrix\n * @return {Float32Array} - proxy for condensedArray\n*/\nexport function distanceMatrixProxy(condensedArray, size) {\n const linearFunc = dmLinearIndex(size);\n function linearIndex(i, j) {\n const iNum = Number(i);\n const jNum = Number(j);\n return linearFunc(iNum, jNum);\n }\n function idx2Handler(idx1) {\n return ({\n get(target, idx2, _receiver) {\n if (idx1 === idx2)\n return 0;\n const linearIdx = Number(idx1) > Number(idx2) ? linearIndex(idx2, idx1) : linearIndex(idx1, idx2);\n return target[linearIdx];\n },\n });\n }\n const idx1Handler = {\n get(target, idx1, _receiver) {\n if (idx1 === 'length')\n return size;\n return new Proxy(target, idx2Handler(idx1));\n },\n };\n return new Proxy(condensedArray, idx1Handler);\n}\nexport function dmLinearIndex(size) {\n return (i, j) => size * i + j - Math.floor(((i + 2) * (i + 1)) / 2);\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJveHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJwcm94eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7Ozs7O0VBTUU7QUFDRixNQUFNLFVBQVUsbUJBQW1CLENBQUMsY0FBNEIsRUFBRSxJQUFZO0lBQzVFLE1BQU0sVUFBVSxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN2QyxTQUFTLFdBQVcsQ0FBQyxDQUFrQixFQUFFLENBQWtCO1FBQ3pELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QixNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkIsT0FBTyxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRCxTQUFTLFdBQVcsQ0FBQyxJQUFxQjtRQUN4QyxPQUFPLENBQ0w7WUFDRSxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTO2dCQUN6QixJQUFJLElBQUksS0FBSyxJQUFJO29CQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUM1QixNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUNsRyxPQUFPLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUMzQixDQUFDO1NBQ0YsQ0FDRixDQUFDO0lBQ0osQ0FBQztJQUNELE1BQU0sV0FBVyxHQUErQjtRQUM5QyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTO1lBQ3pCLElBQUksSUFBSSxLQUFLLFFBQVE7Z0JBQUUsT0FBTyxJQUFJLENBQUM7WUFDbkMsT0FBTyxJQUFJLEtBQUssQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDOUMsQ0FBQztLQUNGLENBQUM7SUFFRixPQUFPLElBQUksS0FBSyxDQUFDLGNBQWMsRUFBRSxXQUFXLENBQUMsQ0FBQztBQUNoRCxDQUFDO0FBRUQsTUFBTSxVQUFVLGFBQWEsQ0FBQyxJQUFZO0lBQ3hDLE9BQU8sQ0FBQyxDQUFTLEVBQUUsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN0RixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiXG5cbi8qKiBQcm94eSBmb3IgRGlzdGFuY2VNYXRyaXggY2xhc3MuIEFsbG93cyB0byBpbmRleCBtYXRyaXggYXMgbWF0cml4W2ldW2pdXG4gKiBOb3RlOiBtdWNoIHNsb3dlciB0aGFuIGRpcmVjdCBpbmRleGluZywgYnV0IHN0aWxsIG11Y2ggZmFzdGVyIHRoYW4gcmVjYWxjdWxhdGluZyBkaXN0YW5jZXMuXG4gKiB3aWxsIGJlIHVzZWQgZm9yIFQtU05FIG1haW5seS5cbiAqIEBwYXJhbSB7RmxvYXQzMkFycmF5fWNvbmRlbnNlZEFycmF5IC0gYXJyYXkgb2YgZGlzdGFuY2VzIGJldHdlZW4gYWxsIHBhaXJzIG9mIG9iamVjdHNcbiAqIEBwYXJhbSB7bnVtYmVyfXNpemUgLSBudW1iZXIgb2YgY29tcGFyZWJsZXMgaW4gbWF0cml4XG4gKiBAcmV0dXJuIHtGbG9hdDMyQXJyYXl9IC0gcHJveHkgZm9yIGNvbmRlbnNlZEFycmF5XG4qL1xuZXhwb3J0IGZ1bmN0aW9uIGRpc3RhbmNlTWF0cml4UHJveHkoY29uZGVuc2VkQXJyYXk6IEZsb2F0MzJBcnJheSwgc2l6ZTogbnVtYmVyKTogRmxvYXQzMkFycmF5IHtcbiAgY29uc3QgbGluZWFyRnVuYyA9IGRtTGluZWFySW5kZXgoc2l6ZSk7XG4gIGZ1bmN0aW9uIGxpbmVhckluZGV4KGk6IHN5bWJvbCB8IHN0cmluZywgajogc3ltYm9sIHwgc3RyaW5nKSB7XG4gICAgY29uc3QgaU51bSA9IE51bWJlcihpKTtcbiAgICBjb25zdCBqTnVtID0gTnVtYmVyKGopO1xuICAgIHJldHVybiBsaW5lYXJGdW5jKGlOdW0sIGpOdW0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaWR4MkhhbmRsZXIoaWR4MTogc3ltYm9sIHwgc3RyaW5nKTpQcm94eUhhbmRsZXI8RmxvYXQzMkFycmF5PiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHtcbiAgICAgICAgZ2V0KHRhcmdldCwgaWR4MiwgX3JlY2VpdmVyKSB7XG4gICAgICAgICAgaWYgKGlkeDEgPT09IGlkeDIpIHJldHVybiAwO1xuICAgICAgICAgIGNvbnN0IGxpbmVhcklkeCA9IE51bWJlcihpZHgxKSA+IE51bWJlcihpZHgyKSA/IGxpbmVhckluZGV4KGlkeDIsIGlkeDEpIDogbGluZWFySW5kZXgoaWR4MSwgaWR4Mik7XG4gICAgICAgICAgcmV0dXJuIHRhcmdldFtsaW5lYXJJZHhdO1xuICAgICAgICB9LFxuICAgICAgfVxuICAgICk7XG4gIH1cbiAgY29uc3QgaWR4MUhhbmRsZXI6IFByb3h5SGFuZGxlcjxGbG9hdDMyQXJyYXk+ID0ge1xuICAgIGdldCh0YXJnZXQsIGlkeDEsIF9yZWNlaXZlcikge1xuICAgICAgaWYgKGlkeDEgPT09ICdsZW5ndGgnKSByZXR1cm4gc2l6ZTtcbiAgICAgIHJldHVybiBuZXcgUHJveHkodGFyZ2V0LCBpZHgySGFuZGxlcihpZHgxKSk7XG4gICAgfSxcbiAgfTtcblxuICByZXR1cm4gbmV3IFByb3h5KGNvbmRlbnNlZEFycmF5LCBpZHgxSGFuZGxlcik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkbUxpbmVhckluZGV4KHNpemU6IG51bWJlcik6IChpOiBudW1iZXIsIGo6IG51bWJlcikgPT4gbnVtYmVyIHtcbiAgcmV0dXJuIChpOiBudW1iZXIsIGo6IG51bWJlcikgPT4gc2l6ZSAqIGkgKyBqIC0gTWF0aC5mbG9vcigoKGkgKyAyKSAqIChpICsgMSkpIC8gMik7XG59XG4iXX0=","export class DistanceMatrixService {\n constructor(useConcurrentWorkers = true, terminateOnComplete = true) {\n const threadCount = navigator.hardwareConcurrency;\n this._workerCount = useConcurrentWorkers ? Math.max(threadCount - 2, 1) : 1;\n this._workers = new Array(this._workerCount).fill(null)\n .map(() => new Worker(new URL('./distance-matrix-worker', import.meta.url)));\n this._terminateOnComplete = terminateOnComplete;\n }\n ;\n async calc(values, fnName, normalize = true, opts) {\n return new Promise(async (resolve, reject) => {\n try {\n const len = values.length;\n const promises = new Array(this._workerCount);\n const totalLength = len * (len - 1) / 2; // size of reduced distance matrix\n this._workerCount = Math.min(this._workerCount, totalLength);\n const chunkSize = totalLength / this._workerCount;\n const distanceMatrix = new Float32Array(totalLength);\n let endRow = 0;\n let endCol = 1;\n // minmax for normalization\n let lmin = 0;\n let lmax = Number.MIN_VALUE;\n for (let i = 0; i < this._workerCount; i++) {\n const start = Math.floor(i * chunkSize);\n const end = (i === this._workerCount - 1) ? totalLength : Math.floor((i + 1) * chunkSize);\n const startRow = endRow;\n const startCol = endCol;\n if (i !== this._workerCount - 1) {\n // These formulas map the linear index to the upper triangular matrix indices\n endRow = len - 2 - Math.floor(Math.sqrt(-8 * end + 4 * len * (len - 1) - 7) / 2 - 0.5);\n endCol = end - len * endRow + Math.floor((endRow + 1) * (endRow + 2) / 2);\n }\n this._workers[i].postMessage({ values, fnName, startRow, startCol, chunckSize: end - start, opts });\n promises[i] = new Promise((resolveWorker, rejectWorker) => {\n this._workers[i].onmessage = ({ data: { error, distanceMatrixData, min, max } }) => {\n this._terminateOnComplete && this._workers[i].terminate();\n if (error) {\n rejectWorker(error);\n }\n else {\n distanceMatrix.set(distanceMatrixData, start);\n if (min < lmin)\n lmin = min;\n if (max > lmax)\n lmax = max;\n resolveWorker();\n }\n };\n });\n }\n await Promise.all(promises);\n if (normalize)\n distanceMatrix.forEach((value, index) => { distanceMatrix[index] = (value - lmin) / (lmax - lmin); });\n resolve(distanceMatrix);\n }\n catch (e) {\n reject(e);\n }\n });\n }\n terminate() {\n this._workers.forEach((worker) => worker.terminate());\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzdGFuY2UtbWF0cml4LXNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJkaXN0YW5jZS1tYXRyaXgtc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxNQUFNLE9BQU8scUJBQXFCO0lBSTlCLFlBQW1CLG9CQUFvQixHQUFHLElBQUksRUFBRSxtQkFBbUIsR0FBRyxJQUFJO1FBQ3hFLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQyxtQkFBbUIsQ0FBQztRQUNsRCxJQUFJLENBQUMsWUFBWSxHQUFHLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1RSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2FBQ3BELEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxJQUFJLEdBQUcsQ0FBQywwQkFBMEIsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvRSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsbUJBQW1CLENBQUM7SUFDbEQsQ0FBQztJQUFBLENBQUM7SUFFSyxLQUFLLENBQUMsSUFBSSxDQUFJLE1BQStCLEVBQUUsTUFBb0IsRUFDeEUsU0FBUyxHQUFHLElBQUksRUFBRSxJQUF5QjtRQUMzQyxPQUFPLElBQUksT0FBTyxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDM0MsSUFBSTtnQkFDRixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO2dCQUMxQixNQUFNLFFBQVEsR0FBRyxJQUFJLEtBQUssQ0FBZ0IsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUM3RCxNQUFNLFdBQVcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsa0NBQWtDO2dCQUMzRSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxXQUFXLENBQUMsQ0FBQztnQkFDN0QsTUFBTSxTQUFTLEdBQUcsV0FBVyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7Z0JBQ2xELE1BQU0sY0FBYyxHQUFHLElBQUksWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUNyRCxJQUFJLE1BQU0sR0FBRyxDQUFDLENBQUM7Z0JBQ2YsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO2dCQUNmLDJCQUEyQjtnQkFDM0IsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO2dCQUNiLElBQUksSUFBSSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7Z0JBQzVCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsRUFBRSxFQUFFO29CQUMxQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQztvQkFDeEMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDO29CQUMxRixNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUM7b0JBQ3hCLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQztvQkFDeEIsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLEVBQUU7d0JBQy9CLDZFQUE2RTt3QkFDN0UsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQzt3QkFDdkYsTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7cUJBQzNFO29CQUNELElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLEVBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxHQUFHLEdBQUcsS0FBSyxFQUFFLElBQUksRUFBQyxDQUFDLENBQUM7b0JBQ2xHLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLE9BQU8sQ0FBQyxDQUFDLGFBQWEsRUFBRSxZQUFZLEVBQUUsRUFBRTt3QkFDeEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxFQUFDLElBQUksRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFDLEVBQUMsRUFBUSxFQUFFOzRCQUNuRixJQUFJLENBQUMsb0JBQW9CLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQzs0QkFDMUQsSUFBSSxLQUFLLEVBQUU7Z0NBQ1QsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDOzZCQUNyQjtpQ0FBTTtnQ0FDTCxjQUFjLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxDQUFDO2dDQUM5QyxJQUFJLEdBQUcsR0FBRyxJQUFJO29DQUNaLElBQUksR0FBRyxHQUFHLENBQUM7Z0NBQ2IsSUFBSSxHQUFHLEdBQUcsSUFBSTtvQ0FDWixJQUFJLEdBQUcsR0FBRyxDQUFDO2dDQUNiLGFBQWEsRUFBRSxDQUFDOzZCQUNqQjt3QkFDSCxDQUFDLENBQUM7b0JBQ0osQ0FBQyxDQUFDLENBQUM7aUJBQ0o7Z0JBQ0QsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUM1QixJQUFJLFNBQVM7b0JBQ1gsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN4RyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7YUFDekI7WUFBQyxPQUFPLENBQUMsRUFBRTtnQkFDVixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDWDtRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLFNBQVM7UUFDZCxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7SUFDeEQsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtLbm93bk1ldHJpY3N9IGZyb20gJy4uL3R5cGVkLW1ldHJpY3MnO1xuXG5leHBvcnQgY2xhc3MgRGlzdGFuY2VNYXRyaXhTZXJ2aWNlIHtcbiAgICBwcml2YXRlIF93b3JrZXJzOiBXb3JrZXJbXTtcbiAgICBwcml2YXRlIF93b3JrZXJDb3VudDogbnVtYmVyO1xuICAgIHByaXZhdGUgX3Rlcm1pbmF0ZU9uQ29tcGxldGU6IGJvb2xlYW47XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHVzZUNvbmN1cnJlbnRXb3JrZXJzID0gdHJ1ZSwgdGVybWluYXRlT25Db21wbGV0ZSA9IHRydWUpIHtcbiAgICAgIGNvbnN0IHRocmVhZENvdW50ID0gbmF2aWdhdG9yLmhhcmR3YXJlQ29uY3VycmVuY3k7XG4gICAgICB0aGlzLl93b3JrZXJDb3VudCA9IHVzZUNvbmN1cnJlbnRXb3JrZXJzID8gTWF0aC5tYXgodGhyZWFkQ291bnQgLSAyLCAxKSA6IDE7XG4gICAgICB0aGlzLl93b3JrZXJzID0gbmV3IEFycmF5KHRoaXMuX3dvcmtlckNvdW50KS5maWxsKG51bGwpXG4gICAgICAgIC5tYXAoKCkgPT4gbmV3IFdvcmtlcihuZXcgVVJMKCcuL2Rpc3RhbmNlLW1hdHJpeC13b3JrZXInLCBpbXBvcnQubWV0YS51cmwpKSk7XG4gICAgICB0aGlzLl90ZXJtaW5hdGVPbkNvbXBsZXRlID0gdGVybWluYXRlT25Db21wbGV0ZTtcbiAgICB9O1xuXG4gICAgcHVibGljIGFzeW5jIGNhbGM8VD4odmFsdWVzOiBBcnJheTxUPiB8IEFycmF5TGlrZTxUPiwgZm5OYW1lOiBLbm93bk1ldHJpY3MsXG4gICAgICBub3JtYWxpemUgPSB0cnVlLCBvcHRzPzoge1tfOiBzdHJpbmddOiBhbnl9KTogUHJvbWlzZTxGbG9hdDMyQXJyYXk+IHtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgbGVuID0gdmFsdWVzLmxlbmd0aDtcbiAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHZvaWQ+Pih0aGlzLl93b3JrZXJDb3VudCk7XG4gICAgICAgICAgY29uc3QgdG90YWxMZW5ndGggPSBsZW4gKiAobGVuIC0gMSkgLyAyOyAvLyBzaXplIG9mIHJlZHVjZWQgZGlzdGFuY2UgbWF0cml4XG4gICAgICAgICAgdGhpcy5fd29ya2VyQ291bnQgPSBNYXRoLm1pbih0aGlzLl93b3JrZXJDb3VudCwgdG90YWxMZW5ndGgpO1xuICAgICAgICAgIGNvbnN0IGNodW5rU2l6ZSA9IHRvdGFsTGVuZ3RoIC8gdGhpcy5fd29ya2VyQ291bnQ7XG4gICAgICAgICAgY29uc3QgZGlzdGFuY2VNYXRyaXggPSBuZXcgRmxvYXQzMkFycmF5KHRvdGFsTGVuZ3RoKTtcbiAgICAgICAgICBsZXQgZW5kUm93ID0gMDtcbiAgICAgICAgICBsZXQgZW5kQ29sID0gMTtcbiAgICAgICAgICAvLyBtaW5tYXggZm9yIG5vcm1hbGl6YXRpb25cbiAgICAgICAgICBsZXQgbG1pbiA9IDA7XG4gICAgICAgICAgbGV0IGxtYXggPSBOdW1iZXIuTUlOX1ZBTFVFO1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fd29ya2VyQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgc3RhcnQgPSBNYXRoLmZsb29yKGkgKiBjaHVua1NpemUpO1xuICAgICAgICAgICAgY29uc3QgZW5kID0gKGkgPT09IHRoaXMuX3dvcmtlckNvdW50IC0gMSkgPyB0b3RhbExlbmd0aCA6IE1hdGguZmxvb3IoKGkgKyAxKSAqIGNodW5rU2l6ZSk7XG4gICAgICAgICAgICBjb25zdCBzdGFydFJvdyA9IGVuZFJvdztcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0Q29sID0gZW5kQ29sO1xuICAgICAgICAgICAgaWYgKGkgIT09IHRoaXMuX3dvcmtlckNvdW50IC0gMSkge1xuICAgICAgICAgICAgICAvLyBUaGVzZSBmb3JtdWxhcyBtYXAgdGhlIGxpbmVhciBpbmRleCB0byB0aGUgdXBwZXIgdHJpYW5ndWxhciBtYXRyaXggaW5kaWNlc1xuICAgICAgICAgICAgICBlbmRSb3cgPSBsZW4gLSAyIC0gTWF0aC5mbG9vcihNYXRoLnNxcnQoLTggKiBlbmQgKyA0ICogbGVuICogKGxlbiAtIDEpIC0gNykgLyAyIC0gMC41KTtcbiAgICAgICAgICAgICAgZW5kQ29sID0gZW5kIC0gbGVuICogZW5kUm93ICsgTWF0aC5mbG9vcigoZW5kUm93ICsgMSkgKiAoZW5kUm93ICsgMikgLyAyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3dvcmtlcnNbaV0ucG9zdE1lc3NhZ2Uoe3ZhbHVlcywgZm5OYW1lLCBzdGFydFJvdywgc3RhcnRDb2wsIGNodW5ja1NpemU6IGVuZCAtIHN0YXJ0LCBvcHRzfSk7XG4gICAgICAgICAgICBwcm9taXNlc1tpXSA9IG5ldyBQcm9taXNlKChyZXNvbHZlV29ya2VyLCByZWplY3RXb3JrZXIpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5fd29ya2Vyc1tpXS5vbm1lc3NhZ2UgPSAoe2RhdGE6IHtlcnJvciwgZGlzdGFuY2VNYXRyaXhEYXRhLCBtaW4sIG1heH19KTogdm9pZCA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGVybWluYXRlT25Db21wbGV0ZSAmJiB0aGlzLl93b3JrZXJzW2ldLnRlcm1pbmF0ZSgpO1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgcmVqZWN0V29ya2VyKGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgZGlzdGFuY2VNYXRyaXguc2V0KGRpc3RhbmNlTWF0cml4RGF0YSwgc3RhcnQpO1xuICAgICAgICAgICAgICAgICAgaWYgKG1pbiA8IGxtaW4pXG4gICAgICAgICAgICAgICAgICAgIGxtaW4gPSBtaW47XG4gICAgICAgICAgICAgICAgICBpZiAobWF4ID4gbG1heClcbiAgICAgICAgICAgICAgICAgICAgbG1heCA9IG1heDtcbiAgICAgICAgICAgICAgICAgIHJlc29sdmVXb3JrZXIoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICAgICAgICAgIGlmIChub3JtYWxpemUpXG4gICAgICAgICAgICBkaXN0YW5jZU1hdHJpeC5mb3JFYWNoKCh2YWx1ZSwgaW5kZXgpID0+IHsgZGlzdGFuY2VNYXRyaXhbaW5kZXhdID0gKHZhbHVlIC0gbG1pbikgLyAobG1heCAtIGxtaW4pOyB9KTtcbiAgICAgICAgICByZXNvbHZlKGRpc3RhbmNlTWF0cml4KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIHRlcm1pbmF0ZSgpOiB2b2lkIHtcbiAgICAgIHRoaXMuX3dvcmtlcnMuZm9yRWFjaCgod29ya2VyKSA9PiB3b3JrZXIudGVybWluYXRlKCkpO1xuICAgIH1cbn1cbiJdfQ==","import { calculateEuclideanDistance, fillRandomMatrix, vectorAdd, } from '@datagrok-libraries/utils/src/vector-operations';\nimport { randomInt } from '@datagrok-libraries/utils/src/random';\nimport { DistanceMatrixService, dmLinearIndex } from './distance-matrix';\n/**\n * Implements stochastic proximity embedding.\n *\n * @export\n * @class SPEBase\n * @link doi:10.1016/S1093-3263(03)00155-4\n */\nclass SPEBase {\n /**\n * Creates an instance of SPEBase.\n * @param {Options} [options] Options to pass to the constructor.\n * @memberof SPEBase\n */\n constructor(options) {\n this.steps = options?.steps ?? 0;\n this.cycles = options?.cycles ?? 1e6;\n // Select a cutoff distance {cutoff} and ...\n this.cutoff = options?.cutoff ?? 0;\n // ... an initial learning rate {lambda} > 0\n this.lambda = options?.lambda ?? 2.0;\n this.dlambda = options?.dlambda ?? 0.01;\n this.lambda2 = this.lambda / 2.;\n this.dlambda2 = this.dlambda / 2.;\n this.epsilon = options?.epsilon ?? 1e-10;\n // eslint-disable-next-line brace-style\n this.distanceFunction = options?.distance ?? calculateEuclideanDistance;\n this.distance = new Float32Array();\n this.distanceFunctionName = options?.distanceFunctionName;\n }\n /**\n * Initializes distance matrix.\n *\n * @param {Vectors} vectors Input vectors to calculate distance between.\n * @memberof SPEBase\n */\n async initDistance(vectors) {\n this.dmIndexFunct = dmLinearIndex(vectors.length);\n const matrixService = new DistanceMatrixService(true, false);\n this.distance = await matrixService.calc(vectors, this.distanceFunctionName);\n matrixService.terminate();\n }\n /**\n * Calculates distance between the two vectors given.\n *\n * @param {Vectors} vectors Set of vectors to calculate distances between.\n * @param {number} index1 Index of the first vector of the pair.\n * @param {number} index2 Index of the second vector of the pair.\n * @return {number} Distance between these two vectors.\n */\n calcDistance(vectors, index1, index2) {\n return this.distance[this.dmIndexFunct(index1, index2)];\n }\n /**\n * Embeds the vectors given into a two-dimensional space.\n *\n * @param {Vectors} vectors D-dimensional coordinates.\n * @return {Coordinates} SPE coordinates in D space.\n */\n async embed(vectors) {\n const nItems = vectors.length;\n const areaWidth = 40;\n // Initialize the D-dimensional coordinates of the N points.\n const coordinates = fillRandomMatrix(nItems, SPEBase.dimension, areaWidth);\n let lambda2 = this.lambda2;\n if (this.steps === 0)\n this.steps = vectors.length - 1;\n await this.initDistance(vectors);\n for (let cycle = 0; cycle < this.cycles; ++cycle) {\n for (let step = 0; step < this.steps; ++step) {\n // Select two points, i and j, at random, ...\n const i = randomInt(nItems);\n let j = randomInt(nItems);\n while (i == j)\n j = randomInt(nItems);\n const rowi = coordinates[i];\n const rowj = coordinates[j];\n // ... retrieve (or evaluate) their proximity in the input space, rij and ...\n const r = this.calcDistance(vectors, i, j);\n // ... compute their Euclidean distance on the D-dimensional map, dij.\n const d = calculateEuclideanDistance(rowi, rowj);\n // If rij <= rc, or if rij > rc and dij < rij ...\n if ((this.cutoff == 0) || (r <= this.cutoff) || (d < r)) {\n const multiplier = lambda2 * (r - d) / (d + this.epsilon);\n // ... update the coordinates xi and xj.\n const diffIJ = vectorAdd(rowi, rowj, -1);\n coordinates[i] = vectorAdd(rowi, diffIJ, multiplier);\n coordinates[j] = vectorAdd(rowj, diffIJ, -multiplier);\n }\n }\n // Decrease the learning rate {lambda} by a prescribed {dlambda}.\n lambda2 -= this.dlambda2;\n if (lambda2 <= 0.)\n break;\n }\n return coordinates;\n }\n}\nSPEBase.dimension = 2;\nexport { SPEBase };\n/**\n * Implements modified stochastic proximity embedding.\n *\n * @export\n * @class PSPEBase\n * @link doi:10.1016/S1093-3263(03)00155-4\n */\nexport class PSPEBase extends SPEBase {\n /**\n * Embeds the vectors given into a two-dimensional space using a modified update rule.\n *\n * @param {Vectors} vectors D-dimensional coordinates.\n * @return {Coordinates} SPE coordinates in D space.\n */\n async embed(vectors) {\n const nItems = vectors.length;\n const areaWidth = 40;\n // Initialize the D-dimensional coordinates of the N points.\n const coordinates = fillRandomMatrix(nItems, PSPEBase.dimension, areaWidth);\n let lambda = this.lambda;\n await this.initDistance(vectors);\n for (let cycle = 0; cycle < this.cycles; ++cycle) {\n // Select a point, i, at random (pivot).\n const i = randomInt(nItems);\n const rowi = coordinates[i];\n // For every point j != i ...\n for (let j = 0; j < nItems; ++j) {\n if (i == j)\n continue;\n const rowj = coordinates[j];\n // ... retrieve (or evaluate) its proximity to i in the input space, rij ...\n const r = this.calcDistance(vectors, i, j);\n // ... and compute their Euclidean distance on the D-dimensional map, dij.\n const d = calculateEuclideanDistance(rowi, rowj);\n // If rij <= rc, or if rij > rc and dij < rij ...\n if ((this.cutoff == 0) || (r <= this.cutoff) || (d < r)) {\n const multiplier = lambda * (r - d) / (d + this.epsilon);\n const diffIJ = vectorAdd(rowi, rowj, -1);\n // ... update the coordinates xj.\n coordinates[j] = vectorAdd(rowj, diffIJ, -multiplier);\n }\n }\n // Decrease the learning rate {lambda} by a prescribed {dlambda}.\n lambda -= this.dlambda;\n if (lambda <= 0.)\n break;\n }\n return coordinates;\n }\n}\n/**\n * Implements modified stochastic proximity embedding.\n *\n * @export\n * @class OriginalSPE\n * @link doi:10.1002/jcc.10234\n */\nexport class OriginalSPE extends SPEBase {\n constructor(options) {\n super(options);\n this.cycles = options?.cycles ?? 1e3;\n this.steps = options?.steps ?? 100000;\n this.radiusPercent = options?.radiusPercent ?? 1.0;\n this.maxDistance = options?.maxDistance ?? null;\n this.maxDistanceSteps = options?.maxDistanceSteps ?? null;\n }\n async embed(vectors) {\n const nItems = vectors.length;\n const areaWidth = 40;\n // Initialize the D-dimensional coordinates of the N points.\n const coordinates = fillRandomMatrix(nItems, OriginalSPE.dimension, areaWidth);\n await this.initDistance(vectors);\n if (this.maxDistanceSteps === null)\n this.maxDistanceSteps = nItems * Math.floor((nItems - 1) / 2);\n if (this.maxDistance === null) {\n this.maxDistance = -1e37;\n for (let n = 0; n < this.maxDistanceSteps; n++) {\n const i = randomInt(nItems);\n let j = randomInt(nItems);\n while (i == j)\n j = randomInt(nItems);\n const d = this.calcDistance(vectors, i, j);\n if (d > this.maxDistance)\n this.maxDistance = d;\n }\n }\n let lambda = this.lambda;\n const radius = (this.radiusPercent == 0.0) ? this.maxDistance : this.maxDistance * this.radiusPercent;\n for (let cycle = 0; cycle < this.cycles; ++cycle) {\n for (let step = 0; step < this.steps; ++step) {\n // Select two points, i and j, at random, ...\n const i = randomInt(nItems);\n let j = randomInt(nItems);\n while (i == j)\n j = randomInt(nItems);\n const rowi = coordinates[i];\n const rowj = coordinates[j];\n // retrieve (or evaluate) their proximity in the input space, rij and ...\n const r = this.calcDistance(vectors, i, j);\n // compute their Euclidean distance on the D-dimensional map, dij.\n const d = calculateEuclideanDistance(rowi, rowj);\n if ((r <= radius) || (d < r)) {\n const multiplier = lambda * 0.5 * (r - d) / (d + this.epsilon);\n // ... update the coordinates xi and xj.\n const diffIJ = vectorAdd(rowi, rowj, -1);\n coordinates[i] = vectorAdd(rowi, diffIJ, multiplier);\n coordinates[j] = vectorAdd(rowj, diffIJ, -multiplier);\n }\n }\n lambda -= ((this.lambda - this.dlambda) / (this.cycles - 1.0));\n ;\n if (lambda < this.dlambda)\n break;\n }\n return coordinates;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3BlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFDTCwwQkFBMEIsRUFDMUIsZ0JBQWdCLEVBQ2hCLFNBQVMsR0FDVixNQUFNLGlEQUFpRCxDQUFDO0FBQ3pELE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxzQ0FBc0MsQ0FBQztBQUUvRCxPQUFPLEVBQUMscUJBQXFCLEVBQUUsYUFBYSxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFFdkU7Ozs7OztHQU1HO0FBQ0gsTUFBYSxPQUFPO0lBZWxCOzs7O09BSUc7SUFDSCxZQUFZLE9BQWlCO1FBQzNCLElBQUksQ0FBQyxLQUFLLEdBQUcsT0FBTyxFQUFFLEtBQUssSUFBSSxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLEVBQUUsTUFBTSxJQUFJLEdBQUcsQ0FBQztRQUNyQyw0Q0FBNEM7UUFDNUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLEVBQUUsTUFBTSxJQUFJLENBQUMsQ0FBQztRQUNuQyw0Q0FBNEM7UUFDNUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLEVBQUUsTUFBTSxJQUFJLEdBQUcsQ0FBQztRQUNyQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sRUFBRSxPQUFPLElBQUksSUFBSSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7UUFDaEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNsQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sRUFBRSxPQUFPLElBQUksS0FBSyxDQUFDO1FBQ3pDLHVDQUF1QztRQUN2QyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsT0FBTyxFQUFFLFFBQVEsSUFBSSwwQkFBMEIsQ0FBQztRQUN4RSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksWUFBWSxF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IFZlY3RvcnMsIERpc3RhbmNlTWV0cmljfSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy90eXBlLWRlY2xhcmF0aW9ucyc7XG5pbXBvcnQge1xuICBjYWxjdWxhdGVFdWNsaWRlYW5EaXN0YW5jZSxcbiAgZmlsbFJhbmRvbU1hdHJpeCxcbiAgdmVjdG9yQWRkLFxufSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy92ZWN0b3Itb3BlcmF0aW9ucyc7XG5pbXBvcnQge3JhbmRvbUludH0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy91dGlscy9zcmMvcmFuZG9tJztcbmltcG9ydCB7S25vd25NZXRyaWNzfSBmcm9tICcuL3R5cGVkLW1ldHJpY3MnO1xuaW1wb3J0IHtEaXN0YW5jZU1hdHJpeFNlcnZpY2UsIGRtTGluZWFySW5kZXh9IGZyb20gJy4vZGlzdGFuY2UtbWF0cml4JztcblxuLyoqXG4gKiBJbXBsZW1lbnRzIHN0b2NoYXN0aWMgcHJveGltaXR5IGVtYmVkZGluZy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgU1BFQmFzZVxuICogQGxpbmsgZG9pOjEwLjEwMTYvUzEwOTMtMzI2MygwMykwMDE1NS00XG4gKi9cbmV4cG9ydCBjbGFzcyBTUEVCYXNlIHtcbiAgcHJvdGVjdGVkIHN0YXRpYyBkaW1lbnNpb24gPSAyO1xuICBwcm90ZWN0ZWQgc3RlcHM6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGN5Y2xlczogbnVtYmVyO1xuICBwcm90ZWN0ZWQgY3V0b2ZmOiBudW1iZXI7XG4gIHByb3RlY3RlZCBsYW1iZGE6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGRsYW1iZGE6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGxhbWJkYTI6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGRsYW1iZGEyOiBudW1iZXI7XG4gIHByb3RlY3RlZCBlcHNpbG9uOiBudW1iZXI7XG4gIHByb3RlY3RlZCBkaXN0YW5jZUZ1bmN0aW9uOiBEaXN0YW5jZU1ldHJpYztcbiAgcHJvdGVjdGVkIGRpc3RhbmNlRnVuY3Rpb25OYW1lOiBLbm93bk1ldHJpY3M7XG4gIGRpc3RhbmNlOiBGbG9hdDMyQXJyYXk7XG4gIHByb3RlY3RlZCBkbUluZGV4RnVuY3Q/OiAoaTogbnVtYmVyLCBqOiBudW1iZXIpID0+IG51bWJlcjtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBTUEVCYXNlLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IFtvcHRpb25zXSBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIGNvbnN0cnVjdG9yLlxuICAgKiBAbWVtYmVyb2YgU1BFQmFzZVxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9ucz86IE9wdGlvbnMpIHtcbiAgICB0aGlzLnN0ZXBzID0gb3B0aW9ucz8uc3RlcHMgPz8gMDtcbiAgICB0aGlzLmN5Y2xlcyA9IG9wdGlvbnM/LmN5Y2xlcyA/PyAxZTY7XG4gICAgLy8gU2VsZWN0IGEgY3V0b2ZmIGRpc3RhbmNlIHtjdXRvZmZ9IGFuZCAuLi5cbiAgICB0aGlzLmN1dG9mZiA9IG9wdGlvbnM/LmN1dG9mZiA/PyAwO1xuICAgIC8vIC4uLiBhbiBpbml0aWFsIGxlYXJuaW5nIHJhdGUge2xhbWJkYX0gPiAwXG4gICAgdGhpcy5sYW1iZGEgPSBvcHRpb25zPy5sYW1iZGEgPz8gMi4wO1xuICAgIHRoaXMuZGxhbWJkYSA9IG9wdGlvbnM/LmRsYW1iZGEgPz8gMC4wMTtcbiAgICB0aGlzLmxhbWJkYTIgPSB0aGlzLmxhbWJkYSAvIDIuO1xuICAgIHRoaXMuZGxhbWJkYTIgPSB0aGlzLmRsYW1iZGEgLyAyLjtcbiAgICB0aGlzLmVwc2lsb24gPSBvcHRpb25zPy5lcHNpbG9uID8/IDFlLTEwO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBicmFjZS1zdHlsZVxuICAgIHRoaXMuZGlzdGFuY2VGdW5jdGlvbiA9IG9wdGlvbnM/LmRpc3RhbmNlID8/IGNhbGN1bGF0ZUV1Y2xpZGVhbkRpc3RhbmNlO1xuICAgIHRoaXMuZGlzdGFuY2UgPSBuZXcgRmxvYXQzMkFycmF5KCk7XG4gICAgdGhpcy5kaXN0YW5jZUZ1bmN0aW9uTmFtZSA9IG9wdGlvbnM/LmRpc3RhbmNlRnVuY3Rpb25OYW1lITtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplcyBkaXN0YW5jZSBtYXRyaXguXG4gICAqXG4gICAqIEBwYXJhbSB7VmVjdG9yc30gdmVjdG9ycyBJbnB1dCB2ZWN0b3JzIHRvIGNhbGN1bGF0ZSBkaXN0YW5jZSBiZXR3ZWVuLlxuICAgKiBAbWVtYmVyb2YgU1BFQmFzZVxuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGluaXREaXN0YW5jZSh2ZWN0b3JzOiBWZWN0b3JzKSB7XG4gICAgdGhpcy5kbUluZGV4RnVuY3QgPSBkbUxpbmVhckluZGV4KHZlY3RvcnMubGVuZ3RoKTtcbiAgICBjb25zdCBtYXRyaXhTZXJ2aWNlID0gbmV3IERpc3RhbmNlTWF0cml4U2VydmljZSh0cnVlLCBmYWxzZSk7XG4gICAgdGhpcy5kaXN0YW5jZSA9IGF3YWl0IG1hdHJpeFNlcnZpY2UuY2FsYyh2ZWN0b3JzLCB0aGlzLmRpc3RhbmNlRnVuY3Rpb25OYW1lKTtcbiAgICBtYXRyaXhTZXJ2aWNlLnRlcm1pbmF0ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgZGlzdGFuY2UgYmV0d2VlbiB0aGUgdHdvIHZlY3RvcnMgZ2l2ZW4uXG4gICAqXG4gICAqIEBwYXJhbSB7VmVjdG9yc30gdmVjdG9ycyBTZXQgb2YgdmVjdG9ycyB0byBjYWxjdWxhdGUgZGlzdGFuY2VzIGJldHdlZW4uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleDEgSW5kZXggb2YgdGhlIGZpcnN0IHZlY3RvciBvZiB0aGUgcGFpci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4MiBJbmRleCBvZiB0aGUgc2Vjb25kIHZlY3RvciBvZiB0aGUgcGFpci5cbiAgICogQHJldHVybiB7bnVtYmVyfSBEaXN0YW5jZSBiZXR3ZWVuIHRoZXNlIHR3byB2ZWN0b3JzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGNhbGNEaXN0YW5jZSh2ZWN0b3JzOiBWZWN0b3JzLCBpbmRleDE6IG51bWJlciwgaW5kZXgyOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmRpc3RhbmNlW3RoaXMuZG1JbmRleEZ1bmN0IShpbmRleDEsIGluZGV4MildO1xuICB9XG5cbiAgLyoqXG4gICAqIEVtYmVkcyB0aGUgdmVjdG9ycyBnaXZlbiBpbnRvIGEgdHdvLWRpbWVuc2lvbmFsIHNwYWNlLlxuICAgKlxuICAgKiBAcGFyYW0ge1ZlY3RvcnN9IHZlY3RvcnMgRC1kaW1lbnNpb25hbCBjb29yZGluYXRlcy5cbiAgICogQHJldHVybiB7Q29vcmRpbmF0ZXN9IFNQRSBjb29yZGluYXRlcyBpbiBEIHNwYWNlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIGVtYmVkKHZlY3RvcnM6IFZlY3RvcnMpOiBQcm9taXNlPENvb3JkaW5hdGVzPiB7XG4gICAgY29uc3Qgbkl0ZW1zID0gdmVjdG9ycy5sZW5ndGg7XG4gICAgY29uc3QgYXJlYVdpZHRoID0gNDA7XG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgRC1kaW1lbnNpb25hbCBjb29yZGluYXRlcyBvZiB0aGUgTiBwb2ludHMuXG4gICAgY29uc3QgY29vcmRpbmF0ZXMgPSBmaWxsUmFuZG9tTWF0cml4KG5JdGVtcywgU1BFQmFzZS5kaW1lbnNpb24sIGFyZWFXaWR0aCk7XG5cbiAgICBsZXQgbGFtYmRhMiA9IHRoaXMubGFtYmRhMjtcblxuICAgIGlmICh0aGlzLnN0ZXBzID09PSAwKVxuICAgICAgdGhpcy5zdGVwcyA9IHZlY3RvcnMubGVuZ3RoIC0gMTtcblxuXG4gICAgYXdhaXQgdGhpcy5pbml0RGlzdGFuY2UodmVjdG9ycyk7XG5cbiAgICBmb3IgKGxldCBjeWNsZSA9IDA7IGN5Y2xlIDwgdGhpcy5jeWNsZXM7ICsrY3ljbGUpIHtcbiAgICAgIGZvciAobGV0IHN0ZXAgPSAwOyBzdGVwIDwgdGhpcy5zdGVwczsgKytzdGVwKSB7XG4gICAgICAgIC8vIFNlbGVjdCB0d28gcG9pbnRzLCBpIGFuZCBqLCBhdCByYW5kb20sIC4uLlxuICAgICAgICBjb25zdCBpID0gcmFuZG9tSW50KG5JdGVtcyk7XG4gICAgICAgIGxldCBqID0gcmFuZG9tSW50KG5JdGVtcyk7XG4gICAgICAgIHdoaWxlIChpID09IGopIGogPSByYW5kb21JbnQobkl0ZW1zKTtcblxuICAgICAgICBjb25zdCByb3dpID0gY29vcmRpbmF0ZXNbaV07XG4gICAgICAgIGNvbnN0IHJvd2ogPSBjb29yZGluYXRlc1tqXTtcblxuICAgICAgICAvLyAuLi4gcmV0cmlldmUgKG9yIGV2YWx1YXRlKSB0aGVpciBwcm94aW1pdHkgaW4gdGhlIGlucHV0IHNwYWNlLCByaWogYW5kIC4uLlxuICAgICAgICBjb25zdCByID0gdGhpcy5jYWxjRGlzdGFuY2UodmVjdG9ycywgaSwgaik7XG4gICAgICAgIC8vIC4uLiBjb21wdXRlIHRoZWlyIEV1Y2xpZGVhbiBkaXN0YW5jZSBvbiB0aGUgRC1kaW1lbnNpb25hbCBtYXAsIGRpai5cbiAgICAgICAgY29uc3QgZCA9IGNhbGN1bGF0ZUV1Y2xpZGVhbkRpc3RhbmNlKHJvd2ksIHJvd2opO1xuXG4gICAgICAgIC8vIElmIHJpaiA8PSByYywgb3IgaWYgcmlqID4gcmMgYW5kIGRpaiA8IHJpaiAuLi5cbiAgICAgICAgaWYgKCh0aGlzLmN1dG9mZiA9PSAwKSB8fCAociA8PSB0aGlzLmN1dG9mZikgfHwgKGQgPCByKSkge1xuICAgICAgICAgIGNvbnN0IG11bHRpcGxpZXIgPSBsYW1iZGEyICogKHIgLSBkKSAvIChkICsgdGhpcy5lcHNpbG9uKTtcbiAgICAgICAgICAvLyAuLi4gdXBkYXRlIHRoZSBjb29yZGluYXRlcyB4aSBhbmQgeGouXG4gICAgICAgICAgY29uc3QgZGlmZklKID0gdmVjdG9yQWRkKHJvd2ksIHJvd2osIC0xKTtcbiAgICAgICAgICBjb29yZGluYXRlc1tpXSA9IHZlY3RvckFkZChyb3dpLCBkaWZmSUosIG11bHRpcGxpZXIpO1xuICAgICAgICAgIGNvb3JkaW5hdGVzW2pdID0gdmVjdG9yQWRkKHJvd2osIGRpZmZJSiwgLW11bHRpcGxpZXIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBEZWNyZWFzZSB0aGUgbGVhcm5pbmcgcmF0ZSB7bGFtYmRhfSBieSBhIHByZXNjcmliZWQge2RsYW1iZGF9LlxuICAgICAgbGFtYmRhMiAtPSB0aGlzLmRsYW1iZGEyO1xuICAgICAgaWYgKGxhbWJkYTIgPD0gMC4pXG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gY29vcmRpbmF0ZXM7XG4gIH1cbn1cblxuLyoqXG4gKiBJbXBsZW1lbnRzIG1vZGlmaWVkIHN0b2NoYXN0aWMgcHJveGltaXR5IGVtYmVkZGluZy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgUFNQRUJhc2VcbiAqIEBsaW5rIGRvaToxMC4xMDE2L1MxMDkzLTMyNjMoMDMpMDAxNTUtNFxuICovXG5leHBvcnQgY2xhc3MgUFNQRUJhc2UgZXh0ZW5kcyBTUEVCYXNlIHtcbiAgLyoqXG4gICAqIEVtYmVkcyB0aGUgdmVjdG9ycyBnaXZlbiBpbnRvIGEgdHdvLWRpbWVuc2lvbmFsIHNwYWNlIHVzaW5nIGEgbW9kaWZpZWQgdXBkYXRlIHJ1bGUuXG4gICAqXG4gICAqIEBwYXJhbSB7VmVjdG9yc30gdmVjdG9ycyBELWRpbWVuc2lvbmFsIGNvb3JkaW5hdGVzLlxuICAgKiBAcmV0dXJuIHtDb29yZGluYXRlc30gU1BFIGNvb3JkaW5hdGVzIGluIEQgc3BhY2UuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZW1iZWQodmVjdG9yczogVmVjdG9ycyk6IFByb21pc2U8Q29vcmRpbmF0ZXM+IHtcbiAgICBjb25zdCBuSXRlbXMgPSB2ZWN0b3JzLmxlbmd0aDtcbiAgICBjb25zdCBhcmVhV2lkdGggPSA0MDtcbiAgICAvLyAgSW5pdGlhbGl6ZSB0aGUgRC1kaW1lbnNpb25hbCBjb29yZGluYXRlcyBvZiB0aGUgTiBwb2ludHMuXG4gICAgY29uc3QgY29vcmRpbmF0ZXMgPSBmaWxsUmFuZG9tTWF0cml4KG5JdGVtcywgUFNQRUJhc2UuZGltZW5zaW9uLCBhcmVhV2lkdGgpO1xuICAgIGxldCBsYW1iZGEgPSB0aGlzLmxhbWJkYTtcblxuICAgIGF3YWl0IHRoaXMuaW5pdERpc3RhbmNlKHZlY3RvcnMpO1xuXG4gICAgZm9yIChsZXQgY3ljbGUgPSAwOyBjeWNsZSA8IHRoaXMuY3ljbGVzOyArK2N5Y2xlKSB7XG4gICAgICAvLyBTZWxlY3QgYSBwb2ludCwgaSwgYXQgcmFuZG9tIChwaXZvdCkuXG4gICAgICBjb25zdCBpOiBudW1iZXIgPSByYW5kb21JbnQobkl0ZW1zKTtcbiAgICAgIGNvbnN0IHJvd2kgPSBjb29yZGluYXRlc1tpXTtcblxuICAgICAgLy8gRm9yIGV2ZXJ5IHBvaW50IGogIT0gaSAuLi5cbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbkl0ZW1zOyArK2opIHtcbiAgICAgICAgaWYgKGkgPT0gaikgY29udGludWU7XG4gICAgICAgIGNvbnN0IHJvd2ogPSBjb29yZGluYXRlc1tqXTtcbiAgICAgICAgLy8gLi4uIHJldHJpZXZlIChvciBldmFsdWF0ZSkgaXRzIHByb3hpbWl0eSB0byBpIGluIHRoZSBpbnB1dCBzcGFjZSwgcmlqIC4uLlxuICAgICAgICBjb25zdCByID0gdGhpcy5jYWxjRGlzdGFuY2UodmVjdG9ycywgaSwgaik7XG4gICAgICAgIC8vIC4uLiBhbmQgY29tcHV0ZSB0aGVpciBFdWNsaWRlYW4gZGlzdGFuY2Ugb24gdGhlIEQtZGltZW5zaW9uYWwgbWFwLCBkaWouXG4gICAgICAgIGNvbnN0IGQgPSBjYWxjdWxhdGVFdWNsaWRlYW5EaXN0YW5jZShyb3dpLCByb3dqKTtcbiAgICAgICAgLy8gSWYgcmlqIDw9IHJjLCBvciBpZiByaWogPiByYyBhbmQgZGlqIDwgcmlqIC4uLlxuICAgICAgICBpZiAoKHRoaXMuY3V0b2ZmID09IDApIHx8IChyIDw9IHRoaXMuY3V0b2ZmKSB8fCAoZCA8IHIpKSB7XG4gICAgICAgICAgY29uc3QgbXVsdGlwbGllciA9IGxhbWJkYSAqIChyIC0gZCkgLyAoZCArIHRoaXMuZXBzaWxvbik7XG4gICAgICAgICAgY29uc3QgZGlmZklKID0gdmVjdG9yQWRkKHJvd2ksIHJvd2osIC0xKTtcbiAgICAgICAgICAvLyAuLi4gdXBkYXRlIHRoZSBjb29yZGluYXRlcyB4ai5cbiAgICAgICAgICBjb29yZGluYXRlc1tqXSA9IHZlY3RvckFkZChyb3dqLCBkaWZmSUosIC1tdWx0aXBsaWVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGVjcmVhc2UgdGhlIGxlYXJuaW5nIHJhdGUge2xhbWJkYX0gYnkgYSBwcmVzY3JpYmVkIHtkbGFtYmRhfS5cbiAgICAgIGxhbWJkYSAtPSB0aGlzLmRsYW1iZGE7XG4gICAgICBpZiAobGFtYmRhIDw9IDAuKVxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIGNvb3JkaW5hdGVzO1xuICB9XG59XG5cbi8qKlxuICogSW1wbGVtZW50cyBtb2RpZmllZCBzdG9jaGFzdGljIHByb3hpbWl0eSBlbWJlZGRpbmcuXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIE9yaWdpbmFsU1BFXG4gKiBAbGluayBkb2k6MTAuMTAwMi9qY2MuMTAyMzRcbiAqL1xuZXhwb3J0IGNsYXNzIE9yaWdpbmFsU1BFIGV4dGVuZHMgU1BFQmFzZSB7XG4gIC8qKlxuICAgKiBFbWJlZHMgdGhlIHZlY3RvcnMgZ2l2ZW4gaW50byBhIHR3by1kaW1lbnNpb25hbCBzcGFjZSB1c2luZyBhIG1vZGlmaWVkIHVwZGF0ZSBydWxlLlxuICAgKlxuICAgKiBAcGFyYW0ge1ZlY3RvcnN9IHZlY3RvcnMgRC1kaW1lbnNpb25hbCBjb29yZGluYXRlcy5cbiAgICogQHJldHVybiB7Q29vcmRpbmF0ZXN9IFNQRSBjb29yZGluYXRlcyBpbiBEIHNwYWNlLlxuICAgKi9cbiAgcHJvdGVjdGVkIHJhZGl1c1BlcmNlbnQ6IG51bWJlcjtcbiAgcHJvdGVjdGVkIG1heERpc3RhbmNlOiBudW1iZXI7XG4gIHByb3RlY3RlZCBtYXhEaXN0YW5jZVN0ZXBzOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9ucz86IE9wdGlvbnMpIHtcbiAgICBzdXBlcihvcHRpb25zKTtcbiAgICB0aGlzLmN5Y2xlcyA9IG9wdGlvbnM/LmN5Y2xlcyA/PyAxZTM7XG4gICAgdGhpcy5zdGVwcyA9IG9wdGlvbnM/LnN0ZXBzID8/IDEwMDAwMDtcbiAgICB0aGlzLnJhZGl1c1BlcmNlbnQgPSBvcHRpb25zPy5yYWRpdXNQZXJjZW50ID8/IDEuMDtcbiAgICB0aGlzLm1heERpc3RhbmNlID0gb3B0aW9ucz8ubWF4RGlzdGFuY2UgPz8gbnVsbDtcbiAgICB0aGlzLm1heERpc3RhbmNlU3RlcHMgPSBvcHRpb25zPy5tYXhEaXN0YW5jZVN0ZXBzID8/IG51bGw7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZW1iZWQodmVjdG9yczogVmVjdG9ycyk6IFByb21pc2U8Q29vcmRpbmF0ZXM+IHtcbiAgICBjb25zdCBuSXRlbXMgPSB2ZWN0b3JzLmxlbmd0aDtcbiAgICBjb25zdCBhcmVhV2lkdGggPSA0MDtcbiAgICAvLyBJbml0aWFsaXplIHRoZSBELWRpbWVuc2lvbmFsIGNvb3JkaW5hdGVzIG9mIHRoZSBOIHBvaW50cy5cbiAgICBjb25zdCBjb29yZGluYXRlcyA9IGZpbGxSYW5kb21NYXRyaXgobkl0ZW1zLCBPcmlnaW5hbFNQRS5kaW1lbnNpb24sIGFyZWFXaWR0aCk7XG5cbiAgICBhd2FpdCB0aGlzLmluaXREaXN0YW5jZSh2ZWN0b3JzKTtcblxuICAgIGlmICh0aGlzLm1heERpc3RhbmNlU3RlcHMgPT09IG51bGwpXG4gICAgICB0aGlzLm1heERpc3RhbmNlU3RlcHMgPSBuSXRlbXMgKiBNYXRoLmZsb29yKChuSXRlbXMgLSAxKSAvIDIpO1xuXG4gICAgaWYgKHRoaXMubWF4RGlzdGFuY2UgPT09IG51bGwpIHtcbiAgICAgIHRoaXMubWF4RGlzdGFuY2UgPSAtMWUzNztcbiAgICAgIGZvciAobGV0IG4gPSAwOyBuIDwgdGhpcy5tYXhEaXN0YW5jZVN0ZXBzOyBuKyspIHtcbiAgICAgICAgY29uc3QgaSA9IHJhbmRvbUludChuSXRlbXMpOyBsZXQgaiA9IHJhbmRvbUludChuSXRlbXMpO1xuICAgICAgICB3aGlsZSAoaSA9PSBqKSBqID0gcmFuZG9tSW50KG5JdGVtcyk7XG5cbiAgICAgICAgY29uc3QgZCA9IHRoaXMuY2FsY0Rpc3RhbmNlKHZlY3RvcnMsIGksIGopO1xuICAgICAgICBpZiAoZCA+IHRoaXMubWF4RGlzdGFuY2UpXG4gICAgICAgICAgdGhpcy5tYXhEaXN0YW5jZSA9IGQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IGxhbWJkYSA9IHRoaXMubGFtYmRhO1xuICAgIGNvbnN0IHJhZGl1cyA9ICh0aGlzLnJhZGl1c1BlcmNlbnQgPT0gMC4wKSA/IHRoaXMubWF4RGlzdGFuY2UgOiB0aGlzLm1heERpc3RhbmNlICogdGhpcy5yYWRpdXNQZXJjZW50O1xuXG4gICAgZm9yIChsZXQgY3ljbGUgPSAwOyBjeWNsZSA8IHRoaXMuY3ljbGVzOyArK2N5Y2xlKSB7XG4gICAgICBmb3IgKGxldCBzdGVwID0gMDsgc3RlcCA8IHRoaXMuc3RlcHM7ICsrc3RlcCkge1xuICAgICAgICAvLyBTZWxlY3QgdHdvIHBvaW50cywgaSBhbmQgaiwgYXQgcmFuZG9tLCAuLi5cbiAgICAgICAgY29uc3QgaSA9IHJhbmRvbUludChuSXRlbXMpO1xuICAgICAgICBsZXQgaiA9IHJhbmRvbUludChuSXRlbXMpO1xuICAgICAgICB3aGlsZSAoaSA9PSBqKSBqID0gcmFuZG9tSW50KG5JdGVtcyk7XG5cbiAgICAgICAgY29uc3Qgcm93aSA9IGNvb3JkaW5hdGVzW2ldO1xuICAgICAgICBjb25zdCByb3dqID0gY29vcmRpbmF0ZXNbal07XG5cbiAgICAgICAgLy8gcmV0cmlldmUgKG9yIGV2YWx1YXRlKSB0aGVpciBwcm94aW1pdHkgaW4gdGhlIGlucHV0IHNwYWNlLCByaWogYW5kIC4uLlxuICAgICAgICBjb25zdCByID0gdGhpcy5jYWxjRGlzdGFuY2UodmVjdG9ycywgaSwgaik7XG4gICAgICAgIC8vIGNvbXB1dGUgdGhlaXIgRXVjbGlkZWFuIGRpc3RhbmNlIG9uIHRoZSBELWRpbWVuc2lvbmFsIG1hcCwgZGlqLlxuICAgICAgICBjb25zdCBkID0gY2FsY3VsYXRlRXVjbGlkZWFuRGlzdGFuY2Uocm93aSwgcm93aik7XG5cbiAgICAgICAgaWYgKChyIDw9IHJhZGl1cykgfHwgKGQgPCByKSkge1xuICAgICAgICAgIGNvbnN0IG11bHRpcGxpZXIgPSBsYW1iZGEgKiAwLjUgKiAociAtIGQpIC8gKGQgKyB0aGlzLmVwc2lsb24pO1xuICAgICAgICAgIC8vIC4uLiB1cGRhdGUgdGhlIGNvb3JkaW5hdGVzIHhpIGFuZCB4ai5cbiAgICAgICAgICBjb25zdCBkaWZmSUogPSB2ZWN0b3JBZGQocm93aSwgcm93aiwgLTEpO1xuICAgICAgICAgIGNvb3JkaW5hdGVzW2ldID0gdmVjdG9yQWRkKHJvd2ksIGRpZmZJSiwgbXVsdGlwbGllcik7XG4gICAgICAgICAgY29vcmRpbmF0ZXNbal0gPSB2ZWN0b3JBZGQocm93aiwgZGlmZklKLCAtbXVsdGlwbGllcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGxhbWJkYSAtPSAoKHRoaXMubGFtYmRhIC0gdGhpcy5kbGFtYmRhKSAvICh0aGlzLmN5Y2xlcyAtIDEuMCkpOyA7XG4gICAgICBpZiAobGFtYmRhIDwgdGhpcy5kbGFtYmRhKVxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIGNvb3JkaW5hdGVzO1xuICB9XG59XG4iXX0=","export var StringMetricsNames;\n(function (StringMetricsNames) {\n StringMetricsNames[\"Levenshtein\"] = \"Levenshtein\";\n StringMetricsNames[\"JaroWinkler\"] = \"Jaro-Winkler\";\n StringMetricsNames[\"Manhattan\"] = \"Manhattan\";\n})(StringMetricsNames || (StringMetricsNames = {}));\nexport var VectorMetricsNames;\n(function (VectorMetricsNames) {\n VectorMetricsNames[\"Euclidean\"] = \"Euclidean\";\n})(VectorMetricsNames || (VectorMetricsNames = {}));\nexport var BitArrayMetricsNames;\n(function (BitArrayMetricsNames) {\n BitArrayMetricsNames[\"Tanimoto\"] = \"Tanimoto\";\n BitArrayMetricsNames[\"Dice\"] = \"Dice\";\n BitArrayMetricsNames[\"Asymmetric\"] = \"Asymmetric\";\n BitArrayMetricsNames[\"BraunBlanquet\"] = \"Braun-Blanquet\";\n BitArrayMetricsNames[\"Cosine\"] = \"Cosine\";\n BitArrayMetricsNames[\"Kulczynski\"] = \"Kulczynski\";\n BitArrayMetricsNames[\"McConnaughey\"] = \"Mc-Connaughey\";\n BitArrayMetricsNames[\"RogotGoldberg\"] = \"Rogot-Goldberg\";\n BitArrayMetricsNames[\"Russel\"] = \"Russel\";\n BitArrayMetricsNames[\"Sokal\"] = \"Sokal\";\n BitArrayMetricsNames[\"Hamming\"] = \"Hamming\";\n BitArrayMetricsNames[\"Euclidean\"] = \"Euclidean\";\n})(BitArrayMetricsNames || (BitArrayMetricsNames = {}));\nexport var IntArrayMetricsNames;\n(function (IntArrayMetricsNames) {\n IntArrayMetricsNames[\"TanimotoIntArray\"] = \"TanimotoIntArray\";\n})(IntArrayMetricsNames || (IntArrayMetricsNames = {}));\nexport var DistanceMetricsSubjects;\n(function (DistanceMetricsSubjects) {\n DistanceMetricsSubjects[\"Vector\"] = \"Vector\";\n DistanceMetricsSubjects[\"String\"] = \"String\";\n DistanceMetricsSubjects[\"BitArray\"] = \"BitArray\";\n DistanceMetricsSubjects[\"MacroMolecule\"] = \"MacroMolecule\";\n DistanceMetricsSubjects[\"Number\"] = \"Number\";\n DistanceMetricsSubjects[\"IntArray\"] = \"IntArray\";\n})(DistanceMetricsSubjects || (DistanceMetricsSubjects = {}));\nexport var NumberMetricsNames;\n(function (NumberMetricsNames) {\n NumberMetricsNames[\"Difference\"] = \"Difference\";\n})(NumberMetricsNames || (NumberMetricsNames = {}));\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY29uc3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBTixJQUFZLGtCQUlUO0FBSkgsV0FBWSxrQkFBa0I7SUFDMUIsaURBQTJCLENBQUE7SUFDM0Isa0RBQTRCLENBQUE7SUFDNUIsNkNBQXVCLENBQUE7QUFDekIsQ0FBQyxFQUpTLGtCQUFrQixLQUFsQixrQkFBa0IsUUFJM0I7QUFFSCxNQUFNLENBQU4sSUFBWSxrQkFFVDtBQUZILFdBQVksa0JBQWtCO0lBQzFCLDZDQUF1QixDQUFBO0FBQ3pCLENBQUMsRUFGUyxrQkFBa0IsS0FBbEIsa0JBQWtCLFFBRTNCO0FBRUgsTUFBTSxDQUFOLElBQVksb0JBYVQ7QUFiSCxXQUFZLG9CQUFvQjtJQUM1Qiw2Q0FBcUIsQ0FBQTtJQUNyQixxQ0FBYSxDQUFBO0lBQ2IsaURBQXlCLENBQUE7SUFDekIsd0RBQWdDLENBQUE7SUFDaEMseUNBQWlCLENBQUE7SUFDakIsaURBQXlCLENBQUE7SUFDekIsc0RBQThCLENBQUE7SUFDOUIsd0RBQWdDLENBQUE7SUFDaEMseUNBQWlCLENBQUE7SUFDakIsdUNBQWUsQ0FBQTtJQUNmLDJDQUFtQixDQUFBO0lBQ25CLCtDQUF1QixDQUFBO0FBQ3pCLENBQUMsRUFiUyxvQkFBb0IsS0FBcEIsb0JBQW9CLFFBYTdCO0FBRUgsTUFBTSxDQUFOLElBQVksb0JBRVg7QUFGRCxXQUFZLG9CQUFvQjtJQUM5Qiw2REFBcUMsQ0FBQTtBQUN2QyxDQUFDLEVBRlcsb0JBQW9CLEtBQXBCLG9CQUFvQixRQUUvQjtBQUVELE1BQU0sQ0FBTixJQUFZLHVCQU9UO0FBUEgsV0FBWSx1QkFBdUI7SUFDL0IsNENBQWlCLENBQUE7SUFDakIsNENBQWlCLENBQUE7SUFDakIsZ0RBQXFCLENBQUE7SUFDckIsMERBQStCLENBQUE7SUFDL0IsNENBQWlCLENBQUE7SUFDakIsZ0RBQXFCLENBQUE7QUFDdkIsQ0FBQyxFQVBTLHVCQUF1QixLQUF2Qix1QkFBdUIsUUFPaEM7QUFFSCxNQUFNLENBQU4sSUFBWSxrQkFFWDtBQUZELFdBQVksa0JBQWtCO0lBQzVCLCtDQUF5QixDQUFBO0FBQzNCLENBQUMsRUFGVyxrQkFBa0IsS0FBbEIsa0JBQWtCLFFBRTdCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGVudW0gU3RyaW5nTWV0cmljc05hbWVzIHtcbiAgICBMZXZlbnNodGVpbiA9ICdMZXZlbnNodGVpbicsXG4gICAgSmFyb1dpbmtsZXIgPSAnSmFyby1XaW5rbGVyJyxcbiAgICBNYW5oYXR0YW4gPSAnTWFuaGF0dGFuJyxcbiAgfVxuXG5leHBvcnQgZW51bSBWZWN0b3JNZXRyaWNzTmFtZXMge1xuICAgIEV1Y2xpZGVhbiA9ICdFdWNsaWRlYW4nLFxuICB9XG5cbmV4cG9ydCBlbnVtIEJpdEFycmF5TWV0cmljc05hbWVzIHtcbiAgICBUYW5pbW90byA9ICdUYW5pbW90bycsXG4gICAgRGljZSA9ICdEaWNlJyxcbiAgICBBc3ltbWV0cmljID0gJ0FzeW1tZXRyaWMnLFxuICAgIEJyYXVuQmxhbnF1ZXQgPSAnQnJhdW4tQmxhbnF1ZXQnLFxuICAgIENvc2luZSA9ICdDb3NpbmUnLFxuICAgIEt1bGN6eW5za2kgPSAnS3VsY3p5bnNraScsXG4gICAgTWNDb25uYXVnaGV5ID0gJ01jLUNvbm5hdWdoZXknLFxuICAgIFJvZ290R29sZGJlcmcgPSAnUm9nb3QtR29sZGJlcmcnLFxuICAgIFJ1c3NlbCA9ICdSdXNzZWwnLFxuICAgIFNva2FsID0gJ1Nva2FsJyxcbiAgICBIYW1taW5nID0gJ0hhbW1pbmcnLFxuICAgIEV1Y2xpZGVhbiA9ICdFdWNsaWRlYW4nLFxuICB9XG5cbmV4cG9ydCBlbnVtIEludEFycmF5TWV0cmljc05hbWVzIHtcbiAgVGFuaW1vdG9JbnRBcnJheSA9ICdUYW5pbW90b0ludEFycmF5Jyxcbn1cblxuZXhwb3J0IGVudW0gRGlzdGFuY2VNZXRyaWNzU3ViamVjdHMge1xuICAgIFZlY3RvciA9ICdWZWN0b3InLFxuICAgIFN0cmluZyA9ICdTdHJpbmcnLFxuICAgIEJpdEFycmF5ID0gJ0JpdEFycmF5JyxcbiAgICBNYWNyb01vbGVjdWxlID0gJ01hY3JvTW9sZWN1bGUnLFxuICAgIE51bWJlciA9ICdOdW1iZXInLFxuICAgIEludEFycmF5ID0gJ0ludEFycmF5JyxcbiAgfVxuXG5leHBvcnQgZW51bSBOdW1iZXJNZXRyaWNzTmFtZXMge1xuICBEaWZmZXJlbmNlID0gJ0RpZmZlcmVuY2UnLFxufVxuXG4iXX0=","import BitArray from '@datagrok-libraries/utils/src/bit-array';\nimport { BitArrayMetricsNames } from './typed-metrics/consts';\nimport { MmDistanceFunctionsNames } from './macromolecule-distance-functions';\nexport const similarityMetric = {\n [BitArrayMetricsNames.Tanimoto]: tanimotoSimilarity,\n [BitArrayMetricsNames.Dice]: diceSimilarity,\n [BitArrayMetricsNames.Asymmetric]: asymmetricSimilarity,\n [BitArrayMetricsNames.BraunBlanquet]: braunBlanquetSimilarity,\n [BitArrayMetricsNames.Cosine]: cosineSimilarity,\n [BitArrayMetricsNames.Kulczynski]: kulczynskiSimilarity,\n [BitArrayMetricsNames.McConnaughey]: mcConnaugheySimilarity,\n [BitArrayMetricsNames.RogotGoldberg]: rogotGoldbergSimilarity,\n [BitArrayMetricsNames.Russel]: russelSimilarity,\n [BitArrayMetricsNames.Sokal]: sokalSimilarity,\n [BitArrayMetricsNames.Hamming]: hammingSimilarity,\n [BitArrayMetricsNames.Euclidean]: euclideanSimilarity,\n};\nexport const distanceMetrics = {\n [BitArrayMetricsNames.Tanimoto]: tanimotoDistance,\n [BitArrayMetricsNames.Dice]: diceDistance,\n [BitArrayMetricsNames.Asymmetric]: asymmetricDistance,\n [BitArrayMetricsNames.BraunBlanquet]: braunBlanquetDistance,\n [BitArrayMetricsNames.Cosine]: cosineDistance,\n [BitArrayMetricsNames.Kulczynski]: kulczynskiDistance,\n [BitArrayMetricsNames.McConnaughey]: mcConnaugheyDistance,\n [BitArrayMetricsNames.RogotGoldberg]: rogotGoldbergDistance,\n [BitArrayMetricsNames.Russel]: russelDistance,\n [BitArrayMetricsNames.Sokal]: sokalDistance,\n [BitArrayMetricsNames.Hamming]: hammingDistance,\n [BitArrayMetricsNames.Euclidean]: euclideanDistance,\n};\nexport const CHEM_SIMILARITY_METRICS = [\n BitArrayMetricsNames.Tanimoto,\n BitArrayMetricsNames.Dice,\n BitArrayMetricsNames.Cosine\n];\nexport const SEQ_SPACE_SIMILARITY_METRICS = [\n BitArrayMetricsNames.Tanimoto,\n BitArrayMetricsNames.Asymmetric,\n BitArrayMetricsNames.Cosine,\n BitArrayMetricsNames.Sokal\n];\nexport const MACROMOLECULE_SIMILARITY_METRICS = [\n MmDistanceFunctionsNames.HAMMING,\n MmDistanceFunctionsNames.LEVENSHTEIN,\n MmDistanceFunctionsNames.MONOMER_CHEMICAL_DISTANCE,\n MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH\n];\nexport function tanimotoSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n if (total == 0)\n return 1.0;\n const common = x.andWithCountBits(y, true);\n return common / (total - common);\n}\nexport function tanimotoDistance(x, y) {\n return getDistanceFromSimilarity(tanimotoSimilarity(x, y));\n}\nexport function tanimotoDistanceIntArray(x, y) {\n const xb = new BitArray(x, x.length * 32);\n const yb = new BitArray(y, y.length * 32);\n return getDistanceFromSimilarity(tanimotoSimilarity(xb, yb));\n}\nexport function diceSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n if (total == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return 2 * common / total;\n}\nexport function diceDistance(x, y) {\n return getDistanceFromSimilarity(diceSimilarity(x, y));\n}\nexport function cosineSimilarity(x, y) {\n const total = x.trueCount() * y.trueCount();\n if (total == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / Math.sqrt(total);\n}\nexport function cosineDistance(x, y) {\n return getDistanceFromSimilarity(cosineSimilarity(x, y));\n}\nexport function euclideanSimilarity(x, y) {\n return getSimilarityFromDistance(euclideanDistance(x, y));\n}\nexport function euclideanDistance(x, y) {\n return Math.sqrt(x.trueCount() + y.trueCount() - 2 * x.andWithCountBits(y, true));\n}\nexport function hammingSimilarity(x, y) {\n return getSimilarityFromDistance(hammingDistance(x, y));\n}\nexport function hammingDistance(x, y) {\n return x.trueCount() + y.trueCount() - 2 * x.andWithCountBits(y, true);\n}\nexport function sokalSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n const common = x.andWithCountBits(y, true);\n return common / (2 * total - 3 * common);\n}\nexport function sokalDistance(x, y) {\n return getDistanceFromSimilarity(sokalSimilarity(x, y));\n}\nexport function kulczynskiSimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n const totalProd = x.trueCount() * y.trueCount();\n if (totalProd == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return (common * total) / (2 * totalProd);\n}\nexport function kulczynskiDistance(x, y) {\n return getDistanceFromSimilarity(kulczynskiSimilarity(x, y));\n}\nexport function mcConnaugheySimilarity(x, y) {\n const total = x.trueCount() + y.trueCount();\n const totalProd = x.trueCount() * y.trueCount();\n if (totalProd == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return (common * total - totalProd) / totalProd;\n}\nexport function mcConnaugheyDistance(x, y) {\n return getDistanceFromSimilarity(mcConnaugheySimilarity(x, y));\n}\nexport function asymmetricSimilarity(x, y) {\n const min = Math.min(x.trueCount(), y.trueCount());\n if (min == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / min;\n}\nexport function asymmetricDistance(x, y) {\n return getDistanceFromSimilarity(asymmetricSimilarity(x, y));\n}\nexport function braunBlanquetSimilarity(x, y) {\n const max = Math.max(x.trueCount(), y.trueCount());\n if (max == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / max;\n}\nexport function braunBlanquetDistance(x, y) {\n return getDistanceFromSimilarity(braunBlanquetSimilarity(x, y));\n}\nexport function russelSimilarity(x, y) {\n if (x.length == 0)\n return 0.0;\n const common = x.andWithCountBits(y, true);\n return common / x.length;\n}\nexport function russelDistance(x, y) {\n return getDistanceFromSimilarity(russelSimilarity(x, y));\n}\nexport function rogotGoldbergSimilarity(x, y) {\n const common = x.andWithCountBits(y, true);\n const total = x.countBits(true) + y.countBits(true);\n const len = x.length;\n const diff = len - total + common;\n if ((common == len) || (diff == len))\n return 1.0;\n else\n return common / total + diff / (2 * len - total);\n}\nexport function rogotGoldbergDistance(x, y) {\n return getDistanceFromSimilarity(rogotGoldbergSimilarity(x, y));\n}\nexport function getSimilarityFromDistance(distance) {\n return 1 / (1 + distance);\n}\nexport function getDistanceFromSimilarity(similarity) {\n return similarity === 0 ? 3.402823E+38 : (1 / similarity) - 1;\n}\nexport function numericDistance(x, y) {\n return Math.abs(x - y);\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzdGFuY2UtbWV0cmljcy1tZXRob2RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGlzdGFuY2UtbWV0cmljcy1tZXRob2RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sUUFBUSxNQUFNLHlDQUF5QyxDQUFDO0FBQy9ELE9BQU8sRUFBQyxvQkFBb0IsRUFBdUIsTUFBTSx3QkFBd0IsQ0FBQztBQUNsRixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUU5RSxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBNkQ7SUFDeEYsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsRUFBRSxrQkFBa0I7SUFDbkQsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxjQUFjO0lBQzNDLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLEVBQUUsb0JBQW9CO0lBQ3ZELENBQUMsb0JBQW9CLENBQUMsYUFBYSxDQUFDLEVBQUUsdUJBQXVCO0lBQzdELENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLEVBQUUsZ0JBQWdCO0lBQy9DLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLEVBQUUsb0JBQW9CO0lBQ3ZELENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDLEVBQUUsc0JBQXNCO0lBQzNELENBQUMsb0JBQW9CLENBQUMsYUFBYSxDQUFDLEVBQUUsdUJBQXVCO0lBQzdELENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLEVBQUUsZ0JBQWdCO0lBQy9DLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLEVBQUUsZUFBZTtJQUM3QyxDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxFQUFFLGlCQUFpQjtJQUNqRCxDQUFDLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxFQUFFLG1CQUFtQjtDQUN0RCxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUE2RDtJQUN2RixDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxF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QUMsR0FBRyxDQUFDLENBQUM7QUFDaEUsQ0FBQztBQUVELE1BQU0sVUFBVSxlQUFlLENBQUMsQ0FBUyxFQUFFLENBQVM7SUFDbEQsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN6QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEJpdEFycmF5IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL2JpdC1hcnJheSc7XG5pbXBvcnQge0JpdEFycmF5TWV0cmljc05hbWVzLCBJbnRBcnJheU1ldHJpY3NOYW1lc30gZnJvbSAnLi90eXBlZC1tZXRyaWNzL2NvbnN0cyc7XG5pbXBvcnQgeyBNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMgfSBmcm9tICcuL21hY3JvbW9sZWN1bGUtZGlzdGFuY2UtZnVuY3Rpb25zJztcblxuZXhwb3J0IGNvbnN0IHNpbWlsYXJpdHlNZXRyaWM6IHsgW25hbWU6IHN0cmluZ106ICh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpID0+IG51bWJlciB9ID0ge1xuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuVGFuaW1vdG9dOiB0YW5pbW90b1NpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5EaWNlXTogZGljZVNpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Bc3ltbWV0cmljXTogYXN5bW1ldHJpY1NpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5CcmF1bkJsYW5xdWV0XTogYnJhdW5CbGFucXVldFNpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Db3NpbmVdOiBjb3NpbmVTaW1pbGFyaXR5LFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuS3VsY3p5bnNraV06IGt1bGN6eW5za2lTaW1pbGFyaXR5LFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuTWNDb25uYXVnaGV5XTogbWNDb25uYXVnaGV5U2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlJvZ290R29sZGJlcmddOiByb2dvdEdvbGRiZXJnU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlJ1c3NlbF06IHJ1c3NlbFNpbWlsYXJpdHksXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Tb2thbF06IHNva2FsU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkhhbW1pbmddOiBoYW1taW5nU2ltaWxhcml0eSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkV1Y2xpZGVhbl06IGV1Y2xpZGVhblNpbWlsYXJpdHksXG59O1xuXG5leHBvcnQgY29uc3QgZGlzdGFuY2VNZXRyaWNzOiB7IFtuYW1lOiBzdHJpbmddOiAoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KSA9PiBudW1iZXIgfSA9IHtcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlRhbmltb3RvXTogdGFuaW1vdG9EaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkRpY2VdOiBkaWNlRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Bc3ltbWV0cmljXTogYXN5bW1ldHJpY0Rpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQnJhdW5CbGFucXVldF06IGJyYXVuQmxhbnF1ZXREaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkNvc2luZV06IGNvc2luZURpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuS3VsY3p5bnNraV06IGt1bGN6eW5za2lEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLk1jQ29ubmF1Z2hleV06IG1jQ29ubmF1Z2hleURpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuUm9nb3RHb2xkYmVyZ106IHJvZ290R29sZGJlcmdEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlJ1c3NlbF06IHJ1c3NlbERpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuU29rYWxdOiBzb2thbERpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuSGFtbWluZ106IGhhbW1pbmdEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkV1Y2xpZGVhbl06IGV1Y2xpZGVhbkRpc3RhbmNlLFxufTtcblxuZXhwb3J0IGNvbnN0IENIRU1fU0lNSUxBUklUWV9NRVRSSUNTID0gW1xuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90byxcbiAgQml0QXJyYXlNZXRyaWNzTmFtZXMuRGljZSxcbiAgQml0QXJyYXlNZXRyaWNzTmFtZXMuQ29zaW5lXTtcbmV4cG9ydCBjb25zdCBTRVFfU1BBQ0VfU0lNSUxBUklUWV9NRVRSSUNTID0gW1xuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90byxcbiAgQml0QXJyYXlNZXRyaWNzTmFtZXMuQXN5bW1ldHJpYyxcbiAgQml0QXJyYXlNZXRyaWNzTmFtZXMuQ29zaW5lLFxuICBCaXRBcnJheU1ldHJpY3NOYW1lcy5Tb2thbF07XG5leHBvcnQgY29uc3QgTUFDUk9NT0xFQ1VMRV9TSU1JTEFSSVRZX01FVFJJQ1MgPSBbXG4gIE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5IQU1NSU5HLFxuICBNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTEVWRU5TSFRFSU4sXG4gIE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5NT05PTUVSX0NIRU1JQ0FMX0RJU1RBTkNFLFxuICBNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTkVFRExFTUFOTl9XVU5TQ0hcbl07XG5cblxuZXhwb3J0IGZ1bmN0aW9uIHRhbmltb3RvU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCB0b3RhbCA9IHgudHJ1ZUNvdW50KCkgKyB5LnRydWVDb3VudCgpO1xuICBpZiAodG90YWwgPT0gMCkgcmV0dXJuIDEuMDtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICByZXR1cm4gY29tbW9uIC8gKHRvdGFsIC0gY29tbW9uKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRhbmltb3RvRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkodGFuaW1vdG9TaW1pbGFyaXR5KHgsIHkpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRhbmltb3RvRGlzdGFuY2VJbnRBcnJheSh4OiBVaW50MzJBcnJheSwgeTogVWludDMyQXJyYXkpOiBudW1iZXIge1xuICBjb25zdCB4YiA9IG5ldyBCaXRBcnJheSh4LCB4Lmxlbmd0aCAqIDMyKTtcbiAgY29uc3QgeWIgPSBuZXcgQml0QXJyYXkoeSwgeS5sZW5ndGggKiAzMik7XG4gIHJldHVybiBnZXREaXN0YW5jZUZyb21TaW1pbGFyaXR5KHRhbmltb3RvU2ltaWxhcml0eSh4YiwgeWIpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRpY2VTaW1pbGFyaXR5KHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIGNvbnN0IHRvdGFsID0geC50cnVlQ291bnQoKSArIHkudHJ1ZUNvdW50KCk7XG4gIGlmICh0b3RhbCA9PSAwKSByZXR1cm4gMC4wO1xuICBjb25zdCBjb21tb24gPSB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG4gIHJldHVybiAyICogY29tbW9uIC8gdG90YWw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkaWNlRGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkoZGljZVNpbWlsYXJpdHkoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29zaW5lU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCB0b3RhbCA9IHgudHJ1ZUNvdW50KCkgKiB5LnRydWVDb3VudCgpO1xuICBpZiAodG90YWwgPT0gMCkgcmV0dXJuIDAuMDtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICByZXR1cm4gY29tbW9uIC8gTWF0aC5zcXJ0KHRvdGFsKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvc2luZURpc3RhbmNlKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIHJldHVybiBnZXREaXN0YW5jZUZyb21TaW1pbGFyaXR5KGNvc2luZVNpbWlsYXJpdHkoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXVjbGlkZWFuU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0U2ltaWxhcml0eUZyb21EaXN0YW5jZShldWNsaWRlYW5EaXN0YW5jZSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBldWNsaWRlYW5EaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gTWF0aC5zcXJ0KHgudHJ1ZUNvdW50KCkgKyB5LnRydWVDb3VudCgpIC0gMiAqIHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYW1taW5nU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0U2ltaWxhcml0eUZyb21EaXN0YW5jZShoYW1taW5nRGlzdGFuY2UoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFtbWluZ0Rpc3RhbmNlKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIHJldHVybiB4LnRydWVDb3VudCgpICsgeS50cnVlQ291bnQoKSAtIDIgKiB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzb2thbFNpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgY29uc3QgdG90YWwgPSB4LnRydWVDb3VudCgpICsgeS50cnVlQ291bnQoKTtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICByZXR1cm4gY29tbW9uIC8gKDIgKiB0b3RhbCAtIDMgKiBjb21tb24pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc29rYWxEaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0RGlzdGFuY2VGcm9tU2ltaWxhcml0eShzb2thbFNpbWlsYXJpdHkoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24ga3VsY3p5bnNraVNpbWlsYXJpdHkoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgY29uc3QgdG90YWwgPSB4LnRydWVDb3VudCgpICsgeS50cnVlQ291bnQoKTtcbiAgY29uc3QgdG90YWxQcm9kID0geC50cnVlQ291bnQoKSAqIHkudHJ1ZUNvdW50KCk7XG4gIGlmICh0b3RhbFByb2QgPT0gMCkgcmV0dXJuIDAuMDtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICByZXR1cm4gKGNvbW1vbiAqIHRvdGFsKSAvICgyICogdG90YWxQcm9kKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGt1bGN6eW5za2lEaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0RGlzdGFuY2VGcm9tU2ltaWxhcml0eShrdWxjenluc2tpU2ltaWxhcml0eSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtY0Nvbm5hdWdoZXlTaW1pbGFyaXR5KHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIGNvbnN0IHRvdGFsID0geC50cnVlQ291bnQoKSArIHkudHJ1ZUNvdW50KCk7XG4gIGNvbnN0IHRvdGFsUHJvZCA9IHgudHJ1ZUNvdW50KCkgKiB5LnRydWVDb3VudCgpO1xuICBpZiAodG90YWxQcm9kID09IDApIHJldHVybiAwLjA7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgcmV0dXJuIChjb21tb24gKiB0b3RhbCAtIHRvdGFsUHJvZCkgLyB0b3RhbFByb2Q7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtY0Nvbm5hdWdoZXlEaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0RGlzdGFuY2VGcm9tU2ltaWxhcml0eShtY0Nvbm5hdWdoZXlTaW1pbGFyaXR5KHgsIHkpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFzeW1tZXRyaWNTaW1pbGFyaXR5KHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIGNvbnN0IG1pbiA9IE1hdGgubWluKHgudHJ1ZUNvdW50KCksIHkudHJ1ZUNvdW50KCkpO1xuICBpZiAobWluID09IDApIHJldHVybiAwLjA7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgcmV0dXJuIGNvbW1vbiAvIG1pbjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFzeW1tZXRyaWNEaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0RGlzdGFuY2VGcm9tU2ltaWxhcml0eShhc3ltbWV0cmljU2ltaWxhcml0eSh4LCB5KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBicmF1bkJsYW5xdWV0U2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBjb25zdCBtYXggPSBNYXRoLm1heCh4LnRydWVDb3VudCgpLCB5LnRydWVDb3VudCgpKTtcbiAgaWYgKG1heCA9PSAwKSByZXR1cm4gMC4wO1xuICBjb25zdCBjb21tb24gPSB4LmFuZFdpdGhDb3VudEJpdHMoeSwgdHJ1ZSk7XG4gIHJldHVybiBjb21tb24gLyBtYXg7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBicmF1bkJsYW5xdWV0RGlzdGFuY2UoeDogQml0QXJyYXksIHk6IEJpdEFycmF5KTogbnVtYmVyIHtcbiAgcmV0dXJuIGdldERpc3RhbmNlRnJvbVNpbWlsYXJpdHkoYnJhdW5CbGFucXVldFNpbWlsYXJpdHkoeCwgeSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcnVzc2VsU2ltaWxhcml0eSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICBpZiAoeC5sZW5ndGggPT0gMCkgcmV0dXJuIDAuMDtcbiAgY29uc3QgY29tbW9uID0geC5hbmRXaXRoQ291bnRCaXRzKHksIHRydWUpO1xuICByZXR1cm4gY29tbW9uIC8geC5sZW5ndGg7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBydXNzZWxEaXN0YW5jZSh4OiBCaXRBcnJheSwgeTogQml0QXJyYXkpOiBudW1iZXIge1xuICByZXR1cm4gZ2V0RGlzdGFuY2VGcm9tU2ltaWxhcml0eShydXNzZWxTaW1pbGFyaXR5KHgsIHkpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJvZ290R29sZGJlcmdTaW1pbGFyaXR5KHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIGNvbnN0IGNvbW1vbiA9IHguYW5kV2l0aENvdW50Qml0cyh5LCB0cnVlKTtcbiAgY29uc3QgdG90YWwgPSB4LmNvdW50Qml0cyh0cnVlKSArIHkuY291bnRCaXRzKHRydWUpO1xuICBjb25zdCBsZW4gPSB4Lmxlbmd0aDtcbiAgY29uc3QgZGlmZiA9IGxlbiAtIHRvdGFsICsgY29tbW9uO1xuICBpZiAoKGNvbW1vbiA9PSBsZW4pIHx8IChkaWZmID09IGxlbikpIHJldHVybiAxLjA7XG4gIGVsc2UgcmV0dXJuIGNvbW1vbiAvIHRvdGFsICsgZGlmZiAvICgyICogbGVuIC0gdG90YWwpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcm9nb3RHb2xkYmVyZ0Rpc3RhbmNlKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSk6IG51bWJlciB7XG4gIHJldHVybiBnZXREaXN0YW5jZUZyb21TaW1pbGFyaXR5KHJvZ290R29sZGJlcmdTaW1pbGFyaXR5KHgsIHkpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNpbWlsYXJpdHlGcm9tRGlzdGFuY2UoZGlzdGFuY2U6IG51bWJlcikge1xuICByZXR1cm4gMSAvICgxICsgZGlzdGFuY2UpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGlzdGFuY2VGcm9tU2ltaWxhcml0eShzaW1pbGFyaXR5OiBudW1iZXIpIHsgLy9pbiBjYXNlIHNpbWlsYXJpdHkgaXMgMCwgdXNlIG1heCBudW1iZXIgZm9yIGZsb2F0MzJcbiAgcmV0dXJuIHNpbWlsYXJpdHkgPT09IDAgPyAzLjQwMjgyM0UrMzggOiAoMSAvIHNpbWlsYXJpdHkpIC0gMTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG51bWVyaWNEaXN0YW5jZSh4OiBudW1iZXIsIHk6IG51bWJlcikge1xuICByZXR1cm4gTWF0aC5hYnMoeCAtIHkpO1xufVxuIl19","import * as fl from 'fastest-levenshtein';\nimport { jaroWinkler } from 'jaro-winkler-typescript';\nimport { asymmetricDistance, braunBlanquetDistance, cosineDistance, diceDistance, euclideanDistance, hammingDistance, kulczynskiDistance, mcConnaugheyDistance, rogotGoldbergDistance, russelDistance, sokalDistance, tanimotoDistance, numericDistance, tanimotoDistanceIntArray, } from '../distance-metrics-methods';\nimport { calculateEuclideanDistance } from '@datagrok-libraries/utils/src/vector-operations';\nimport { mmDistanceFunctions, MmDistanceFunctionsNames } from '../macromolecule-distance-functions';\nimport { DistanceMetricsSubjects, BitArrayMetricsNames, StringMetricsNames, VectorMetricsNames, NumberMetricsNames, IntArrayMetricsNames } from './consts';\nexport const vectorDistanceMetricsMethods = {\n [VectorMetricsNames.Euclidean]: calculateEuclideanDistance,\n};\nexport const stringDistanceMetricsMethods = {\n [StringMetricsNames.Levenshtein]: fl.distance,\n [StringMetricsNames.JaroWinkler]: jaroWinkler,\n [StringMetricsNames.Manhattan]: manhattanDistance,\n};\nexport const bitArrayDistanceMetricsMethods = {\n [BitArrayMetricsNames.Tanimoto]: tanimotoDistance,\n [BitArrayMetricsNames.Dice]: diceDistance,\n [BitArrayMetricsNames.Asymmetric]: asymmetricDistance,\n [BitArrayMetricsNames.BraunBlanquet]: braunBlanquetDistance,\n [BitArrayMetricsNames.Cosine]: cosineDistance,\n [BitArrayMetricsNames.Kulczynski]: kulczynskiDistance,\n [BitArrayMetricsNames.McConnaughey]: mcConnaugheyDistance,\n [BitArrayMetricsNames.RogotGoldberg]: rogotGoldbergDistance,\n [BitArrayMetricsNames.Russel]: russelDistance,\n [BitArrayMetricsNames.Sokal]: sokalDistance,\n [BitArrayMetricsNames.Hamming]: hammingDistance,\n [BitArrayMetricsNames.Euclidean]: euclideanDistance,\n};\nexport const intArrayDistanceMetricsMethods = {\n [IntArrayMetricsNames.TanimotoIntArray]: tanimotoDistanceIntArray,\n};\nexport const numberDistanceMetricsMethods = {\n [NumberMetricsNames.Difference]: numericDistance,\n};\nexport const AvailableMetrics = {\n [DistanceMetricsSubjects.Vector]: {\n [VectorMetricsNames.Euclidean]: vectorDistanceMetricsMethods[VectorMetricsNames.Euclidean],\n },\n [DistanceMetricsSubjects.String]: {\n [StringMetricsNames.Levenshtein]: stringDistanceMetricsMethods[StringMetricsNames.Levenshtein],\n [StringMetricsNames.JaroWinkler]: stringDistanceMetricsMethods[StringMetricsNames.JaroWinkler],\n [StringMetricsNames.Manhattan]: stringDistanceMetricsMethods[StringMetricsNames.Manhattan],\n },\n [DistanceMetricsSubjects.BitArray]: {\n [BitArrayMetricsNames.Tanimoto]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Tanimoto],\n [BitArrayMetricsNames.Dice]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Dice],\n [BitArrayMetricsNames.Asymmetric]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Asymmetric],\n [BitArrayMetricsNames.BraunBlanquet]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.BraunBlanquet],\n [BitArrayMetricsNames.Cosine]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Cosine],\n [BitArrayMetricsNames.Kulczynski]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Kulczynski],\n [BitArrayMetricsNames.McConnaughey]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.McConnaughey],\n [BitArrayMetricsNames.RogotGoldberg]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.RogotGoldberg],\n [BitArrayMetricsNames.Russel]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Russel],\n [BitArrayMetricsNames.Sokal]: bitArrayDistanceMetricsMethods[BitArrayMetricsNames.Sokal],\n },\n [DistanceMetricsSubjects.MacroMolecule]: {\n [MmDistanceFunctionsNames.HAMMING]: mmDistanceFunctions[MmDistanceFunctionsNames.HAMMING],\n [MmDistanceFunctionsNames.LEVENSHTEIN]: mmDistanceFunctions[MmDistanceFunctionsNames.LEVENSHTEIN],\n [MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH]: mmDistanceFunctions[MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH],\n [MmDistanceFunctionsNames.MONOMER_CHEMICAL_DISTANCE]: mmDistanceFunctions[MmDistanceFunctionsNames.MONOMER_CHEMICAL_DISTANCE],\n },\n [DistanceMetricsSubjects.Number]: {\n [NumberMetricsNames.Difference]: numberDistanceMetricsMethods[NumberMetricsNames.Difference],\n },\n [DistanceMetricsSubjects.IntArray]: {\n [IntArrayMetricsNames.TanimotoIntArray]: intArrayDistanceMetricsMethods[IntArrayMetricsNames.TanimotoIntArray],\n }\n};\nexport const MetricToDataType = Object.keys(AvailableMetrics)\n .reduce((ret, key) => {\n for (const val of Object.keys(AvailableMetrics[key]))\n ret[val] = key;\n return ret;\n}, {});\nexport function isStringMetric(name) {\n return MetricToDataType[name] == 'String';\n}\nexport function isBitArrayMetric(name) {\n return MetricToDataType[name] == 'BitArray';\n}\nexport function isVectorMetric(name) {\n return MetricToDataType[name] == 'Vector';\n}\nexport function isMacroMoleculeMetric(name) {\n return MetricToDataType[name] == DistanceMetricsSubjects.MacroMolecule.toString();\n}\n/** Manhattan distance between two sequences (match - 0, mismatch - 1) normalized for length. */\nexport function manhattanDistance(s1, s2) {\n if (s1.length !== s2.length) {\n return 1;\n }\n else {\n let dist = 0;\n for (let i = 1; i < s1.length; i++)\n dist += s1[i] == s2[i] ? 0 : 1;\n return dist / s1.length;\n }\n}\n/** Unified class implementing different string measures. */\nexport class Measure {\n /**\n * Creates an instance of Measure with .\n * @param {string} method Method to calculate distance between strings.\n * @memberof Measurer\n */\n constructor(method) {\n this.method = method;\n this.dataType = MetricToDataType[method];\n }\n /**\n * Returns custom string distance function specified.\n * @param {opts} opts Options for the measure. used for macromolecule distances\n * @return {DistanceMetric} Callback of the measure chosen.\n * @memberof Measurer\n */\n getMeasure(opts) {\n const dict = AvailableMetrics;\n if (!dict.hasOwnProperty(this.dataType) || !dict[this.dataType].hasOwnProperty(this.method))\n throw new Error(`Unknown measure ${this.method} for data type ${this.dataType}`);\n return isMacroMoleculeMetric(this.method) ?\n dict[this.dataType][this.method](opts) :\n dict[this.dataType][this.method];\n }\n /**\n * Returns custom string distance by the given data type.\n * @param {AvailableDataTypes} dataType Metric's data type\n * @return {string[]} Metric names which expects the given data type\n * @memberof Measurer\n */\n static getMetricByDataType(dataType) {\n return Object.keys(AvailableMetrics[dataType]);\n }\n /** Returns metric names available.\n * @memberof Measurer\n */\n static get availableMeasures() {\n return Object.keys(AvailableMetrics);\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZWQtbWV0cmljcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInR5cGVkLW1ldHJpY3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMxQyxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFFcEQsT0FBTyxFQUNMLGtCQUFrQixFQUNsQixxQkFBcUIsRUFDckIsY0FBYyxFQUNkLFlBQVksRUFDWixpQkFBaUIsRUFDakIsZUFBZSxFQUNmLGtCQUFrQixFQUNsQixvQkFBb0IsRUFDcEIscUJBQXFCLEVBQ3JCLGNBQWMsRUFDZCxhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLGVBQWUsRUFDZix3QkFBd0IsR0FDekIsTUFBTSw2QkFBNkIsQ0FBQztBQUVyQyxPQUFPLEVBQUMsMEJBQTBCLEVBQUMsTUFBTSxpREFBaUQsQ0FBQztBQUczRixPQUFPLEVBQUMsbUJBQW1CLEVBQUUsd0JBQXdCLEVBQUMsTUFBTSxxQ0FBcUMsQ0FBQztBQUNsRyxPQUFPLEVBQUMsdUJBQXVCLEVBQUUsb0JBQW9CLEVBQ25ELGtCQUFrQixFQUFFLGtCQUFrQixFQUFFLGtCQUFrQixFQUFFLG9CQUFvQixFQUFDLE1BQU0sVUFBVSxDQUFDO0FBR3BHLE1BQU0sQ0FBQyxNQUFNLDRCQUE0QixHQUF5RDtJQUNoRyxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxFQUFFLDBCQUEwQjtDQUMzRCxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQXlEO0lBQ2hHLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLEVBQUUsRUFBRSxDQUFDLFFBQVE7SUFDN0MsQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsRUFBRSxXQUFXO0lBQzdDLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLEVBQUUsaUJBQWlCO0NBQ2xELENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSw4QkFBOEIsR0FBNkQ7SUFDdEcsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsRUFBRSxnQkFBZ0I7SUFDakQsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxZQUFZO0lBQ3pDLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLEVBQUUsa0JBQWtCO0lBQ3JELENBQUMsb0JBQW9CLENBQUMsYUFBYSxDQUFDLEVBQUUscUJBQXFCO0lBQzNELENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLEVBQUUsY0FBYztJQUM3QyxDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxFQUFFLGtCQUFrQjtJQUNyRCxDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxFQUFFLG9CQUFvQjtJQUN6RCxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxFQUFFLHFCQUFxQjtJQUMzRCxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxFQUFFLGNBQWM7SUFDN0MsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxhQUFhO0lBQzNDLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLEVBQUUsZUFBZTtJQUMvQyxDQUFDLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxFQUFFLGlCQUFpQjtDQUNwRCxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sOEJBQThCLEdBQW1FO0lBQzVHLENBQUMsb0JBQW9CLENBQUMsZ0JBQWdCLENBQUMsRUFBRSx3QkFBd0I7Q0FDbEUsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLDRCQUE0QixHQUF5RDtJQUNoRyxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxFQUFFLGVBQWU7Q0FDakQsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHO0lBQzlCLENBQUMsdUJBQXVCLENBQUMsTUFBTSxDQUFDLEVBQUU7UUFDaEMsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsRUFBRSw0QkFBNEIsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUM7S0FDM0Y7SUFDRCxDQUFDLHVCQUF1QixDQUFDLE1BQU0sQ0FBQyxFQUFFO1FBQ2hDLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLEVBQUUsNEJBQTRCLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDO1FBQzlGLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLEVBQUUsNEJBQTRCLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDO1FBQzlGLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLEVBQUUsNEJBQTRCLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDO0tBQzNGO0lBQ0QsQ0FBQyx1QkFBdUIsQ0FBQyxRQUFRLENBQUMsRUFBRTtRQUNsQyxDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLFFBQVEsQ0FBQztRQUM5RixDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQztRQUN0RixDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQztRQUNsRyxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQztRQUN4RyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQztRQUMxRixDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQztRQUNsRyxDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLFlBQVksQ0FBQztRQUN0RyxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQztRQUN4RyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxFQUFFLDhCQUE4QixDQUFDLG9CQUFvQixDQUFD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dCB7amFyb1dpbmtsZXJ9IGZyb20gJ2phcm8td2lua2xlci10eXBlc2NyaXB0JztcbmltcG9ydCB7RGlzdGFuY2VNZXRyaWN9IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL3R5cGUtZGVjbGFyYXRpb25zJztcbmltcG9ydCB7XG4gIGFzeW1tZXRyaWNEaXN0YW5jZSxcbiAgYnJhdW5CbGFucXVldERpc3RhbmNlLFxuICBjb3NpbmVEaXN0YW5jZSxcbiAgZGljZURpc3RhbmNlLFxuICBldWNsaWRlYW5EaXN0YW5jZSxcbiAgaGFtbWluZ0Rpc3RhbmNlLFxuICBrdWxjenluc2tpRGlzdGFuY2UsXG4gIG1jQ29ubmF1Z2hleURpc3RhbmNlLFxuICByb2dvdEdvbGRiZXJnRGlzdGFuY2UsXG4gIHJ1c3NlbERpc3RhbmNlLFxuICBzb2thbERpc3RhbmNlLFxuICB0YW5pbW90b0Rpc3RhbmNlLFxuICBudW1lcmljRGlzdGFuY2UsXG4gIHRhbmltb3RvRGlzdGFuY2VJbnRBcnJheSxcbn0gZnJvbSAnLi4vZGlzdGFuY2UtbWV0cmljcy1tZXRob2RzJztcblxuaW1wb3J0IHtjYWxjdWxhdGVFdWNsaWRlYW5EaXN0YW5jZX0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy91dGlscy9zcmMvdmVjdG9yLW9wZXJhdGlvbnMnO1xuaW1wb3J0IEJpdEFycmF5IGZyb20gJ0BkYXRhZ3Jvay1saWJyYXJpZXMvdXRpbHMvc3JjL2JpdC1hcnJheSc7XG5pbXBvcnQge1ZlY3RvciwgU3RyaW5nRGljdGlvbmFyeX0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy91dGlscy9zcmMvdHlwZS1kZWNsYXJhdGlvbnMnO1xuaW1wb3J0IHttbURpc3RhbmNlRnVuY3Rpb25zLCBNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXN9IGZyb20gJy4uL21hY3JvbW9sZWN1bGUtZGlzdGFuY2UtZnVuY3Rpb25zJztcbmltcG9ydCB7RGlzdGFuY2VNZXRyaWNzU3ViamVjdHMsIEJpdEFycmF5TWV0cmljc05hbWVzLFxuICBTdHJpbmdNZXRyaWNzTmFtZXMsIFZlY3Rvck1ldHJpY3NOYW1lcywgTnVtYmVyTWV0cmljc05hbWVzLCBJbnRBcnJheU1ldHJpY3NOYW1lc30gZnJvbSAnLi9jb25zdHMnO1xuXG5cbmV4cG9ydCBjb25zdCB2ZWN0b3JEaXN0YW5jZU1ldHJpY3NNZXRob2RzOiB7IFtuYW1lOiBzdHJpbmddOiAoeDogVmVjdG9yLCB5OiBWZWN0b3IpID0+IG51bWJlciB9ID0ge1xuICBbVmVjdG9yTWV0cmljc05hbWVzLkV1Y2xpZGVhbl06IGNhbGN1bGF0ZUV1Y2xpZGVhbkRpc3RhbmNlLFxufTtcblxuZXhwb3J0IGNvbnN0IHN0cmluZ0Rpc3RhbmNlTWV0cmljc01ldGhvZHM6IHsgW25hbWU6IHN0cmluZ106ICh4OiBzdHJpbmcsIHk6IHN0cmluZykgPT4gbnVtYmVyIH0gPSB7XG4gIFtTdHJpbmdNZXRyaWNzTmFtZXMuTGV2ZW5zaHRlaW5dOiBmbC5kaXN0YW5jZSxcbiAgW1N0cmluZ01ldHJpY3NOYW1lcy5KYXJvV2lua2xlcl06IGphcm9XaW5rbGVyLFxuICBbU3RyaW5nTWV0cmljc05hbWVzLk1hbmhhdHRhbl06IG1hbmhhdHRhbkRpc3RhbmNlLFxufTtcblxuZXhwb3J0IGNvbnN0IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kczogeyBbbmFtZTogc3RyaW5nXTogKHg6IEJpdEFycmF5LCB5OiBCaXRBcnJheSkgPT4gbnVtYmVyIH0gPSB7XG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90b106IHRhbmltb3RvRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5EaWNlXTogZGljZURpc3RhbmNlLFxuICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuQXN5bW1ldHJpY106IGFzeW1tZXRyaWNEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkJyYXVuQmxhbnF1ZXRdOiBicmF1bkJsYW5xdWV0RGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5Db3NpbmVdOiBjb3NpbmVEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkt1bGN6eW5za2ldOiBrdWxjenluc2tpRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5NY0Nvbm5hdWdoZXldOiBtY0Nvbm5hdWdoZXlEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlJvZ290R29sZGJlcmddOiByb2dvdEdvbGRiZXJnRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5SdXNzZWxdOiBydXNzZWxEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLlNva2FsXTogc29rYWxEaXN0YW5jZSxcbiAgW0JpdEFycmF5TWV0cmljc05hbWVzLkhhbW1pbmddOiBoYW1taW5nRGlzdGFuY2UsXG4gIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5FdWNsaWRlYW5dOiBldWNsaWRlYW5EaXN0YW5jZSxcbn07XG5cbmV4cG9ydCBjb25zdCBpbnRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHM6IHsgW25hbWU6IHN0cmluZ106ICh4OiBVaW50MzJBcnJheSwgeTogVWludDMyQXJyYXkpID0+IG51bWJlciB9ID0ge1xuICBbSW50QXJyYXlNZXRyaWNzTmFtZXMuVGFuaW1vdG9JbnRBcnJheV06IHRhbmltb3RvRGlzdGFuY2VJbnRBcnJheSxcbn07XG5cbmV4cG9ydCBjb25zdCBudW1iZXJEaXN0YW5jZU1ldHJpY3NNZXRob2RzOiB7IFtuYW1lOiBzdHJpbmddOiAoeDogbnVtYmVyLCB5OiBudW1iZXIpID0+IG51bWJlciB9ID0ge1xuICBbTnVtYmVyTWV0cmljc05hbWVzLkRpZmZlcmVuY2VdOiBudW1lcmljRGlzdGFuY2UsXG59O1xuXG5leHBvcnQgY29uc3QgQXZhaWxhYmxlTWV0cmljcyA9IHtcbiAgW0Rpc3RhbmNlTWV0cmljc1N1YmplY3RzLlZlY3Rvcl06IHtcbiAgICBbVmVjdG9yTWV0cmljc05hbWVzLkV1Y2xpZGVhbl06IHZlY3RvckRpc3RhbmNlTWV0cmljc01ldGhvZHNbVmVjdG9yTWV0cmljc05hbWVzLkV1Y2xpZGVhbl0sXG4gIH0sXG4gIFtEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5TdHJpbmddOiB7XG4gICAgW1N0cmluZ01ldHJpY3NOYW1lcy5MZXZlbnNodGVpbl06IHN0cmluZ0Rpc3RhbmNlTWV0cmljc01ldGhvZHNbU3RyaW5nTWV0cmljc05hbWVzLkxldmVuc2h0ZWluXSxcbiAgICBbU3RyaW5nTWV0cmljc05hbWVzLkphcm9XaW5rbGVyXTogc3RyaW5nRGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tTdHJpbmdNZXRyaWNzTmFtZXMuSmFyb1dpbmtsZXJdLFxuICAgIFtTdHJpbmdNZXRyaWNzTmFtZXMuTWFuaGF0dGFuXTogc3RyaW5nRGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tTdHJpbmdNZXRyaWNzTmFtZXMuTWFuaGF0dGFuXSxcbiAgfSxcbiAgW0Rpc3RhbmNlTWV0cmljc1N1YmplY3RzLkJpdEFycmF5XToge1xuICAgIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90b106IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90b10sXG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLkRpY2VdOiBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHNbQml0QXJyYXlNZXRyaWNzTmFtZXMuRGljZV0sXG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLkFzeW1tZXRyaWNdOiBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHNbQml0QXJyYXlNZXRyaWNzTmFtZXMuQXN5bW1ldHJpY10sXG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLkJyYXVuQmxhbnF1ZXRdOiBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHNbQml0QXJyYXlNZXRyaWNzTmFtZXMuQnJhdW5CbGFucXVldF0sXG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLkNvc2luZV06IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5Db3NpbmVdLFxuICAgIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5LdWxjenluc2tpXTogYml0QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzW0JpdEFycmF5TWV0cmljc05hbWVzLkt1bGN6eW5za2ldLFxuICAgIFtCaXRBcnJheU1ldHJpY3NOYW1lcy5NY0Nvbm5hdWdoZXldOiBiaXRBcnJheURpc3RhbmNlTWV0cmljc01ldGhvZHNbQml0QXJyYXlNZXRyaWNzTmFtZXMuTWNDb25uYXVnaGV5XSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuUm9nb3RHb2xkYmVyZ106IGJpdEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tCaXRBcnJheU1ldHJpY3NOYW1lcy5Sb2dvdEdvbGRiZXJnXSxcbiAgICBbQml0QXJyYXlNZXRyaWNzTmFtZXMuUnVzc2VsXTogYml0QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzW0JpdEFycmF5TWV0cmljc05hbWVzLlJ1c3NlbF0sXG4gICAgW0JpdEFycmF5TWV0cmljc05hbWVzLlNva2FsXTogYml0QXJyYXlEaXN0YW5jZU1ldHJpY3NNZXRob2RzW0JpdEFycmF5TWV0cmljc05hbWVzLlNva2FsXSxcbiAgfSxcbiAgW0Rpc3RhbmNlTWV0cmljc1N1YmplY3RzLk1hY3JvTW9sZWN1bGVdOiB7IC8vIG9wdGlvbmFsIGFyZ3MgbmVlZGVkIGZvciBtYWNyb21vbGVjdWxlIGZ1bmN0aW9ucyB3aGljaCBpbml0aWFsaXplIHRoZW1cbiAgICBbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLkhBTU1JTkddOiBtbURpc3RhbmNlRnVuY3Rpb25zW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5IQU1NSU5HXSxcbiAgICBbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLkxFVkVOU0hURUlOXTogbW1EaXN0YW5jZUZ1bmN0aW9uc1tNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTEVWRU5TSFRFSU5dLFxuICAgIFtNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTkVFRExFTUFOTl9XVU5TQ0hdOiBtbURpc3RhbmNlRnVuY3Rpb25zW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5ORUVETEVNQU5OX1dVTlNDSF0sXG4gICAgW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5NT05PTUVSX0NIRU1JQ0FMX0RJU1RBTkNFXTogbW1EaXN0YW5jZUZ1bmN0aW9uc1tNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTU9OT01FUl9DSEVNSUNBTF9ESVNUQU5DRV0sXG4gIH0sXG4gIFtEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5OdW1iZXJdOiB7XG4gICAgW051bWJlck1ldHJpY3NOYW1lcy5EaWZmZXJlbmNlXTogbnVtYmVyRGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tOdW1iZXJNZXRyaWNzTmFtZXMuRGlmZmVyZW5jZV0sXG4gIH0sXG4gIFtEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5JbnRBcnJheV06IHtcbiAgICBbSW50QXJyYXlNZXRyaWNzTmFtZXMuVGFuaW1vdG9JbnRBcnJheV06IGludEFycmF5RGlzdGFuY2VNZXRyaWNzTWV0aG9kc1tJbnRBcnJheU1ldHJpY3NOYW1lcy5UYW5pbW90b0ludEFycmF5XSxcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IE1ldHJpY1RvRGF0YVR5cGU6IFN0cmluZ0RpY3Rpb25hcnkgPSBPYmplY3Qua2V5cyhBdmFpbGFibGVNZXRyaWNzKVxuICAucmVkdWNlKChyZXQ6IFN0cmluZ0RpY3Rpb25hcnksIGtleSkgPT4ge1xuICAgIGZvciAoY29uc3QgdmFsIG9mIE9iamVjdC5rZXlzKEF2YWlsYWJsZU1ldHJpY3Nba2V5IGFzIEF2YWlsYWJsZURhdGFUeXBlc10pKVxuICAgICAgcmV0W3ZhbCBhcyBBdmFpbGFibGVEYXRhVHlwZXNdID0ga2V5O1xuXG4gICAgcmV0dXJuIHJldDtcbiAgfSwge30pO1xuXG5leHBvcnQgdHlwZSBBdmFpbGFibGVEYXRhVHlwZXMgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlTWV0cmljcztcbmV4cG9ydCB0eXBlIFZlY3Rvck1ldHJpY3MgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlTWV0cmljc1tEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5WZWN0b3JdO1xuZXhwb3J0IHR5cGUgU3RyaW5nTWV0cmljcyA9IGtleW9mIHR5cGVvZiBBdmFpbGFibGVNZXRyaWNzW0Rpc3RhbmNlTWV0cmljc1N1YmplY3RzLlN0cmluZ107XG5leHBvcnQgdHlwZSBCaXRBcnJheU1ldHJpY3MgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlTWV0cmljc1tEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5CaXRBcnJheV07XG5leHBvcnQgdHlwZSBLbm93bk1ldHJpY3MgPSBTdHJpbmdNZXRyaWNzIHwgQml0QXJyYXlNZXRyaWNzIHwgVmVjdG9yTWV0cmljcyB8XG4gIE1tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcyB8IE51bWJlck1ldHJpY3NOYW1lcyB8IEludEFycmF5TWV0cmljc05hbWVzO1xuXG5leHBvcnQgdHlwZSBWYWxpZFR5cGVzID1cbiAgeyBkYXRhOiBzdHJpbmdbXSwgbWV0cmljOiBTdHJpbmdNZXRyaWNzIHwgTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzIH0gfFxuICB7IGRhdGE6IFZlY3RvcltdLCBtZXRyaWM6IFZlY3Rvck1ldHJpY3MgfSB8XG4gIHsgZGF0YTogQml0QXJyYXlbXSwgbWV0cmljOiBCaXRBcnJheU1ldHJpY3MgfSB8XG4gIHsgZGF0YTogbnVtYmVyW10sIG1ldHJpYzogTnVtYmVyTWV0cmljc05hbWVzIH07XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1N0cmluZ01ldHJpYyhuYW1lOiBLbm93bk1ldHJpY3MpIHtcbiAgcmV0dXJuIE1ldHJpY1RvRGF0YVR5cGVbbmFtZV0gPT0gJ1N0cmluZyc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0JpdEFycmF5TWV0cmljKG5hbWU6IEtub3duTWV0cmljcykge1xuICByZXR1cm4gTWV0cmljVG9EYXRhVHlwZVtuYW1lXSA9PSAnQml0QXJyYXknO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNWZWN0b3JNZXRyaWMobmFtZTogS25vd25NZXRyaWNzKSB7XG4gIHJldHVybiBNZXRyaWNUb0RhdGFUeXBlW25hbWVdID09ICdWZWN0b3InO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNNYWNyb01vbGVjdWxlTWV0cmljKG5hbWU6IEtub3duTWV0cmljcykge1xuICByZXR1cm4gTWV0cmljVG9EYXRhVHlwZVtuYW1lXSA9PSBEaXN0YW5jZU1ldHJpY3NTdWJqZWN0cy5NYWNyb01vbGVjdWxlLnRvU3RyaW5nKCk7XG59XG5cbi8qKiBNYW5oYXR0YW4gZGlzdGFuY2UgYmV0d2VlbiB0d28gc2VxdWVuY2VzIChtYXRjaCAtIDAsIG1pc21hdGNoIC0gMSkgbm9ybWFsaXplZCBmb3IgbGVuZ3RoLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hbmhhdHRhbkRpc3RhbmNlKHMxOiBzdHJpbmcsIHMyOiBzdHJpbmcpOiBudW1iZXIge1xuICBpZiAoczEubGVuZ3RoICE9PSBzMi5sZW5ndGgpIHtcbiAgICByZXR1cm4gMTtcbiAgfSBlbHNlIHtcbiAgICBsZXQgZGlzdDogbnVtYmVyID0gMDtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHMxLmxlbmd0aDsgaSsrKVxuICAgICAgZGlzdCArPSBzMVtpXSA9PSBzMltpXSA/IDAgOiAxO1xuICAgIHJldHVybiBkaXN0IC8gczEubGVuZ3RoO1xuICB9XG59XG5cbi8qKiBVbmlmaWVkIGNsYXNzIGltcGxlbWVudGluZyBkaWZmZXJlbnQgc3RyaW5nIG1lYXN1cmVzLiAqL1xuZXhwb3J0IGNsYXNzIE1lYXN1cmUge1xuICBwcm90ZWN0ZWQgbWV0aG9kOiBLbm93bk1ldHJpY3M7XG4gIHByb3RlY3RlZCBkYXRhVHlwZTogQXZhaWxhYmxlRGF0YVR5cGVzO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIE1lYXN1cmUgd2l0aCAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXRob2QgTWV0aG9kIHRvIGNhbGN1bGF0ZSBkaXN0YW5jZSBiZXR3ZWVuIHN0cmluZ3MuXG4gICAqIEBtZW1iZXJvZiBNZWFzdXJlclxuICAgKi9cbiAgY29uc3RydWN0b3IobWV0aG9kOiBLbm93bk1ldHJpY3MpIHtcbiAgICB0aGlzLm1ldGhvZCA9IG1ldGhvZDtcbiAgICB0aGlzLmRhdGFUeXBlID0gTWV0cmljVG9EYXRhVHlwZVttZXRob2RdIGFzIEF2YWlsYWJsZURhdGFUeXBlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGN1c3RvbSBzdHJpbmcgZGlzdGFuY2UgZnVuY3Rpb24gc3BlY2lmaWVkLlxuICAgKiBAcGFyYW0ge29wdHN9IG9wdHMgT3B0aW9ucyBmb3IgdGhlIG1lYXN1cmUuIHVzZWQgZm9yIG1hY3JvbW9sZWN1bGUgZGlzdGFuY2VzXG4gICAqIEByZXR1cm4ge0Rpc3RhbmNlTWV0cmljfSBDYWxsYmFjayBvZiB0aGUgbWVhc3VyZSBjaG9zZW4uXG4gICAqIEBtZW1iZXJvZiBNZWFzdXJlclxuICAgKi9cbiAgcHVibGljIGdldE1lYXN1cmUob3B0cz86IGFueSk6IERpc3RhbmNlTWV0cmljIHtcbiAgICBjb25zdCBkaWN0OiB7IFtrZXk6IHN0cmluZ106XG4gICAgICB7W2tleTI6IHN0cmluZ106IERpc3RhbmNlTWV0cmljIHwgKChvcHRzOiBhbnkpID0+IERpc3RhbmNlTWV0cmljKX1cbiAgICB9ID0gQXZhaWxhYmxlTWV0cmljcztcbiAgICBpZiAoIWRpY3QuaGFzT3duUHJvcGVydHkodGhpcy5kYXRhVHlwZSkgfHwgIWRpY3RbdGhpcy5kYXRhVHlwZV0uaGFzT3duUHJvcGVydHkodGhpcy5tZXRob2QpKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIG1lYXN1cmUgJHt0aGlzLm1ldGhvZH0gZm9yIGRhdGEgdHlwZSAke3RoaXMuZGF0YVR5cGV9YCk7XG4gICAgcmV0dXJuIGlzTWFjcm9Nb2xlY3VsZU1ldHJpYyh0aGlzLm1ldGhvZCkgP1xuICAgICAgKGRpY3RbdGhpcy5kYXRhVHlwZV1bdGhpcy5tZXRob2RdIGFzICgob3B0czogYW55KSA9PiBEaXN0YW5jZU1ldHJpYykpKG9wdHMpIDpcbiAgICAgIGRpY3RbdGhpcy5kYXRhVHlwZV1bdGhpcy5tZXRob2RdIGFzIERpc3RhbmNlTWV0cmljO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgY3VzdG9tIHN0cmluZyBkaXN0YW5jZSBieSB0aGUgZ2l2ZW4gZGF0YSB0eXBlLlxuICAgKiBAcGFyYW0ge0F2YWlsYWJsZURhdGFUeXBlc30gZGF0YVR5cGUgTWV0cmljJ3MgZGF0YSB0eXBlXG4gICAqIEByZXR1cm4ge3N0cmluZ1tdfSBNZXRyaWMgbmFtZXMgd2hpY2ggZXhwZWN0cyB0aGUgZ2l2ZW4gZGF0YSB0eXBlXG4gICAqIEBtZW1iZXJvZiBNZWFzdXJlclxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBnZXRNZXRyaWNCeURhdGFUeXBlKGRhdGFUeXBlOiBBdmFpbGFibGVEYXRhVHlwZXMpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKEF2YWlsYWJsZU1ldHJpY3NbZGF0YVR5cGVdKTtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIG1ldHJpYyBuYW1lcyBhdmFpbGFibGUuXG4gICAqIEBtZW1iZXJvZiBNZWFzdXJlclxuICAgKi9cbiAgc3RhdGljIGdldCBhdmFpbGFibGVNZWFzdXJlcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKEF2YWlsYWJsZU1ldHJpY3MpO1xuICB9XG59XG4iXX0=","/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\n/**\n * Simple random integer function\n */\nexport function tauRandInt(n, random) {\n return Math.floor(random() * n);\n}\n/**\n * Simple random float function\n */\nexport function tauRand(random) {\n return random();\n}\n/**\n * Compute the (standard l2) norm of a vector.\n */\nexport function norm(vec) {\n let result = 0;\n for (let item of vec) {\n result += item ** 2;\n }\n return Math.sqrt(result);\n}\n/**\n * Creates an empty array (filled with undefined)\n */\nexport function empty(n) {\n const output = [];\n for (let i = 0; i < n; i++) {\n output.push(undefined);\n }\n return output;\n}\n/**\n * Creates an array filled with index values\n */\nexport function range(n) {\n return empty(n).map((_, i) => i);\n}\n/**\n * Creates an array filled with a specific value\n */\nexport function filled(n, v) {\n return empty(n).map(() => v);\n}\n/**\n * Creates an array filled with zeros\n */\nexport function zeros(n) {\n return filled(n, 0);\n}\n/**\n * Creates an array filled with ones\n */\nexport function ones(n) {\n return filled(n, 1);\n}\n/**\n * Creates an array from a to b, of length len, inclusive\n */\nexport function linear(a, b, len) {\n return empty(len).map((_, i) => {\n return a + i * ((b - a) / (len - 1));\n });\n}\n/**\n * Returns the sum of an array\n */\nexport function sum(input) {\n return input.reduce((sum, val) => sum + val);\n}\n/**\n * Returns the mean of an array\n */\nexport function mean(input) {\n return sum(input) / input.length;\n}\n/**\n * Returns the maximum value of an array\n */\nexport function max(input) {\n let max = 0;\n for (let i = 0; i < input.length; i++) {\n max = input[i] > max ? input[i] : max;\n }\n return max;\n}\n/**\n * Returns the maximum value of a 2d array\n */\nexport function max2d(input) {\n let max = 0;\n for (let i = 0; i < input.length; i++) {\n for (let j = 0; j < input[i].length; j++) {\n max = input[i][j] > max ? input[i][j] : max;\n }\n }\n return max;\n}\n/**\n * Generate nSamples many integers from 0 to poolSize such that no\n * integer is selected twice. The duplication constraint is achieved via\n * rejection sampling.\n */\nexport function rejectionSample(nSamples, poolSize, random) {\n const result = zeros(nSamples);\n for (let i = 0; i < nSamples; i++) {\n let rejectSample = true;\n while (rejectSample) {\n const j = tauRandInt(poolSize, random);\n let broken = false;\n for (let k = 0; k < i; k++) {\n if (j === result[k]) {\n broken = true;\n break;\n }\n }\n if (!broken) {\n rejectSample = false;\n }\n result[i] = j;\n }\n }\n return result;\n}\n/**\n * Reshapes a 1d array into a 2D of given dimensions.\n */\nexport function reshape2d(x, a, b) {\n const rows = [];\n let count = 0;\n let index = 0;\n if (x.length !== a * b) {\n throw new Error('Array dimensions must match input length.');\n }\n for (let i = 0; i < a; i++) {\n const col = [];\n for (let j = 0; j < b; j++) {\n col.push(x[index]);\n index += 1;\n }\n rows.push(col);\n count += 1;\n }\n return rows;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ1dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFJSDs7R0FFRztBQUNILE1BQU0sVUFBVSxVQUFVLENBQUMsQ0FBUyxFQUFFLE1BQWdCO0lBQ3BELE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNsQyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsT0FBTyxDQUFDLE1BQWdCO0lBQ3RDLE9BQU8sTUFBTSxFQUFFLENBQUM7QUFDbEIsQ0FBQztBQUNEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLElBQUksQ0FBQyxHQUFhO0lBQ2hDLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNmLEtBQUssSUFBSSxJQUFJLElBQUksR0FBRyxFQUFFO1FBQ3BCLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxDQUFDO0tBQ3JCO0lBQ0QsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzNCLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxLQUFLLENBQUMsQ0FBUztJQUM3QixNQUFNLE1BQU0sR0FBZ0IsRUFBRSxDQUFDO0lBQy9CLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDMUIsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztLQUN4QjtJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxLQUFLLENBQUMsQ0FBUztJQUM3QixPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQyxDQUFDO0FB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QUMsQ0FBQztTQUNaO1FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNmLEtBQUssSUFBSSxDQUFDLENBQUM7S0FDWjtJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqXG4gKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5cbmltcG9ydCB7IFJhbmRvbUZuIH0gZnJvbSAnLi91bWFwJztcblxuLyoqXG4gKiBTaW1wbGUgcmFuZG9tIGludGVnZXIgZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRhdVJhbmRJbnQobjogbnVtYmVyLCByYW5kb206IFJhbmRvbUZuKSB7XG4gIHJldHVybiBNYXRoLmZsb29yKHJhbmRvbSgpICogbik7XG59XG5cbi8qKlxuICogU2ltcGxlIHJhbmRvbSBmbG9hdCBmdW5jdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gdGF1UmFuZChyYW5kb206IFJhbmRvbUZuKSB7XG4gIHJldHVybiByYW5kb20oKTtcbn1cbi8qKlxuICogQ29tcHV0ZSB0aGUgKHN0YW5kYXJkIGwyKSBub3JtIG9mIGEgdmVjdG9yLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybSh2ZWM6IG51bWJlcltdKSB7XG4gIGxldCByZXN1bHQgPSAwO1xuICBmb3IgKGxldCBpdGVtIG9mIHZlYykge1xuICAgIHJlc3VsdCArPSBpdGVtICoqIDI7XG4gIH1cbiAgcmV0dXJuIE1hdGguc3FydChyZXN1bHQpO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYW4gZW1wdHkgYXJyYXkgKGZpbGxlZCB3aXRoIHVuZGVmaW5lZClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVtcHR5KG46IG51bWJlcik6IHVuZGVmaW5lZFtdIHtcbiAgY29uc3Qgb3V0cHV0OiB1bmRlZmluZWRbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykge1xuICAgIG91dHB1dC5wdXNoKHVuZGVmaW5lZCk7XG4gIH1cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZpbGxlZCB3aXRoIGluZGV4IHZhbHVlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmFuZ2UobjogbnVtYmVyKTogbnVtYmVyW10ge1xuICByZXR1cm4gZW1wdHkobikubWFwKChfLCBpKSA9PiBpKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZpbGxlZCB3aXRoIGEgc3BlY2lmaWMgdmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbGxlZChuOiBudW1iZXIsIHY6IG51bWJlcik6IG51bWJlcltdIHtcbiAgcmV0dXJuIGVtcHR5KG4pLm1hcCgoKSA9PiB2KTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZpbGxlZCB3aXRoIHplcm9zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB6ZXJvcyhuOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gIHJldHVybiBmaWxsZWQobiwgMCk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBmaWxsZWQgd2l0aCBvbmVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbmVzKG46IG51bWJlcik6IG51bWJlcltdIHtcbiAgcmV0dXJuIGZpbGxlZChuLCAxKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGZyb20gYSB0byBiLCBvZiBsZW5ndGggbGVuLCBpbmNsdXNpdmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhcihhOiBudW1iZXIsIGI6IG51bWJlciwgbGVuOiBudW1iZXIpOiBudW1iZXJbXSB7XG4gIHJldHVybiBlbXB0eShsZW4pLm1hcCgoXywgaSkgPT4ge1xuICAgIHJldHVybiBhICsgaSAqICgoYiAtIGEpIC8gKGxlbiAtIDEpKTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3VtIG9mIGFuIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdW0oaW5wdXQ6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgcmV0dXJuIGlucHV0LnJlZHVjZSgoc3VtLCB2YWwpID0+IHN1bSArIHZhbCk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbWVhbiBvZiBhbiBhcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVhbihpbnB1dDogbnVtYmVyW10pOiBudW1iZXIge1xuICByZXR1cm4gc3VtKGlucHV0KSAvIGlucHV0Lmxlbmd0aDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtYXhpbXVtIHZhbHVlIG9mIGFuIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXgoaW5wdXQ6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgbGV0IG1heCA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoOyBpKyspIHtcbiAgICBtYXggPSBpbnB1dFtpXSA+IG1heCA/IGlucHV0W2ldIDogbWF4O1xuICB9XG4gIHJldHVybiBtYXg7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbWF4aW11bSB2YWx1ZSBvZiBhIDJkIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXgyZChpbnB1dDogbnVtYmVyW11bXSk6IG51bWJlciB7XG4gIGxldCBtYXggPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0Lmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbnB1dFtpXS5sZW5ndGg7IGorKykge1xuICAgICAgbWF4ID0gaW5wdXRbaV1bal0gPiBtYXggPyBpbnB1dFtpXVtqXSA6IG1heDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG1heDtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBuU2FtcGxlcyBtYW55IGludGVnZXJzIGZyb20gMCB0byBwb29sU2l6ZSBzdWNoIHRoYXQgbm9cbiAqIGludGVnZXIgaXMgc2VsZWN0ZWQgdHdpY2UuIFRoZSBkdXBsaWNhdGlvbiBjb25zdHJhaW50IGlzIGFjaGlldmVkIHZpYVxuICogcmVqZWN0aW9uIHNhbXBsaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVqZWN0aW9uU2FtcGxlKFxuICBuU2FtcGxlczogbnVtYmVyLFxuICBwb29sU2l6ZTogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pOiBudW1iZXJbXSB7XG4gIGNvbnN0IHJlc3VsdCA9IHplcm9zKG5TYW1wbGVzKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuU2FtcGxlczsgaSsrKSB7XG4gICAgbGV0IHJlamVjdFNhbXBsZSA9IHRydWU7XG4gICAgd2hpbGUgKHJlamVjdFNhbXBsZSkge1xuICAgICAgY29uc3QgaiA9IHRhdVJhbmRJbnQocG9vbFNpemUsIHJhbmRvbSk7XG4gICAgICBsZXQgYnJva2VuID0gZmFsc2U7XG4gICAgICBmb3IgKGxldCBrID0gMDsgayA8IGk7IGsrKykge1xuICAgICAgICBpZiAoaiA9PT0gcmVzdWx0W2tdKSB7XG4gICAgICAgICAgYnJva2VuID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCFicm9rZW4pIHtcbiAgICAgICAgcmVqZWN0U2FtcGxlID0gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXN1bHRbaV0gPSBqO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFJlc2hhcGVzIGEgMWQgYXJyYXkgaW50byBhIDJEIG9mIGdpdmVuIGRpbWVuc2lvbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNoYXBlMmQ8VD4oeDogVFtdLCBhOiBudW1iZXIsIGI6IG51bWJlcik6IFRbXVtdIHtcbiAgY29uc3Qgcm93czogVFtdW10gPSBbXTtcbiAgbGV0IGNvdW50ID0gMDtcbiAgbGV0IGluZGV4ID0gMDtcblxuICBpZiAoeC5sZW5ndGggIT09IGEgKiBiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBcnJheSBkaW1lbnNpb25zIG11c3QgbWF0Y2ggaW5wdXQgbGVuZ3RoLicpO1xuICB9XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhOyBpKyspIHtcbiAgICBjb25zdCBjb2w6IFRbXSA9IFtdO1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgYjsgaisrKSB7XG4gICAgICBjb2wucHVzaCh4W2luZGV4XSk7XG4gICAgICBpbmRleCArPSAxO1xuICAgIH1cbiAgICByb3dzLnB1c2goY29sKTtcbiAgICBjb3VudCArPSAxO1xuICB9XG4gIHJldHVybiByb3dzO1xufVxuIl19","/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\nimport * as utils from './utils';\n/**\n * Constructor for the heap objects. The heaps are used\n * for approximate nearest neighbor search, maintaining a list of potential\n * neighbors sorted by their distance. We also flag if potential neighbors\n * are newly added to the list or not. Internally this is stored as\n * a single array; the first axis determines whether we are looking at the\n * array of candidate indices, the array of distances, or the flag array for\n * whether elements are new or not. Each of these arrays are of shape\n * (``nPoints``, ``size``)\n */\nexport function makeHeap(nPoints, size) {\n const makeArrays = (fillValue) => {\n return utils.empty(nPoints).map(() => {\n return utils.filled(size, fillValue);\n });\n };\n const heap = [];\n heap.push(makeArrays(-1));\n heap.push(makeArrays(Infinity));\n heap.push(makeArrays(0));\n return heap;\n}\n/**\n * Generate n_samples many integers from 0 to pool_size such that no\n * integer is selected twice. The duplication constraint is achieved via\n * rejection sampling.\n */\nexport function rejectionSample(nSamples, poolSize, random) {\n const result = utils.zeros(nSamples);\n for (let i = 0; i < nSamples; i++) {\n let rejectSample = true;\n let j = 0;\n while (rejectSample) {\n j = utils.tauRandInt(poolSize, random);\n let broken = false;\n for (let k = 0; k < i; k++) {\n if (j === result[k]) {\n broken = true;\n break;\n }\n }\n if (!broken)\n rejectSample = false;\n }\n result[i] = j;\n }\n return result;\n}\n/**\n * Push a new element onto the heap. The heap stores potential neighbors\n * for each data point. The ``row`` parameter determines which data point we\n * are addressing, the ``weight`` determines the distance (for heap sorting),\n * the ``index`` is the element to add, and the flag determines whether this\n * is to be considered a new addition.\n */\nexport function heapPush(heap, row, weight, index, flag) {\n row = Math.floor(row);\n const indices = heap[0][row];\n const weights = heap[1][row];\n const isNew = heap[2][row];\n if (weight >= weights[0]) {\n return 0;\n }\n // Break if we already have this element.\n for (let i = 0; i < indices.length; i++) {\n if (index === indices[i]) {\n return 0;\n }\n }\n return uncheckedHeapPush(heap, row, weight, index, flag);\n}\n/**\n * Push a new element onto the heap. The heap stores potential neighbors\n * for each data point. The ``row`` parameter determines which data point we\n * are addressing, the ``weight`` determines the distance (for heap sorting),\n * the ``index`` is the element to add, and the flag determines whether this\n * is to be considered a new addition.\n */\nexport function uncheckedHeapPush(heap, row, weight, index, flag) {\n const indices = heap[0][row];\n const weights = heap[1][row];\n const isNew = heap[2][row];\n if (weight >= weights[0]) {\n return 0;\n }\n // Insert val at position zero\n weights[0] = weight;\n indices[0] = index;\n isNew[0] = flag;\n // Descend the heap, swapping values until the max heap criterion is met\n let i = 0;\n let iSwap = 0;\n while (true) {\n const ic1 = 2 * i + 1;\n const ic2 = ic1 + 1;\n const heapShape2 = heap[0][0].length;\n if (ic1 >= heapShape2) {\n break;\n }\n else if (ic2 >= heapShape2) {\n if (weights[ic1] > weight) {\n iSwap = ic1;\n }\n else {\n break;\n }\n }\n else if (weights[ic1] >= weights[ic2]) {\n if (weight < weights[ic1]) {\n iSwap = ic1;\n }\n else {\n break;\n }\n }\n else {\n if (weight < weights[ic2]) {\n iSwap = ic2;\n }\n else {\n break;\n }\n }\n weights[i] = weights[iSwap];\n indices[i] = indices[iSwap];\n isNew[i] = isNew[iSwap];\n i = iSwap;\n }\n weights[i] = weight;\n indices[i] = index;\n isNew[i] = flag;\n return 1;\n}\n/**\n * Build a heap of candidate neighbors for nearest neighbor descent. For\n * each vertex the candidate neighbors are any current neighbors, and any\n * vertices that have the vertex as one of their nearest neighbors.\n */\nexport function buildCandidates(currentGraph, nVertices, nNeighbors, maxCandidates, random) {\n const candidateNeighbors = makeHeap(nVertices, maxCandidates);\n for (let i = 0; i < nVertices; i++) {\n for (let j = 0; j < nNeighbors; j++) {\n if (currentGraph[0][i][j] < 0) {\n continue;\n }\n const idx = currentGraph[0][i][j];\n const isn = currentGraph[2][i][j];\n const d = utils.tauRand(random);\n heapPush(candidateNeighbors, i, d, idx, isn);\n heapPush(candidateNeighbors, idx, d, i, isn);\n currentGraph[2][i][j] = 0;\n }\n }\n return candidateNeighbors;\n}\n/**\n * Given an array of heaps (of indices and weights), unpack the heap\n * out to give and array of sorted lists of indices and weights by increasing\n * weight. This is effectively just the second half of heap sort (the first\n * half not being required since we already have the data in a heap).\n */\nexport function deheapSort(heap) {\n const indices = heap[0];\n const weights = heap[1];\n for (let i = 0; i < indices.length; i++) {\n const indHeap = indices[i];\n const distHeap = weights[i];\n for (let j = 0; j < indHeap.length - 1; j++) {\n const indHeapIndex = indHeap.length - j - 1;\n const distHeapIndex = distHeap.length - j - 1;\n const temp1 = indHeap[0];\n indHeap[0] = indHeap[indHeapIndex];\n indHeap[indHeapIndex] = temp1;\n const temp2 = distHeap[0];\n distHeap[0] = distHeap[distHeapIndex];\n distHeap[distHeapIndex] = temp2;\n siftDown(distHeap, indHeap, distHeapIndex, 0);\n }\n }\n return { indices, weights };\n}\n/**\n * Restore the heap property for a heap with an out of place element\n * at position ``elt``. This works with a heap pair where heap1 carries\n * the weights and heap2 holds the corresponding elements.\n */\nfunction siftDown(heap1, heap2, ceiling, elt) {\n while (elt * 2 + 1 < ceiling) {\n const leftChild = elt * 2 + 1;\n const rightChild = leftChild + 1;\n let swap = elt;\n if (heap1[swap] < heap1[leftChild]) {\n swap = leftChild;\n }\n if (rightChild < ceiling && heap1[swap] < heap1[rightChild]) {\n swap = rightChild;\n }\n if (swap === elt) {\n break;\n }\n else {\n const temp1 = heap1[elt];\n heap1[elt] = heap1[swap];\n heap1[swap] = temp1;\n const temp2 = heap2[elt];\n heap2[elt] = heap2[swap];\n heap2[swap] = temp2;\n elt = swap;\n }\n }\n}\n/**\n * Search the heap for the smallest element that is still flagged.\n */\nexport function smallestFlagged(heap, row) {\n const ind = heap[0][row];\n const dist = heap[1][row];\n const flag = heap[2][row];\n let minDist = Infinity;\n let resultIndex = -1;\n for (let i = 0; i > ind.length; i++) {\n if (flag[i] === 1 && dist[i] < minDist) {\n minDist = dist[i];\n resultIndex = i;\n }\n }\n if (resultIndex >= 0) {\n flag[resultIndex] = 0;\n return Math.floor(ind[resultIndex]);\n }\n else {\n return -1;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImhlYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBMkNILE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBSWpDOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSxRQUFRLENBQUMsT0FBZSxFQUFFLElBQVk7SUFDcEQsTUFBTSxVQUFVLEdBQUcsQ0FBQyxTQUFpQixFQUFFLEVBQUU7UUFDdkMsT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDbkMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQztJQUVGLE1BQU0sSUFBSSxHQUFTLEVBQUUsQ0FBQztJQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUIsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3pCLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsZUFBZSxDQUM3QixRQUFnQixFQUNoQixRQUFnQixFQUNoQixNQUFnQjtJQUVoQixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3JDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDakMsSUFBSSxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxHQUFHLENBQUMs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SSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUUxQixJQUFJLE9BQU8sR0FBRyxRQUFRLENBQUM7SUFDdkIsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFckIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDbkMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLEVBQUU7WUFDdEMsT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNsQixXQUFXLEdBQUcsQ0FBQyxDQUFDO1NBQ2pCO0tBQ0Y7SUFFRCxJQUFJLFdBQVcsSUFBSSxDQUFDLEVBQUU7UUFDcEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN0QixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7S0FDckM7U0FBTTtRQUNMLE9BQU8sQ0FBQyxDQUFDLENBQUM7S0FDWDtBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vKipcbiAqIFRoaXMgaXMgYSBKYXZhU2NyaXB0IHJlaW1wbGVtZW50YXRpb24gb2YgVU1BUCAob3JpZ2luYWwgbGljZW5zZSBiZWxvdyksIGZyb21cbiAqIHRoZSBweXRob24gaW1wbGVtZW50YXRpb24gZm91bmQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2xtY2lubmVzL3VtYXAuXG4gKlxuICogQGF1dGhvciBhbmR5Y29lbmVuQGdvb2dsZS5jb20gKEFuZHkgQ29lbmVuKVxuICovXG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIEJTRCAzLUNsYXVzZSBMaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDE3LCBMZWxhbmQgTWNJbm5lc1xuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4gKiAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gKiAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqICogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0c1xuICogICBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbVxuICogICB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEVcbiAqIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMXG4gKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUlxuICogU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVJcbiAqIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksXG4gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRVxuICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5pbXBvcnQgeyBSYW5kb21GbiB9IGZyb20gJy4vdW1hcCc7XG5pbXBvcnQgKiBhcyB1dGlscyBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IHR5cGUgSGVhcCA9IG51bWJlcltdW11bXTtcblxuLyoqXG4gKiAgQ29uc3RydWN0b3IgZm9yIHRoZSBoZWFwIG9iamVjdHMuIFRoZSBoZWFwcyBhcmUgdXNlZFxuICogZm9yIGFwcHJveGltYXRlIG5lYXJlc3QgbmVpZ2hib3Igc2VhcmNoLCBtYWludGFpbmluZyBhIGxpc3Qgb2YgcG90ZW50aWFsXG4gKiBuZWlnaGJvcnMgc29ydGVkIGJ5IHRoZWlyIGRpc3RhbmNlLiBXZSBhbHNvIGZsYWcgaWYgcG90ZW50aWFsIG5laWdoYm9yc1xuICogYXJlIG5ld2x5IGFkZGVkIHRvIHRoZSBsaXN0IG9yIG5vdC4gSW50ZXJuYWxseSB0aGlzIGlzIHN0b3JlZCBhc1xuICogYSBzaW5nbGUgYXJyYXk7IHRoZSBmaXJzdCBheGlzIGRldGVybWluZXMgd2hldGhlciB3ZSBhcmUgbG9va2luZyBhdCB0aGVcbiAqIGFycmF5IG9mIGNhbmRpZGF0ZSBpbmRpY2VzLCB0aGUgYXJyYXkgb2YgZGlzdGFuY2VzLCBvciB0aGUgZmxhZyBhcnJheSBmb3JcbiAqIHdoZXRoZXIgZWxlbWVudHMgYXJlIG5ldyBvciBub3QuIEVhY2ggb2YgdGhlc2UgYXJyYXlzIGFyZSBvZiBzaGFwZVxuICogKGBgblBvaW50c2BgLCBgYHNpemVgYClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VIZWFwKG5Qb2ludHM6IG51bWJlciwgc2l6ZTogbnVtYmVyKTogSGVhcCB7XG4gIGNvbnN0IG1ha2VBcnJheXMgPSAoZmlsbFZhbHVlOiBudW1iZXIpID0+IHtcbiAgICByZXR1cm4gdXRpbHMuZW1wdHkoblBvaW50cykubWFwKCgpID0+IHtcbiAgICAgIHJldHVybiB1dGlscy5maWxsZWQoc2l6ZSwgZmlsbFZhbHVlKTtcbiAgICB9KTtcbiAgfTtcblxuICBjb25zdCBoZWFwOiBIZWFwID0gW107XG4gIGhlYXAucHVzaChtYWtlQXJyYXlzKC0xKSk7XG4gIGhlYXAucHVzaChtYWtlQXJyYXlzKEluZmluaXR5KSk7XG4gIGhlYXAucHVzaChtYWtlQXJyYXlzKDApKTtcbiAgcmV0dXJuIGhlYXA7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgbl9zYW1wbGVzIG1hbnkgaW50ZWdlcnMgZnJvbSAwIHRvIHBvb2xfc2l6ZSBzdWNoIHRoYXQgbm9cbiAqIGludGVnZXIgaXMgc2VsZWN0ZWQgdHdpY2UuIFRoZSBkdXBsaWNhdGlvbiBjb25zdHJhaW50IGlzIGFjaGlldmVkIHZpYVxuICogcmVqZWN0aW9uIHNhbXBsaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVqZWN0aW9uU2FtcGxlKFxuICBuU2FtcGxlczogbnVtYmVyLFxuICBwb29sU2l6ZTogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pIHtcbiAgY29uc3QgcmVzdWx0ID0gdXRpbHMuemVyb3MoblNhbXBsZXMpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG5TYW1wbGVzOyBpKyspIHtcbiAgICBsZXQgcmVqZWN0U2FtcGxlID0gdHJ1ZTtcbiAgICBsZXQgaiA9IDA7XG4gICAgd2hpbGUgKHJlamVjdFNhbXBsZSkge1xuICAgICAgaiA9IHV0aWxzLnRhdVJhbmRJbnQocG9vbFNpemUsIHJhbmRvbSk7XG4gICAgICBsZXQgYnJva2VuID0gZmFsc2U7XG4gICAgICBmb3IgKGxldCBrID0gMDsgayA8IGk7IGsrKykge1xuICAgICAgICBpZiAoaiA9PT0gcmVzdWx0W2tdKSB7XG4gICAgICAgICAgYnJva2VuID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCFicm9rZW4pIHJlamVjdFNhbXBsZSA9IGZhbHNlO1xuICAgIH1cbiAgICByZXN1bHRbaV0gPSBqO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogUHVzaCBhIG5ldyBlbGVtZW50IG9udG8gdGhlIGhlYXAuIFRoZSBoZWFwIHN0b3JlcyBwb3RlbnRpYWwgbmVpZ2hib3JzXG4gKiBmb3IgZWFjaCBkYXRhIHBvaW50LiBUaGUgYGByb3dgYCBwYXJhbWV0ZXIgZGV0ZXJtaW5lcyB3aGljaCBkYXRhIHBvaW50IHdlXG4gKiBhcmUgYWRkcmVzc2luZywgdGhlIGBgd2VpZ2h0YGAgZGV0ZXJtaW5lcyB0aGUgZGlzdGFuY2UgKGZvciBoZWFwIHNvcnRpbmcpLFxuICogdGhlIGBgaW5kZXhgYCBpcyB0aGUgZWxlbWVudCB0byBhZGQsIGFuZCB0aGUgZmxhZyBkZXRlcm1pbmVzIHdoZXRoZXIgdGhpc1xuICogaXMgdG8gYmUgY29uc2lkZXJlZCBhIG5ldyBhZGRpdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhlYXBQdXNoKFxuICBoZWFwOiBIZWFwLFxuICByb3c6IG51bWJlcixcbiAgd2VpZ2h0OiBudW1iZXIsXG4gIGluZGV4OiBudW1iZXIsXG4gIGZsYWc6IG51bWJlclxuKTogbnVtYmVyIHtcbiAgcm93ID0gTWF0aC5mbG9vcihyb3cpO1xuICBjb25zdCBpbmRpY2VzID0gaGVhcFswXVtyb3ddO1xuICBjb25zdCB3ZWlnaHRzID0gaGVhcFsxXVtyb3ddO1xuICBjb25zdCBpc05ldyA9IGhlYXBbMl1bcm93XTtcblxuICBpZiAod2VpZ2h0ID49IHdlaWdodHNbMF0pIHtcbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIC8vIEJyZWFrIGlmIHdlIGFscmVhZHkgaGF2ZSB0aGlzIGVsZW1lbnQuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChpbmRleCA9PT0gaW5kaWNlc1tpXSkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVuY2hlY2tlZEhlYXBQdXNoKGhlYXAsIHJvdywgd2VpZ2h0LCBpbmRleCwgZmxhZyk7XG59XG5cbi8qKlxuICogUHVzaCBhIG5ldyBlbGVtZW50IG9udG8gdGhlIGhlYXAuIFRoZSBoZWFwIHN0b3JlcyBwb3RlbnRpYWwgbmVpZ2hib3JzXG4gKiBmb3IgZWFjaCBkYXRhIHBvaW50LiBUaGUgYGByb3dgYCBwYXJhbWV0ZXIgZGV0ZXJtaW5lcyB3aGljaCBkYXRhIHBvaW50IHdlXG4gKiBhcmUgYWRkcmVzc2luZywgdGhlIGBgd2VpZ2h0YGAgZGV0ZXJtaW5lcyB0aGUgZGlzdGFuY2UgKGZvciBoZWFwIHNvcnRpbmcpLFxuICogdGhlIGBgaW5kZXhgYCBpcyB0aGUgZWxlbWVudCB0byBhZGQsIGFuZCB0aGUgZmxhZyBkZXRlcm1pbmVzIHdoZXRoZXIgdGhpc1xuICogaXMgdG8gYmUgY29uc2lkZXJlZCBhIG5ldyBhZGRpdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVuY2hlY2tlZEhlYXBQdXNoKFxuICBoZWFwOiBIZWFwLFxuICByb3c6IG51bWJlcixcbiAgd2VpZ2h0OiBudW1iZXIsXG4gIGluZGV4OiBudW1iZXIsXG4gIGZsYWc6IG51bWJlclxuKTogbnVtYmVyIHtcbiAgY29uc3QgaW5kaWNlcyA9IGhlYXBbMF1bcm93XTtcbiAgY29uc3Qgd2VpZ2h0cyA9IGhlYXBbMV1bcm93XTtcbiAgY29uc3QgaXNOZXcgPSBoZWFwWzJdW3Jvd107XG5cbiAgaWYgKHdlaWdodCA+PSB3ZWlnaHRzWzBdKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICAvLyBJbnNlcnQgdmFsIGF0IHBvc2l0aW9uIHplcm9cbiAgd2VpZ2h0c1swXSA9IHdlaWdodDtcbiAgaW5kaWNlc1swXSA9IGluZGV4O1xuICBpc05ld1swXSA9IGZsYWc7XG5cbiAgLy8gRGVzY2VuZCB0aGUgaGVhcCwgc3dhcHBpbmcgdmFsdWVzIHVudGlsIHRoZSBtYXggaGVhcCBjcml0ZXJpb24gaXMgbWV0XG4gIGxldCBpID0gMDtcbiAgbGV0IGlTd2FwID0gMDtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBjb25zdCBpYzEgPSAyICogaSArIDE7XG4gICAgY29uc3QgaWMyID0gaWMxICsgMTtcblxuICAgIGNvbnN0IGhlYXBTaGFwZTIgPSBoZWFwWzBdWzBdLmxlbmd0aDtcbiAgICBpZiAoaWMxID49IGhlYXBTaGFwZTIpIHtcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSBpZiAoaWMyID49IGhlYXBTaGFwZTIpIHtcbiAgICAgIGlmICh3ZWlnaHRzW2ljMV0gPiB3ZWlnaHQpIHtcbiAgICAgICAgaVN3YXAgPSBpYzE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHdlaWdodHNbaWMxXSA+PSB3ZWlnaHRzW2ljMl0pIHtcbiAgICAgIGlmICh3ZWlnaHQgPCB3ZWlnaHRzW2ljMV0pIHtcbiAgICAgICAgaVN3YXAgPSBpYzE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHdlaWdodCA8IHdlaWdodHNbaWMyXSkge1xuICAgICAgICBpU3dhcCA9IGljMjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHdlaWdodHNbaV0gPSB3ZWlnaHRzW2lTd2FwXTtcbiAgICBpbmRpY2VzW2ldID0gaW5kaWNlc1tpU3dhcF07XG4gICAgaXNOZXdbaV0gPSBpc05ld1tpU3dhcF07XG5cbiAgICBpID0gaVN3YXA7XG4gIH1cblxuICB3ZWlnaHRzW2ldID0gd2VpZ2h0O1xuICBpbmRpY2VzW2ldID0gaW5kZXg7XG4gIGlzTmV3W2ldID0gZmxhZztcbiAgcmV0dXJuIDE7XG59XG5cbi8qKlxuICogQnVpbGQgYSBoZWFwIG9mIGNhbmRpZGF0ZSBuZWlnaGJvcnMgZm9yIG5lYXJlc3QgbmVpZ2hib3IgZGVzY2VudC4gRm9yXG4gKiBlYWNoIHZlcnRleCB0aGUgY2FuZGlkYXRlIG5laWdoYm9ycyBhcmUgYW55IGN1cnJlbnQgbmVpZ2hib3JzLCBhbmQgYW55XG4gKiB2ZXJ0aWNlcyB0aGF0IGhhdmUgdGhlIHZlcnRleCBhcyBvbmUgb2YgdGhlaXIgbmVhcmVzdCBuZWlnaGJvcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZENhbmRpZGF0ZXMoXG4gIGN1cnJlbnRHcmFwaDogSGVhcCxcbiAgblZlcnRpY2VzOiBudW1iZXIsXG4gIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgbWF4Q2FuZGlkYXRlczogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pIHtcbiAgY29uc3QgY2FuZGlkYXRlTmVpZ2hib3JzID0gbWFrZUhlYXAoblZlcnRpY2VzLCBtYXhDYW5kaWRhdGVzKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuVmVydGljZXM7IGkrKykge1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgbk5laWdoYm9yczsgaisrKSB7XG4gICAgICBpZiAoY3VycmVudEdyYXBoWzBdW2ldW2pdIDwgMCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGlkeCA9IGN1cnJlbnRHcmFwaFswXVtpXVtqXTtcbiAgICAgIGNvbnN0IGlzbiA9IGN1cnJlbnRHcmFwaFsyXVtpXVtqXTtcbiAgICAgIGNvbnN0IGQgPSB1dGlscy50YXVSYW5kKHJhbmRvbSk7XG4gICAgICBoZWFwUHVzaChjYW5kaWRhdGVOZWlnaGJvcnMsIGksIGQsIGlkeCwgaXNuKTtcbiAgICAgIGhlYXBQdXNoKGNhbmRpZGF0ZU5laWdoYm9ycywgaWR4LCBkLCBpLCBpc24pO1xuICAgICAgY3VycmVudEdyYXBoWzJdW2ldW2pdID0gMDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNhbmRpZGF0ZU5laWdoYm9ycztcbn1cblxuLyoqXG4gKiBHaXZlbiBhbiBhcnJheSBvZiBoZWFwcyAob2YgaW5kaWNlcyBhbmQgd2VpZ2h0cyksIHVucGFjayB0aGUgaGVhcFxuICogb3V0IHRvIGdpdmUgYW5kIGFycmF5IG9mIHNvcnRlZCBsaXN0cyBvZiBpbmRpY2VzIGFuZCB3ZWlnaHRzIGJ5IGluY3JlYXNpbmdcbiAqIHdlaWdodC4gVGhpcyBpcyBlZmZlY3RpdmVseSBqdXN0IHRoZSBzZWNvbmQgaGFsZiBvZiBoZWFwIHNvcnQgKHRoZSBmaXJzdFxuICogaGFsZiBub3QgYmVpbmcgcmVxdWlyZWQgc2luY2Ugd2UgYWxyZWFkeSBoYXZlIHRoZSBkYXRhIGluIGEgaGVhcCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWhlYXBTb3J0KGhlYXA6IEhlYXApIHtcbiAgY29uc3QgaW5kaWNlcyA9IGhlYXBbMF07XG4gIGNvbnN0IHdlaWdodHMgPSBoZWFwWzFdO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGluZEhlYXAgPSBpbmRpY2VzW2ldO1xuICAgIGNvbnN0IGRpc3RIZWFwID0gd2VpZ2h0c1tpXTtcblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kSGVhcC5sZW5ndGggLSAxOyBqKyspIHtcbiAgICAgIGNvbnN0IGluZEhlYXBJbmRleCA9IGluZEhlYXAubGVuZ3RoIC0gaiAtIDE7XG4gICAgICBjb25zdCBkaXN0SGVhcEluZGV4ID0gZGlzdEhlYXAubGVuZ3RoIC0gaiAtIDE7XG5cbiAgICAgIGNvbnN0IHRlbXAxID0gaW5kSGVhcFswXTtcbiAgICAgIGluZEhlYXBbMF0gPSBpbmRIZWFwW2luZEhlYXBJbmRleF07XG4gICAgICBpbmRIZWFwW2luZEhlYXBJbmRleF0gPSB0ZW1wMTtcblxuICAgICAgY29uc3QgdGVtcDIgPSBkaXN0SGVhcFswXTtcbiAgICAgIGRpc3RIZWFwWzBdID0gZGlzdEhlYXBbZGlzdEhlYXBJbmRleF07XG4gICAgICBkaXN0SGVhcFtkaXN0SGVhcEluZGV4XSA9IHRlbXAyO1xuXG4gICAgICBzaWZ0RG93bihkaXN0SGVhcCwgaW5kSGVhcCwgZGlzdEhlYXBJbmRleCwgMCk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7IGluZGljZXMsIHdlaWdodHMgfTtcbn1cblxuLyoqXG4gKiBSZXN0b3JlIHRoZSBoZWFwIHByb3BlcnR5IGZvciBhIGhlYXAgd2l0aCBhbiBvdXQgb2YgcGxhY2UgZWxlbWVudFxuICogYXQgcG9zaXRpb24gYGBlbHRgYC4gVGhpcyB3b3JrcyB3aXRoIGEgaGVhcCBwYWlyIHdoZXJlIGhlYXAxIGNhcnJpZXNcbiAqIHRoZSB3ZWlnaHRzIGFuZCBoZWFwMiBob2xkcyB0aGUgY29ycmVzcG9uZGluZyBlbGVtZW50cy5cbiAqL1xuZnVuY3Rpb24gc2lmdERvd24oXG4gIGhlYXAxOiBudW1iZXJbXSxcbiAgaGVhcDI6IG51bWJlcltdLFxuICBjZWlsaW5nOiBudW1iZXIsXG4gIGVsdDogbnVtYmVyXG4pIHtcbiAgd2hpbGUgKGVsdCAqIDIgKyAxIDwgY2VpbGluZykge1xuICAgIGNvbnN0IGxlZnRDaGlsZCA9IGVsdCAqIDIgKyAxO1xuICAgIGNvbnN0IHJpZ2h0Q2hpbGQgPSBsZWZ0Q2hpbGQgKyAxO1xuICAgIGxldCBzd2FwID0gZWx0O1xuXG4gICAgaWYgKGhlYXAxW3N3YXBdIDwgaGVhcDFbbGVmdENoaWxkXSkge1xuICAgICAgc3dhcCA9IGxlZnRDaGlsZDtcbiAgICB9XG4gICAgaWYgKHJpZ2h0Q2hpbGQgPCBjZWlsaW5nICYmIGhlYXAxW3N3YXBdIDwgaGVhcDFbcmlnaHRDaGlsZF0pIHtcbiAgICAgIHN3YXAgPSByaWdodENoaWxkO1xuICAgIH1cblxuICAgIGlmIChzd2FwID09PSBlbHQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0ZW1wMSA9IGhlYXAxW2VsdF07XG4gICAgICBoZWFwMVtlbHRdID0gaGVhcDFbc3dhcF07XG4gICAgICBoZWFwMVtzd2FwXSA9IHRlbXAxO1xuXG4gICAgICBjb25zdCB0ZW1wMiA9IGhlYXAyW2VsdF07XG4gICAgICBoZWFwMltlbHRdID0gaGVhcDJbc3dhcF07XG4gICAgICBoZWFwMltzd2FwXSA9IHRlbXAyO1xuICAgICAgZWx0ID0gc3dhcDtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBTZWFyY2ggdGhlIGhlYXAgZm9yIHRoZSBzbWFsbGVzdCBlbGVtZW50IHRoYXQgaXMgc3RpbGwgZmxhZ2dlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNtYWxsZXN0RmxhZ2dlZChoZWFwOiBIZWFwLCByb3c6IG51bWJlcikge1xuICBjb25zdCBpbmQgPSBoZWFwWzBdW3Jvd107XG4gIGNvbnN0IGRpc3QgPSBoZWFwWzFdW3Jvd107XG4gIGNvbnN0IGZsYWcgPSBoZWFwWzJdW3Jvd107XG5cbiAgbGV0IG1pbkRpc3QgPSBJbmZpbml0eTtcbiAgbGV0IHJlc3VsdEluZGV4ID0gLTE7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPiBpbmQubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoZmxhZ1tpXSA9PT0gMSAmJiBkaXN0W2ldIDwgbWluRGlzdCkge1xuICAgICAgbWluRGlzdCA9IGRpc3RbaV07XG4gICAgICByZXN1bHRJbmRleCA9IGk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHJlc3VsdEluZGV4ID49IDApIHtcbiAgICBmbGFnW3Jlc3VsdEluZGV4XSA9IDA7XG4gICAgcmV0dXJuIE1hdGguZmxvb3IoaW5kW3Jlc3VsdEluZGV4XSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG59XG4iXX0=","/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\nimport * as utils from './utils';\n/**\n * Internal 2-dimensional sparse matrix class\n */\nexport class SparseMatrix {\n constructor(rows, cols, values, dims) {\n this.entries = new Map();\n this.nRows = 0;\n this.nCols = 0;\n if (rows.length !== cols.length || rows.length !== values.length) {\n throw new Error('rows, cols and values arrays must all have the same length');\n }\n // TODO: Assert that dims are legit.\n this.nRows = dims[0];\n this.nCols = dims[1];\n for (let i = 0; i < values.length; i++) {\n const row = rows[i];\n const col = cols[i];\n this.checkDims(row, col);\n const key = this.makeKey(row, col);\n this.entries.set(key, { value: values[i], row, col });\n }\n }\n makeKey(row, col) {\n return `${row}:${col}`;\n }\n checkDims(row, col) {\n const withinBounds = row < this.nRows && col < this.nCols;\n if (!withinBounds) {\n throw new Error('row and/or col specified outside of matrix dimensions');\n }\n }\n set(row, col, value) {\n this.checkDims(row, col);\n const key = this.makeKey(row, col);\n if (!this.entries.has(key)) {\n this.entries.set(key, { value, row, col });\n }\n else {\n this.entries.get(key).value = value;\n }\n }\n get(row, col, defaultValue = 0) {\n //this.checkDims(row, col);\n const key = this.makeKey(row, col);\n if (this.entries.has(key)) {\n return this.entries.get(key).value;\n }\n else {\n return defaultValue;\n }\n }\n getAll(ordered = true) {\n const rowColValues = new Array(this.entries.size).fill(null);\n let i = 0;\n this.entries.forEach(value => {\n rowColValues[i++] = value;\n });\n if (ordered) {\n // Ordering the result isn't required for processing but it does make it easier to write tests\n rowColValues.sort((a, b) => {\n if (a.row === b.row) {\n return a.col - b.col;\n }\n else {\n return a.row - b.row;\n }\n });\n }\n return rowColValues;\n }\n getDims() {\n return [this.nRows, this.nCols];\n }\n getRows() {\n return Array.from(this.entries, ([key, value]) => value.row);\n // return this.rows as unknown as number[];\n }\n getCols() {\n return Array.from(this.entries, ([key, value]) => value.col);\n // return this.cols as unknown as number[];\n }\n getValues() {\n return Array.from(this.entries, ([key, value]) => value.value);\n //return this.values as unknown as number[];\n }\n forEach(fn) {\n this.entries.forEach(value => fn(value.value, value.row, value.col));\n }\n map(fn) {\n const vals = new Float32Array(this.entries.size);\n let i = 0;\n this.entries.forEach(value => {\n vals[i++] = fn(value.value, value.row, value.col);\n });\n const dims = [this.nRows, this.nCols];\n return new SparseMatrix(this.getRows(), this.getCols(), vals, dims);\n }\n toArray() {\n const rows = utils.empty(this.nRows);\n const output = rows.map(() => {\n return utils.zeros(this.nCols);\n });\n this.entries.forEach(value => {\n output[value.row][value.col] = value.value;\n });\n return output;\n }\n}\n/**\n * Transpose a sparse matrix\n */\nexport function transpose(matrix) {\n const oldRows = matrix.getRows();\n const oldCols = matrix.getCols();\n const oldVals = matrix.getValues();\n const matlen = oldCols.length;\n const cols = new Int32Array(matlen);\n const rows = new Int32Array(matlen);\n const vals = new Float32Array(matlen);\n cols.set(oldRows);\n rows.set(oldCols);\n vals.set(oldVals);\n const dims = [matrix.nCols, matrix.nRows];\n return new SparseMatrix(rows, cols, vals, dims);\n}\n/**\n * Construct a sparse identity matrix\n */\nexport function identity(size) {\n const [rows] = size;\n const matrix = new SparseMatrix([], [], [], size);\n for (let i = 0; i < rows; i++) {\n matrix.set(i, i, 1);\n }\n return matrix;\n}\n/**\n * Element-wise multiplication of two matrices\n */\nexport function pairwiseMultiply(a, b) {\n return elementWise(a, b, (x, y) => x * y);\n}\n/**\n * Element-wise addition of two matrices\n */\nexport function add(a, b) {\n return elementWise(a, b, (x, y) => x + y);\n}\n/**\n * Element-wise subtraction of two matrices\n */\nexport function subtract(a, b) {\n return elementWise(a, b, (x, y) => x - y);\n}\n/**\n * Element-wise maximum of two matrices\n */\nexport function maximum(a, b) {\n return elementWise(a, b, (x, y) => (x > y ? x : y));\n}\n/**\n * Scalar multiplication of two matrices\n */\nexport function multiplyScalar(a, scalar) {\n return a.map((value) => {\n return value * scalar;\n });\n}\n/**\n * Returns a new matrix with zero entries removed.\n */\nexport function eliminateZeros(m) {\n const zeroIndices = new Set();\n const values = m.getValues();\n const rows = m.getRows();\n const cols = m.getCols();\n for (let i = 0; i < values.length; i++) {\n if (values[i] === 0) {\n zeroIndices.add(i);\n }\n }\n const removeByZeroIndex = (_, index) => !zeroIndices.has(index);\n const nextValues = values.filter(removeByZeroIndex);\n const nextRows = rows.filter(removeByZeroIndex);\n const nextCols = cols.filter(removeByZeroIndex);\n return new SparseMatrix(nextRows, nextCols, nextValues, m.getDims());\n}\n/**\n * Normalization of a sparse matrix.\n */\nexport function normalize(m, normType = \"l2\" /* NormType.l2 */) {\n const normFn = normFns[normType];\n const colsByRow = new Map();\n m.forEach((_, row, col) => {\n const cols = colsByRow.get(row) || [];\n cols.push(col);\n colsByRow.set(row, cols);\n });\n const nextMatrix = new SparseMatrix([], [], [], m.getDims());\n for (let row of colsByRow.keys()) {\n const cols = colsByRow.get(row).sort();\n const vals = cols.map(col => m.get(row, col));\n const norm = normFn(vals);\n for (let i = 0; i < norm.length; i++) {\n nextMatrix.set(row, cols[i], norm[i]);\n }\n }\n return nextMatrix;\n}\nconst normFns = {\n [\"max\" /* NormType.max */]: (xs) => {\n let max = -Infinity;\n for (let i = 0; i < xs.length; i++) {\n max = xs[i] > max ? xs[i] : max;\n }\n return xs.map(x => x / max);\n },\n [\"l1\" /* NormType.l1 */]: (xs) => {\n let sum = 0;\n for (let i = 0; i < xs.length; i++) {\n sum += xs[i];\n }\n return xs.map(x => x / sum);\n },\n [\"l2\" /* NormType.l2 */]: (xs) => {\n let sum = 0;\n for (let i = 0; i < xs.length; i++) {\n sum += xs[i] ** 2;\n }\n return xs.map(x => Math.sqrt(x ** 2 / sum));\n },\n};\n/**\n * Helper function for element-wise operations.\n */\nfunction elementWise(a, b, op) {\n const visited = new Set();\n const rows = [];\n const cols = [];\n const vals = [];\n const operate = (row, col) => {\n rows.push(row);\n cols.push(col);\n const nextValue = op(a.get(row, col), b.get(row, col));\n vals.push(nextValue);\n };\n const valuesA = a.getValues();\n const rowsA = a.getRows();\n const colsA = a.getCols();\n for (let i = 0; i < valuesA.length; i++) {\n const row = rowsA[i];\n const col = colsA[i];\n const key = `${row}:${col}`;\n visited.add(key);\n operate(row, col);\n }\n const valuesB = b.getValues();\n const rowsB = b.getRows();\n const colsB = b.getCols();\n for (let i = 0; i < valuesB.length; i++) {\n const row = rowsB[i];\n const col = colsB[i];\n const key = `${row}:${col}`;\n if (visited.has(key))\n continue;\n operate(row, col);\n }\n const dims = [a.nRows, a.nCols];\n return new SparseMatrix(rows, cols, vals, dims);\n}\n/**\n * Helper function for getting data, indices, and inptr arrays from a sparse\n * matrix to follow csr matrix conventions. Super inefficient (and kind of\n * defeats the purpose of this convention) but a lot of the ported python tree\n * search logic depends on this data format.\n */\nexport function getCSR(x) {\n const entries = [];\n x.forEach((value, row, col) => {\n entries.push({ value, row, col });\n });\n entries.sort((a, b) => {\n if (a.row === b.row) {\n return a.col - b.col;\n }\n else {\n return a.row - b.row;\n }\n });\n const indices = [];\n const values = [];\n const indptr = [];\n let currentRow = -1;\n for (let i = 0; i < entries.length; i++) {\n const { row, col, value } = entries[i];\n if (row !== currentRow) {\n currentRow = row;\n indptr.push(i);\n }\n indices.push(col);\n values.push(value);\n }\n return { indices, values, indptr };\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0cml4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibWF0cml4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUVILE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBSWpDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFlBQVk7SUFNdkIsWUFDRSxJQUEyQixFQUMzQixJQUEyQixFQUMzQixNQUErQixFQUMvQixJQUFjO1FBVFIsWUFBTyxHQUFHLElBQUksR0FBRyxFQUFpQixDQUFDO1FBRWxDLFVBQUssR0FBVyxDQUFDLENBQUM7UUFDbEIsVUFBSyxHQUFXLENBQUMsQ0FBQztRQVF6QixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxNQUFNLEVBQUU7WUFDaEUsTUFBTSxJQUFJLEtBQUssQ0FDYiw0REFBNEQsQ0FDN0QsQ0FBQztTQUNIO1FBRUQsb0NBQW9DO1FBQ3BDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3RDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNwQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDcEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDekIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDbkMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxH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LElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzdELDJDQUEyQztJQUM1QyxDQUFDO0lBRUQsT0FBTztRQUNOLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM3RCwyQ0FBMkM7SUFDNUMsQ0FBQztJQUVELFNBQVM7UUFDVCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0QsNENBQTRDO0lBQzVDLENBQUM7SUFFRCxPQUFPLENBQUMsRUFBcUQ7UUFDM0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFFRCxHQUFHLENBQUMsRUFBdUQ7UUFDekQsTUFBTSxJQUFJLEdBQUcsSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDVCxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUMzQixJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNwRCxDQUFDLENBQUMsQ0FBQztRQUNI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QUVILE1BQU0sT0FBTyxHQUFhLEVBQUUsQ0FBQztJQUM3QixNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7SUFDNUIsTUFBTSxNQUFNLEdBQWEsRUFBRSxDQUFDO0lBRTVCLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3BCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ3ZDLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QyxJQUFJLEdBQUcsS0FBSyxVQUFVLEVBQUU7WUFDdEIsVUFBVSxHQUFHLEdBQUcsQ0FBQztZQUNqQixNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ2hCO1FBQ0QsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNsQixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQ3BCO0lBRUQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUM7QUFDckMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqXG4gKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5cbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuXG50eXBlIEVudHJ5ID0geyB2YWx1ZTogbnVtYmVyOyByb3c6IG51bWJlcjsgY29sOiBudW1iZXIgfTtcblxuLyoqXG4gKiBJbnRlcm5hbCAyLWRpbWVuc2lvbmFsIHNwYXJzZSBtYXRyaXggY2xhc3NcbiAqL1xuZXhwb3J0IGNsYXNzIFNwYXJzZU1hdHJpeCB7XG4gIHByaXZhdGUgZW50cmllcyA9IG5ldyBNYXA8c3RyaW5nLCBFbnRyeT4oKTtcblxuICByZWFkb25seSBuUm93czogbnVtYmVyID0gMDtcbiAgcmVhZG9ubHkgbkNvbHM6IG51bWJlciA9IDA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcm93czogbnVtYmVyW10gfCBJbnQzMkFycmF5LFxuICAgIGNvbHM6IG51bWJlcltdIHwgSW50MzJBcnJheSxcbiAgICB2YWx1ZXM6IG51bWJlcltdIHwgRmxvYXQzMkFycmF5LFxuICAgIGRpbXM6IG51bWJlcltdXG4gICkge1xuICAgIGlmIChyb3dzLmxlbmd0aCAhPT0gY29scy5sZW5ndGggfHwgcm93cy5sZW5ndGggIT09IHZhbHVlcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ3Jvd3MsIGNvbHMgYW5kIHZhbHVlcyBhcnJheXMgbXVzdCBhbGwgaGF2ZSB0aGUgc2FtZSBsZW5ndGgnXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIFRPRE86IEFzc2VydCB0aGF0IGRpbXMgYXJlIGxlZ2l0LlxuICAgIHRoaXMublJvd3MgPSBkaW1zWzBdO1xuICAgIHRoaXMubkNvbHMgPSBkaW1zWzFdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCByb3cgPSByb3dzW2ldO1xuICAgICAgY29uc3QgY29sID0gY29sc1tpXTtcbiAgICAgIHRoaXMuY2hlY2tEaW1zKHJvdywgY29sKTtcbiAgICAgIGNvbnN0IGtleSA9IHRoaXMubWFrZUtleShyb3csIGNvbCk7XG4gICAgICB0aGlzLmVudHJpZXMuc2V0KGtleSwgeyB2YWx1ZTogdmFsdWVzW2ldLCByb3csIGNvbCB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1ha2VLZXkocm93OiBudW1iZXIsIGNvbDogbnVtYmVyKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCR7cm93fToke2NvbH1gO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0RpbXMocm93OiBudW1iZXIsIGNvbDogbnVtYmVyKSB7XG4gICAgY29uc3Qgd2l0aGluQm91bmRzID0gcm93IDwgdGhpcy5uUm93cyAmJiBjb2wgPCB0aGlzLm5Db2xzO1xuICAgIGlmICghd2l0aGluQm91bmRzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3JvdyBhbmQvb3IgY29sIHNwZWNpZmllZCBvdXRzaWRlIG9mIG1hdHJpeCBkaW1lbnNpb25zJyk7XG4gICAgfVxuICB9XG5cbiAgc2V0KHJvdzogbnVtYmVyLCBjb2w6IG51bWJlciwgdmFsdWU6IG51bWJlcikge1xuICAgIHRoaXMuY2hlY2tEaW1zKHJvdywgY29sKTtcbiAgICBjb25zdCBrZXkgPSB0aGlzLm1ha2VLZXkocm93LCBjb2wpO1xuICAgIGlmICghdGhpcy5lbnRyaWVzLmhhcyhrZXkpKSB7XG4gICAgICB0aGlzLmVudHJpZXMuc2V0KGtleSwgeyB2YWx1ZSwgcm93LCBjb2wgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW50cmllcy5nZXQoa2V5KSEudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICBnZXQocm93OiBudW1iZXIsIGNvbDogbnVtYmVyLCBkZWZhdWx0VmFsdWUgPSAwKSB7XG4gICAgLy90aGlzLmNoZWNrRGltcyhyb3csIGNvbCk7XG4gICAgY29uc3Qga2V5ID0gdGhpcy5tYWtlS2V5KHJvdywgY29sKTtcbiAgICBpZiAodGhpcy5lbnRyaWVzLmhhcyhrZXkpKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbnRyaWVzLmdldChrZXkpIS52YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICB9XG4gIH1cblxuICBnZXRBbGwob3JkZXJlZCA9IHRydWUpOiB7IHZhbHVlOiBudW1iZXI7IHJvdzogbnVtYmVyOyBjb2w6IG51bWJlciB9W10ge1xuICAgIGNvbnN0IHJvd0NvbFZhbHVlczogRW50cnlbXSA9IG5ldyBBcnJheSh0aGlzLmVudHJpZXMuc2l6ZSkuZmlsbChudWxsKTtcbiAgICBsZXQgaSA9IDA7XG4gICAgdGhpcy5lbnRyaWVzLmZvckVhY2godmFsdWUgPT4ge1xuICAgICAgcm93Q29sVmFsdWVzW2krK10gPSB2YWx1ZTtcbiAgICB9KTtcbiAgICBpZiAob3JkZXJlZCkge1xuICAgICAgLy8gT3JkZXJpbmcgdGhlIHJlc3VsdCBpc24ndCByZXF1aXJlZCBmb3IgcHJvY2Vzc2luZyBidXQgaXQgZG9lcyBtYWtlIGl0IGVhc2llciB0byB3cml0ZSB0ZXN0c1xuICAgICAgcm93Q29sVmFsdWVzLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgaWYgKGEucm93ID09PSBiLnJvdykge1xuICAgICAgICAgIHJldHVybiBhLmNvbCAtIGIuY29sO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBhLnJvdyAtIGIucm93O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHJvd0NvbFZhbHVlcztcbiAgfVxuXG4gIGdldERpbXMoKTogbnVtYmVyW10ge1xuICAgIHJldHVybiBbdGhpcy5uUm93cywgdGhpcy5uQ29sc107XG4gIH1cblxuICBnZXRSb3dzKCk6IG51bWJlcltdIHtcbiAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuZW50cmllcywgKFtrZXksIHZhbHVlXSkgPT4gdmFsdWUucm93KTtcbiAgIC8vIHJldHVybiB0aGlzLnJvd3MgYXMgdW5rbm93biBhcyBudW1iZXJbXTtcbiAgfVxuXG4gIGdldENvbHMoKTogbnVtYmVyW117XG4gICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmVudHJpZXMsIChba2V5LCB2YWx1ZV0pID0+IHZhbHVlLmNvbCk7XG4gICAvLyByZXR1cm4gdGhpcy5jb2xzIGFzIHVua25vd24gYXMgbnVtYmVyW107XG4gIH1cblxuICBnZXRWYWx1ZXMoKTogbnVtYmVyW10ge1xuICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmVudHJpZXMsIChba2V5LCB2YWx1ZV0pID0+IHZhbHVlLnZhbHVlKTtcbiAgLy9yZXR1cm4gdGhpcy52YWx1ZXMgYXMgdW5rbm93biBhcyBudW1iZXJbXTtcbiAgfVxuXG4gIGZvckVhY2goZm46ICh2YWx1ZTogbnVtYmVyLCByb3c6IG51bWJlciwgY29sOiBudW1iZXIpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLmVudHJpZXMuZm9yRWFjaCh2YWx1ZSA9PiBmbih2YWx1ZS52YWx1ZSwgdmFsdWUucm93LCB2YWx1ZS5jb2wpKTtcbiAgfVxuXG4gIG1hcChmbjogKHZhbHVlOiBudW1iZXIsIHJvdzogbnVtYmVyLCBjb2w6IG51bWJlcikgPT4gbnVtYmVyKTogU3BhcnNlTWF0cml4IHtcbiAgICBjb25zdCB2YWxzID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmVudHJpZXMuc2l6ZSk7XG4gICAgbGV0IGkgPSAwXG4gICAgdGhpcy5lbnRyaWVzLmZvckVhY2godmFsdWUgPT4ge1xuICAgICAgdmFsc1tpKytdID0gZm4odmFsdWUudmFsdWUsIHZhbHVlLnJvdywgdmFsdWUuY29sKTtcbiAgICB9KTtcbiAgICBjb25zdCBkaW1zID0gW3RoaXMublJvd3MsIHRoaXMubkNvbHNdO1xuICAgIHJldHVybiBuZXcgU3BhcnNlTWF0cml4KHRoaXMuZ2V0Um93cygpLCB0aGlzLmdldENvbHMoKSwgdmFscyBhcyB1bmtub3duIGFzIG51bWJlcltdLCBkaW1zKTtcbiAgfVxuXG4gIHRvQXJyYXkoKSB7XG4gICAgY29uc3Qgcm93czogdW5kZWZpbmVkW10gPSB1dGlscy5lbXB0eSh0aGlzLm5Sb3dzKTtcbiAgICBjb25zdCBvdXRwdXQgPSByb3dzLm1hcCgoKSA9PiB7XG4gICAgICByZXR1cm4gdXRpbHMuemVyb3ModGhpcy5uQ29scyk7XG4gICAgfSk7XG4gICAgdGhpcy5lbnRyaWVzLmZvckVhY2godmFsdWUgPT4ge1xuICAgICAgb3V0cHV0W3ZhbHVlLnJvd11bdmFsdWUuY29sXSA9IHZhbHVlLnZhbHVlO1xuICAgIH0pO1xuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cbn1cblxuLyoqXG4gKiBUcmFuc3Bvc2UgYSBzcGFyc2UgbWF0cml4XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc3Bvc2UobWF0cml4OiBTcGFyc2VNYXRyaXgpOiBTcGFyc2VNYXRyaXgge1xuICBjb25zdCBvbGRSb3dzID0gbWF0cml4LmdldFJvd3MoKTtcbiAgY29uc3Qgb2xkQ29scyA9IG1hdHJpeC5nZXRDb2xzKCk7XG4gIGNvbnN0IG9sZFZhbHMgPSBtYXRyaXguZ2V0VmFsdWVzKCk7XG4gIGNvbnN0IG1hdGxlbiA9IG9sZENvbHMubGVuZ3RoO1xuICBjb25zdCBjb2xzID0gbmV3IEludDMyQXJyYXkobWF0bGVuKTtcbiAgY29uc3Qgcm93cyA9IG5ldyBJbnQzMkFycmF5KG1hdGxlbik7XG4gIGNvbnN0IHZhbHMgPSBuZXcgRmxvYXQzMkFycmF5KG1hdGxlbik7XG5cbiAgY29scy5zZXQob2xkUm93cyk7XG4gIHJvd3Muc2V0KG9sZENvbHMpO1xuICB2YWxzLnNldChvbGRWYWxzKTtcbiAgY29uc3QgZGltcyA9IFttYXRyaXgubkNvbHMsIG1hdHJpeC5uUm93c107XG4gIHJldHVybiBuZXcgU3BhcnNlTWF0cml4KHJvd3MsIGNvbHMsIHZhbHMsIGRpbXMpO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdCBhIHNwYXJzZSBpZGVudGl0eSBtYXRyaXhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlkZW50aXR5KHNpemU6IG51bWJlcltdKTogU3BhcnNlTWF0cml4IHtcbiAgY29uc3QgW3Jvd3NdID0gc2l6ZTtcbiAgY29uc3QgbWF0cml4ID0gbmV3IFNwYXJzZU1hdHJpeChbXSwgW10sIFtdLCBzaXplKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzOyBpKyspIHtcbiAgICBtYXRyaXguc2V0KGksIGksIDEpO1xuICB9XG4gIHJldHVybiBtYXRyaXg7XG59XG5cbi8qKlxuICogRWxlbWVudC13aXNlIG11bHRpcGxpY2F0aW9uIG9mIHR3byBtYXRyaWNlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGFpcndpc2VNdWx0aXBseShcbiAgYTogU3BhcnNlTWF0cml4LFxuICBiOiBTcGFyc2VNYXRyaXhcbik6IFNwYXJzZU1hdHJpeCB7XG4gIHJldHVybiBlbGVtZW50V2lzZShhLCBiLCAoeCwgeSkgPT4geCAqIHkpO1xufVxuXG4vKipcbiAqIEVsZW1lbnQtd2lzZSBhZGRpdGlvbiBvZiB0d28gbWF0cmljZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZChhOiBTcGFyc2VNYXRyaXgsIGI6IFNwYXJzZU1hdHJpeCk6IFNwYXJzZU1hdHJpeCB7XG4gIHJldHVybiBlbGVtZW50V2lzZShhLCBiLCAoeCwgeSkgPT4geCArIHkpO1xufVxuXG4vKipcbiAqIEVsZW1lbnQtd2lzZSBzdWJ0cmFjdGlvbiBvZiB0d28gbWF0cmljZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN1YnRyYWN0KGE6IFNwYXJzZU1hdHJpeCwgYjogU3BhcnNlTWF0cml4KTogU3BhcnNlTWF0cml4IHtcbiAgcmV0dXJuIGVsZW1lbnRXaXNlKGEsIGIsICh4LCB5KSA9PiB4IC0geSk7XG59XG5cbi8qKlxuICogRWxlbWVudC13aXNlIG1heGltdW0gb2YgdHdvIG1hdHJpY2VzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXhpbXVtKGE6IFNwYXJzZU1hdHJpeCwgYjogU3BhcnNlTWF0cml4KTogU3BhcnNlTWF0cml4IHtcbiAgcmV0dXJuIGVsZW1lbnRXaXNlKGEsIGIsICh4LCB5KSA9PiAoeCA+IHkgPyB4IDogeSkpO1xufVxuXG4vKipcbiAqIFNjYWxhciBtdWx0aXBsaWNhdGlvbiBvZiB0d28gbWF0cmljZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGx5U2NhbGFyKGE6IFNwYXJzZU1hdHJpeCwgc2NhbGFyOiBudW1iZXIpOiBTcGFyc2VNYXRyaXgge1xuICByZXR1cm4gYS5tYXAoKHZhbHVlOiBudW1iZXIpID0+IHtcbiAgICByZXR1cm4gdmFsdWUgKiBzY2FsYXI7XG4gIH0pO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBuZXcgbWF0cml4IHdpdGggemVybyBlbnRyaWVzIHJlbW92ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbGltaW5hdGVaZXJvcyhtOiBTcGFyc2VNYXRyaXgpIHtcbiAgY29uc3QgemVyb0luZGljZXMgPSBuZXcgU2V0KCk7XG4gIGNvbnN0IHZhbHVlcyA9IG0uZ2V0VmFsdWVzKCk7XG4gIGNvbnN0IHJvd3MgPSBtLmdldFJvd3MoKTtcbiAgY29uc3QgY29scyA9IG0uZ2V0Q29scygpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgIGlmICh2YWx1ZXNbaV0gPT09IDApIHtcbiAgICAgIHplcm9JbmRpY2VzLmFkZChpKTtcbiAgICB9XG4gIH1cbiAgY29uc3QgcmVtb3ZlQnlaZXJvSW5kZXggPSAoXzogYW55LCBpbmRleDogbnVtYmVyKSA9PiAhemVyb0luZGljZXMuaGFzKGluZGV4KTtcbiAgY29uc3QgbmV4dFZhbHVlcyA9IHZhbHVlcy5maWx0ZXIocmVtb3ZlQnlaZXJvSW5kZXgpO1xuICBjb25zdCBuZXh0Um93cyA9IHJvd3MuZmlsdGVyKHJlbW92ZUJ5WmVyb0luZGV4KTtcbiAgY29uc3QgbmV4dENvbHMgPSBjb2xzLmZpbHRlcihyZW1vdmVCeVplcm9JbmRleCk7XG5cbiAgcmV0dXJuIG5ldyBTcGFyc2VNYXRyaXgobmV4dFJvd3MsIG5leHRDb2xzLCBuZXh0VmFsdWVzLCBtLmdldERpbXMoKSk7XG59XG5cbi8qKlxuICogTm9ybWFsaXphdGlvbiBvZiBhIHNwYXJzZSBtYXRyaXguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemUobTogU3BhcnNlTWF0cml4LCBub3JtVHlwZSA9IE5vcm1UeXBlLmwyKSB7XG4gIGNvbnN0IG5vcm1GbiA9IG5vcm1GbnNbbm9ybVR5cGVdO1xuXG4gIGNvbnN0IGNvbHNCeVJvdyA9IG5ldyBNYXA8bnVtYmVyLCBudW1iZXJbXT4oKTtcbiAgbS5mb3JFYWNoKChfLCByb3csIGNvbCkgPT4ge1xuICAgIGNvbnN0IGNvbHMgPSBjb2xzQnlSb3cuZ2V0KHJvdykgfHwgW107XG4gICAgY29scy5wdXNoKGNvbCk7XG4gICAgY29sc0J5Um93LnNldChyb3csIGNvbHMpO1xuICB9KTtcblxuICBjb25zdCBuZXh0TWF0cml4ID0gbmV3IFNwYXJzZU1hdHJpeChbXSwgW10sIFtdLCBtLmdldERpbXMoKSk7XG5cbiAgZm9yIChsZXQgcm93IG9mIGNvbHNCeVJvdy5rZXlzKCkpIHtcbiAgICBjb25zdCBjb2xzID0gY29sc0J5Um93LmdldChyb3cpIS5zb3J0KCk7XG5cbiAgICBjb25zdCB2YWxzID0gY29scy5tYXAoY29sID0+IG0uZ2V0KHJvdywgY29sKSk7XG4gICAgY29uc3Qgbm9ybSA9IG5vcm1Gbih2YWxzKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vcm0ubGVuZ3RoOyBpKyspIHtcbiAgICAgIG5leHRNYXRyaXguc2V0KHJvdywgY29sc1tpXSwgbm9ybVtpXSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5leHRNYXRyaXg7XG59XG5cbi8qKlxuICogVmVjdG9yIG5vcm1hbGl6YXRpb24gZnVuY3Rpb25zXG4gKi9cbnR5cGUgTm9ybUZucyA9IHsgW2tleSBpbiBOb3JtVHlwZV06ICh2OiBudW1iZXJbXSkgPT4gbnVtYmVyW10gfTtcbmNvbnN0IG5vcm1GbnM6IE5vcm1GbnMgPSB7XG4gIFtOb3JtVHlwZS5tYXhdOiAoeHM6IG51bWJlcltdKSA9PiB7XG4gICAgbGV0IG1heCA9IC1JbmZpbml0eTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBtYXggPSB4c1tpXSA+IG1heCA/IHhzW2ldIDogbWF4O1xuICAgIH1cbiAgICByZXR1cm4geHMubWFwKHggPT4geCAvIG1heCk7XG4gIH0sXG4gIFtOb3JtVHlwZS5sMV06ICh4czogbnVtYmVyW10pID0+IHtcbiAgICBsZXQgc3VtID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBzdW0gKz0geHNbaV07XG4gICAgfVxuICAgIHJldHVybiB4cy5tYXAoeCA9PiB4IC8gc3VtKTtcbiAgfSxcbiAgW05vcm1UeXBlLmwyXTogKHhzOiBudW1iZXJbXSkgPT4ge1xuICAgIGxldCBzdW0gPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHN1bSArPSB4c1tpXSAqKiAyO1xuICAgIH1cbiAgICByZXR1cm4geHMubWFwKHggPT4gTWF0aC5zcXJ0KHggKiogMiAvIHN1bSkpO1xuICB9LFxufTtcblxuZXhwb3J0IGNvbnN0IGVudW0gTm9ybVR5cGUge1xuICBtYXggPSAnbWF4JyxcbiAgbDEgPSAnbDEnLFxuICBsMiA9ICdsMicsXG59XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIGZvciBlbGVtZW50LXdpc2Ugb3BlcmF0aW9ucy5cbiAqL1xuZnVuY3Rpb24gZWxlbWVudFdpc2UoXG4gIGE6IFNwYXJzZU1hdHJpeCxcbiAgYjogU3BhcnNlTWF0cml4LFxuICBvcDogKHg6IG51bWJlciwgeTogbnVtYmVyKSA9PiBudW1iZXJcbik6IFNwYXJzZU1hdHJpeCB7XG4gIGNvbnN0IHZpc2l0ZWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgY29uc3Qgcm93czogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgY29sczogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgdmFsczogbnVtYmVyW10gPSBbXTtcblxuICBjb25zdCBvcGVyYXRlID0gKHJvdzogbnVtYmVyLCBjb2w6IG51bWJlcikgPT4ge1xuICAgIHJvd3MucHVzaChyb3cpO1xuICAgIGNvbHMucHVzaChjb2wpO1xuICAgIGNvbnN0IG5leHRWYWx1ZSA9IG9wKGEuZ2V0KHJvdywgY29sKSwgYi5nZXQocm93LCBjb2wpKTtcbiAgICB2YWxzLnB1c2gobmV4dFZhbHVlKTtcbiAgfTtcbiAgY29uc3QgdmFsdWVzQSA9IGEuZ2V0VmFsdWVzKCk7XG4gIGNvbnN0IHJvd3NBID0gYS5nZXRSb3dzKCk7XG4gIGNvbnN0IGNvbHNBID0gYS5nZXRDb2xzKCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzQS5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHJvdyA9IHJvd3NBW2ldO1xuICAgIGNvbnN0IGNvbCA9IGNvbHNBW2ldO1xuICAgIGNvbnN0IGtleSA9IGAke3Jvd306JHtjb2x9YDtcbiAgICB2aXNpdGVkLmFkZChrZXkpO1xuICAgIG9wZXJhdGUocm93LCBjb2wpO1xuICB9XG5cbiAgY29uc3QgdmFsdWVzQiA9IGIuZ2V0VmFsdWVzKCk7XG4gIGNvbnN0IHJvd3NCID0gYi5nZXRSb3dzKCk7XG4gIGNvbnN0IGNvbHNCID0gYi5nZXRDb2xzKCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzQi5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHJvdyA9IHJvd3NCW2ldO1xuICAgIGNvbnN0IGNvbCA9IGNvbHNCW2ldO1xuICAgIGNvbnN0IGtleSA9IGAke3Jvd306JHtjb2x9YDtcbiAgICBpZiAodmlzaXRlZC5oYXMoa2V5KSkgY29udGludWU7XG4gICAgb3BlcmF0ZShyb3csIGNvbCk7XG4gIH1cblxuICBjb25zdCBkaW1zID0gW2EublJvd3MsIGEubkNvbHNdO1xuICByZXR1cm4gbmV3IFNwYXJzZU1hdHJpeChyb3dzLCBjb2xzLCB2YWxzLCBkaW1zKTtcbn1cblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gZm9yIGdldHRpbmcgZGF0YSwgaW5kaWNlcywgYW5kIGlucHRyIGFycmF5cyBmcm9tIGEgc3BhcnNlXG4gKiBtYXRyaXggdG8gZm9sbG93IGNzciBtYXRyaXggY29udmVudGlvbnMuIFN1cGVyIGluZWZmaWNpZW50IChhbmQga2luZCBvZlxuICogZGVmZWF0cyB0aGUgcHVycG9zZSBvZiB0aGlzIGNvbnZlbnRpb24pIGJ1dCBhIGxvdCBvZiB0aGUgcG9ydGVkIHB5dGhvbiB0cmVlXG4gKiBzZWFyY2ggbG9naWMgZGVwZW5kcyBvbiB0aGlzIGRhdGEgZm9ybWF0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q1NSKHg6IFNwYXJzZU1hdHJpeCkge1xuICBjb25zdCBlbnRyaWVzOiBFbnRyeVtdID0gW107XG5cbiAgeC5mb3JFYWNoKCh2YWx1ZSwgcm93LCBjb2wpID0+IHtcbiAgICBlbnRyaWVzLnB1c2goeyB2YWx1ZSwgcm93LCBjb2wgfSk7XG4gIH0pO1xuXG4gIGVudHJpZXMuc29ydCgoYSwgYikgPT4ge1xuICAgIGlmIChhLnJvdyA9PT0gYi5yb3cpIHtcbiAgICAgIHJldHVybiBhLmNvbCAtIGIuY29sO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYS5yb3cgLSBiLnJvdztcbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IGluZGljZXM6IG51bWJlcltdID0gW107XG4gIGNvbnN0IHZhbHVlczogbnVtYmVyW10gPSBbXTtcbiAgY29uc3QgaW5kcHRyOiBudW1iZXJbXSA9IFtdO1xuXG4gIGxldCBjdXJyZW50Um93ID0gLTE7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZW50cmllcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHsgcm93LCBjb2wsIHZhbHVlIH0gPSBlbnRyaWVzW2ldO1xuICAgIGlmIChyb3cgIT09IGN1cnJlbnRSb3cpIHtcbiAgICAgIGN1cnJlbnRSb3cgPSByb3c7XG4gICAgICBpbmRwdHIucHVzaChpKTtcbiAgICB9XG4gICAgaW5kaWNlcy5wdXNoKGNvbCk7XG4gICAgdmFsdWVzLnB1c2godmFsdWUpO1xuICB9XG5cbiAgcmV0dXJuIHsgaW5kaWNlcywgdmFsdWVzLCBpbmRwdHIgfTtcbn1cbiJdfQ==","/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\n/**\n * This is a JavaScript reimplementation of UMAP (original license below), from\n * the python implementation found at https://github.com/lmcinnes/umap.\n *\n * @author andycoenen@google.com (Andy Coenen)\n */\n/**\n * @license\n * BSD 3-Clause License\n *\n * Copyright (c) 2017, Leland McInnes\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * * Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n *\n * * Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * * Neither the name of the copyright holder nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport * as utils from './utils';\nexport class FlatTree {\n constructor(hyperplanes, offsets, children, indices) {\n this.hyperplanes = hyperplanes;\n this.offsets = offsets;\n this.children = children;\n this.indices = indices;\n }\n}\n/**\n * Build a random projection forest with ``nTrees``.\n */\nexport function makeForest(data, nNeighbors, nTrees, random) {\n const leafSize = Math.max(10, nNeighbors);\n const trees = utils\n .range(nTrees)\n .map((_, i) => makeTree(data, leafSize, i, random));\n const forest = trees.map(tree => flattenTree(tree, leafSize));\n return forest;\n}\n/**\n * Construct a random projection tree based on ``data`` with leaves\n * of size at most ``leafSize``\n */\nfunction makeTree(data, leafSize = 30, n, random) {\n const indices = utils.range(data.length);\n const tree = makeEuclideanTree(data, indices, leafSize, n, random);\n return tree;\n}\nfunction makeEuclideanTree(data, indices, leafSize = 30, q, random) {\n if (indices.length > leafSize) {\n const splitResults = euclideanRandomProjectionSplit(data, indices, random);\n const { indicesLeft, indicesRight, hyperplane, offset } = splitResults;\n const leftChild = makeEuclideanTree(data, indicesLeft, leafSize, q + 1, random);\n const rightChild = makeEuclideanTree(data, indicesRight, leafSize, q + 1, random);\n const node = { leftChild, rightChild, isLeaf: false, hyperplane, offset };\n return node;\n }\n else {\n const node = { indices, isLeaf: true };\n return node;\n }\n}\n/**\n * Given a set of ``indices`` for data points from ``data``, create\n * a random hyperplane to split the data, returning two arrays indices\n * that fall on either side of the hyperplane. This is the basis for a\n * random projection tree, which simply uses this splitting recursively.\n * This particular split uses euclidean distance to determine the hyperplane\n * and which side each data sample falls on.\n */\nfunction euclideanRandomProjectionSplit(data, indices, random) {\n const dim = 1;\n // Select two random points, set the hyperplane between them\n let leftIndex = utils.tauRandInt(indices.length, random);\n let rightIndex = utils.tauRandInt(indices.length, random);\n rightIndex += leftIndex === rightIndex ? 1 : 0;\n rightIndex = rightIndex % indices.length;\n const left = indices[leftIndex];\n const right = indices[rightIndex];\n // Compute the normal vector to the hyperplane (the vector between the two\n // points) and the offset from the origin\n let hyperplaneOffset = 0;\n let hyperplaneVector = 0;\n hyperplaneVector = data[left] - data[right];\n hyperplaneOffset -=\n (hyperplaneVector * (data[left] + data[right])) / 2.0;\n // For each point compute the margin (project into normal vector)\n // If we are on lower side of the hyperplane put in one pile, otherwise\n // put it in the other pile (if we hit hyperplane on the nose, flip a coin)\n let nLeft = 0;\n let nRight = 0;\n const side = utils.zeros(indices.length);\n for (let i = 0; i < indices.length; i++) {\n let margin = hyperplaneOffset;\n margin += hyperplaneVector * data[indices[i]];\n if (margin === 0) {\n side[i] = utils.tauRandInt(2, random);\n if (side[i] === 0) {\n nLeft += 1;\n }\n else {\n nRight += 1;\n }\n }\n else if (margin > 0) {\n side[i] = 0;\n nLeft += 1;\n }\n else {\n side[i] = 1;\n nRight += 1;\n }\n }\n // Now that we have the counts, allocate arrays\n const indicesLeft = utils.zeros(nLeft);\n const indicesRight = utils.zeros(nRight);\n // Populate the arrays with indices according to which side they fell on\n nLeft = 0;\n nRight = 0;\n for (let i = 0; i < side.length; i++) {\n if (side[i] === 0) {\n indicesLeft[nLeft] = indices[i];\n nLeft += 1;\n }\n else {\n indicesRight[nRight] = indices[i];\n nRight += 1;\n }\n }\n return {\n indicesLeft,\n indicesRight,\n hyperplane: hyperplaneVector,\n offset: hyperplaneOffset,\n };\n}\nfunction flattenTree(tree, leafSize) {\n const nNodes = numNodes(tree);\n const nLeaves = numLeaves(tree);\n // TODO: Verify that sparse code is not relevant...\n const hyperplanes = utils\n .range(nNodes)\n .map(() => tree.hyperplane ? 1 : 0);\n const offsets = utils.zeros(nNodes);\n const children = utils.range(nNodes).map(() => [-1, -1]);\n const indices = utils\n .range(nLeaves)\n .map(() => utils.range(leafSize).map(() => -1));\n recursiveFlatten(tree, hyperplanes, offsets, children, indices, 0, 0);\n return new FlatTree(hyperplanes, offsets, children, indices);\n}\nfunction recursiveFlatten(tree, hyperplanes, offsets, children, indices, nodeNum, leafNum) {\n if (tree.isLeaf) {\n children[nodeNum][0] = -leafNum;\n // TODO: Triple check this operation corresponds to\n // indices[leafNum : tree.indices.shape[0]] = tree.indices\n indices[leafNum].splice(0, tree.indices.length, ...tree.indices);\n leafNum += 1;\n return { nodeNum, leafNum };\n }\n else {\n hyperplanes[nodeNum] = tree.hyperplane;\n offsets[nodeNum] = tree.offset;\n children[nodeNum][0] = nodeNum + 1;\n const oldNodeNum = nodeNum;\n let res = recursiveFlatten(tree.leftChild, hyperplanes, offsets, children, indices, nodeNum + 1, leafNum);\n nodeNum = res.nodeNum;\n leafNum = res.leafNum;\n children[oldNodeNum][1] = nodeNum + 1;\n res = recursiveFlatten(tree.rightChild, hyperplanes, offsets, children, indices, nodeNum + 1, leafNum);\n return { nodeNum: res.nodeNum, leafNum: res.leafNum };\n }\n}\nfunction numNodes(tree) {\n if (tree.isLeaf) {\n return 1;\n }\n else {\n return 1 + numNodes(tree.leftChild) + numNodes(tree.rightChild);\n }\n}\nfunction numLeaves(tree) {\n if (tree.isLeaf) {\n return 1;\n }\n else {\n return numLeaves(tree.leftChild) + numLeaves(tree.rightChild);\n }\n}\n/**\n * Generate an array of sets of candidate nearest neighbors by\n * constructing a random projection forest and taking the leaves of all the\n * trees. Any given tree has leaves that are a set of potential nearest\n * neighbors. Given enough trees the set of all such leaves gives a good\n * likelihood of getting a good set of nearest neighbors in composite. Since\n * such a random projection forest is inexpensive to compute, this can be a\n * useful means of seeding other nearest neighbor algorithms.\n */\nexport function makeLeafArray(rpForest) {\n if (rpForest.length > 0) {\n const output = [];\n for (let tree of rpForest) {\n output.push(...tree.indices);\n }\n return output;\n }\n else {\n return [[-1]];\n }\n}\n/**\n * Selects the side of the tree to search during flat tree search.\n */\nfunction selectSide(hyperplane, offset, point, random) {\n let margin = offset;\n margin += hyperplane * point;\n if (margin === 0) {\n const side = utils.tauRandInt(2, random);\n return side;\n }\n else if (margin > 0) {\n return 0;\n }\n else {\n return 1;\n }\n}\n/**\n * Searches a flattened rp-tree for a point.\n */\nexport function searchFlatTree(point, tree, random) {\n let node = 0;\n while (tree.children[node][0] > 0) {\n const side = selectSide(tree.hyperplanes[node], tree.offsets[node], point, random);\n if (side === 0) {\n node = tree.children[node][0];\n }\n else {\n node = tree.children[node][1];\n }\n }\n const index = -1 * tree.children[node][0];\n return tree.indices[index];\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRyZWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBRUg7Ozs7O0dBS0c7QUFFSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCRztBQUVILE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBZWpDLE1BQU0sT0FBTyxRQUFRO0lBQ25CLFlBQ1MsV0FBcUIsRUFDckIsT0FBaUIsRUFDakIsUUFBb0IsRUFDcEIsT0FBbUI7UUFIbkIsZ0JBQVcsR0FBWCxXQUFXLENBQVU7UUFDckIsWUFBTyxHQUFQLE9BQU8sQ0FBVTtRQUNqQixhQUFRLEdBQVIsUUFBUSxDQUFZO1FBQ3BCLFlBQU8sR0FBUCxPQUFPLENBQVk7SUFDekIsQ0FBQztDQUNMO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsVUFBVSxDQUN4QixJQUFZLEVBQ1osVUFBa0IsRUFDbEIsTUFBYyxFQUNkLE1BQWdCO0lBRWhCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBRTFDLE1BQU0sS0FBSyxHQUFHLEtBQUs7U0FDaEIsS0FBSyxDQUFDLE1BQU0sQ0FBQztTQUNiLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3RELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFFOUQsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQVMsUUFBUSxDQUNmLElBQVksRUFDWixRQUFRLEdBQUcsRUFBRSxFQUNi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QUMvQjthQUFNO1lBQ0wsSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDL0I7S0FDRjtJQUVELE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzdCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG4vKipcbiAqIFRoaXMgaXMgYSBKYXZhU2NyaXB0IHJlaW1wbGVtZW50YXRpb24gb2YgVU1BUCAob3JpZ2luYWwgbGljZW5zZSBiZWxvdyksIGZyb21cbiAqIHRoZSBweXRob24gaW1wbGVtZW50YXRpb24gZm91bmQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2xtY2lubmVzL3VtYXAuXG4gKlxuICogQGF1dGhvciBhbmR5Y29lbmVuQGdvb2dsZS5jb20gKEFuZHkgQ29lbmVuKVxuICovXG5cbi8qKlxuICogQGxpY2Vuc2VcbiAqIEJTRCAzLUNsYXVzZSBMaWNlbnNlXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDE3LCBMZWxhbmQgTWNJbm5lc1xuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzXG4gKiAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICpcbiAqICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gKiAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqICogTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0c1xuICogICBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbVxuICogICB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuICpcbiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEVcbiAqIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMXG4gKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUlxuICogU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVJcbiAqIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksXG4gKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRVxuICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiAqL1xuXG5pbXBvcnQgKiBhcyB1dGlscyBmcm9tICcuL3V0aWxzJztcbmltcG9ydCB7IFJhbmRvbUZuLCBWZWN0b3IsIFZlY3RvcnMgfSBmcm9tICcuL3VtYXAnO1xuXG4vKipcbiAqIFRyZWUgZnVuY3Rpb25hbGl0eSBmb3IgYXBwcm94aW1hdGluZyBuZWFyZXN0IG5laWdoYm9yc1xuICovXG5pbnRlcmZhY2UgUmFuZG9tUHJvamVjdGlvblRyZWVOb2RlIHtcbiAgaXNMZWFmOiBib29sZWFuO1xuICBpbmRpY2VzPzogbnVtYmVyW107XG4gIGxlZnRDaGlsZD86IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZTtcbiAgcmlnaHRDaGlsZD86IFJhbmRvbVByb2plY3Rpb25UcmVlTm9kZTtcbiAgaHlwZXJwbGFuZT86IG51bWJlcjtcbiAgb2Zmc2V0PzogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgRmxhdFRyZWUge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgaHlwZXJwbGFuZXM6IG51bWJlcltdLFxuICAgIHB1YmxpYyBvZmZzZXRzOiBudW1iZXJbXSxcbiAgICBwdWJsaWMgY2hpbGRyZW46IG51bWJlcltdW10sXG4gICAgcHVibGljIGluZGljZXM6IG51bWJlcltdW11cbiAgKSB7fVxufVxuXG4vKipcbiAqIEJ1aWxkIGEgcmFuZG9tIHByb2plY3Rpb24gZm9yZXN0IHdpdGggYGBuVHJlZXNgYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VGb3Jlc3QoXG4gIGRhdGE6IFZlY3RvcixcbiAgbk5laWdoYm9yczogbnVtYmVyLFxuICBuVHJlZXM6IG51bWJlcixcbiAgcmFuZG9tOiBSYW5kb21GblxuKSB7XG4gIGNvbnN0IGxlYWZTaXplID0gTWF0aC5tYXgoMTAsIG5OZWlnaGJvcnMpO1xuXG4gIGNvbnN0IHRyZWVzID0gdXRpbHNcbiAgICAucmFuZ2UoblRyZWVzKVxuICAgIC5tYXAoKF8sIGkpID0+IG1ha2VUcmVlKGRhdGEsIGxlYWZTaXplLCBpLCByYW5kb20pKTtcbiAgY29uc3QgZm9yZXN0ID0gdHJlZXMubWFwKHRyZWUgPT4gZmxhdHRlblRyZWUodHJlZSwgbGVhZlNpemUpKTtcblxuICByZXR1cm4gZm9yZXN0O1xufVxuXG4vKipcbiAqIENvbnN0cnVjdCBhIHJhbmRvbSBwcm9qZWN0aW9uIHRyZWUgYmFzZWQgb24gYGBkYXRhYGAgd2l0aCBsZWF2ZXNcbiAqIG9mIHNpemUgYXQgbW9zdCBgYGxlYWZTaXplYGBcbiAqL1xuZnVuY3Rpb24gbWFrZVRyZWUoXG4gIGRhdGE6IFZlY3RvcixcbiAgbGVhZlNpemUgPSAzMCxcbiAgbjogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pOiBSYW5kb21Qcm9qZWN0aW9uVHJlZU5vZGUge1xuICBjb25zdCBpbmRpY2VzID0gdXRpbHMucmFuZ2UoZGF0YS5sZW5ndGgpO1xuICBjb25zdCB0cmVlID0gbWFrZUV1Y2xpZGVhblRyZWUoZGF0YSwgaW5kaWNlcywgbGVhZlNpemUsIG4sIHJhbmRvbSk7XG4gIHJldHVybiB0cmVlO1xufVxuXG5mdW5jdGlvbiBtYWtlRXVjbGlkZWFuVHJlZShcbiAgZGF0YTogVmVjdG9yLFxuICBpbmRpY2VzOiBudW1iZXJbXSxcbiAgbGVhZlNpemUgPSAzMCxcbiAgcTogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pOiBSYW5kb21Qcm9qZWN0aW9uVHJlZU5vZGUge1xuICBpZiAoaW5kaWNlcy5sZW5ndGggPiBsZWFmU2l6ZSkge1xuICAgIGNvbnN0IHNwbGl0UmVzdWx0cyA9IGV1Y2xpZGVhblJhbmRvbVByb2plY3Rpb25TcGxpdChkYXRhLCBpbmRpY2VzLCByYW5kb20pO1xuICAgIGNvbnN0IHsgaW5kaWNlc0xlZnQsIGluZGljZXNSaWdodCwgaHlwZXJwbGFuZSwgb2Zmc2V0IH0gPSBzcGxpdFJlc3VsdHM7XG5cbiAgICBjb25zdCBsZWZ0Q2hpbGQgPSBtYWtlRXVjbGlkZWFuVHJlZShcbiAgICAgIGRhdGEsXG4gICAgICBpbmRpY2VzTGVmdCxcbiAgICAgIGxlYWZTaXplLFxuICAgICAgcSArIDEsXG4gICAgICByYW5kb21cbiAgICApO1xuICAgIGNvbnN0IHJpZ2h0Q2hpbGQgPSBtYWtlRXVjbGlkZWFuVHJlZShcbiAgICAgIGRhdGEsXG4gICAgICBpbmRpY2VzUmlnaHQsXG4gICAgICBsZWFmU2l6ZSxcbiAgICAgIHEgKyAxLFxuICAgICAgcmFuZG9tXG4gICAgKTtcblxuICAgIGNvbnN0IG5vZGUgPSB7IGxlZnRDaGlsZCwgcmlnaHRDaGlsZCwgaXNMZWFmOiBmYWxzZSwgaHlwZXJwbGFuZSwgb2Zmc2V0IH07XG4gICAgcmV0dXJuIG5vZGU7XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qgbm9kZSA9IHsgaW5kaWNlcywgaXNMZWFmOiB0cnVlIH07XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cbn1cblxuLyoqXG4gKiBHaXZlbiBhIHNldCBvZiBgYGluZGljZXNgYCBmb3IgZGF0YSBwb2ludHMgZnJvbSBgYGRhdGFgYCwgY3JlYXRlXG4gKiBhIHJhbmRvbSBoeXBlcnBsYW5lIHRvIHNwbGl0IHRoZSBkYXRhLCByZXR1cm5pbmcgdHdvIGFycmF5cyBpbmRpY2VzXG4gKiB0aGF0IGZhbGwgb24gZWl0aGVyIHNpZGUgb2YgdGhlIGh5cGVycGxhbmUuIFRoaXMgaXMgdGhlIGJhc2lzIGZvciBhXG4gKiByYW5kb20gcHJvamVjdGlvbiB0cmVlLCB3aGljaCBzaW1wbHkgdXNlcyB0aGlzIHNwbGl0dGluZyByZWN1cnNpdmVseS5cbiAqIFRoaXMgcGFydGljdWxhciBzcGxpdCB1c2VzIGV1Y2xpZGVhbiBkaXN0YW5jZSB0byBkZXRlcm1pbmUgdGhlIGh5cGVycGxhbmVcbiAqIGFuZCB3aGljaCBzaWRlIGVhY2ggZGF0YSBzYW1wbGUgZmFsbHMgb24uXG4gKi9cbmZ1bmN0aW9uIGV1Y2xpZGVhblJhbmRvbVByb2plY3Rpb25TcGxpdChcbiAgZGF0YTogVmVjdG9yLFxuICBpbmRpY2VzOiBudW1iZXJbXSxcbiAgcmFuZG9tOiBSYW5kb21GblxuKSB7XG4gIGNvbnN0IGRpbSA9IDE7XG5cbiAgLy8gU2VsZWN0IHR3byByYW5kb20gcG9pbnRzLCBzZXQgdGhlIGh5cGVycGxhbmUgYmV0d2VlbiB0aGVtXG4gIGxldCBsZWZ0SW5kZXggPSB1dGlscy50YXVSYW5kSW50KGluZGljZXMubGVuZ3RoLCByYW5kb20pO1xuICBsZXQgcmlnaHRJbmRleCA9IHV0aWxzLnRhdVJhbmRJbnQoaW5kaWNlcy5sZW5ndGgsIHJhbmRvbSk7XG4gIHJpZ2h0SW5kZXggKz0gbGVmdEluZGV4ID09PSByaWdodEluZGV4ID8gMSA6IDA7XG4gIHJpZ2h0SW5kZXggPSByaWdodEluZGV4ICUgaW5kaWNlcy5sZW5ndGg7XG4gIGNvbnN0IGxlZnQgPSBpbmRpY2VzW2xlZnRJbmRleF07XG4gIGNvbnN0IHJpZ2h0ID0gaW5kaWNlc1tyaWdodEluZGV4XTtcblxuICAvLyBDb21wdXRlIHRoZSBub3JtYWwgdmVjdG9yIHRvIHRoZSBoeXBlcnBsYW5lICh0aGUgdmVjdG9yIGJldHdlZW4gdGhlIHR3b1xuICAvLyBwb2ludHMpIGFuZCB0aGUgb2Zmc2V0IGZyb20gdGhlIG9yaWdpblxuICBsZXQgaHlwZXJwbGFuZU9mZnNldCA9IDA7XG4gIGxldCBoeXBlcnBsYW5lVmVjdG9yID0gMDtcblxuICBcbiAgaHlwZXJwbGFuZVZlY3RvciA9IGRhdGFbbGVmdF0gLSBkYXRhW3JpZ2h0XTtcbiAgaHlwZXJwbGFuZU9mZnNldCAtPVxuICAgIChoeXBlcnBsYW5lVmVjdG9yICogKGRhdGFbbGVmdF0gKyBkYXRhW3JpZ2h0XSkpIC8gMi4wO1xuICBcblxuICAvLyBGb3IgZWFjaCBwb2ludCBjb21wdXRlIHRoZSBtYXJnaW4gKHByb2plY3QgaW50byBub3JtYWwgdmVjdG9yKVxuICAvLyBJZiB3ZSBhcmUgb24gbG93ZXIgc2lkZSBvZiB0aGUgaHlwZXJwbGFuZSBwdXQgaW4gb25lIHBpbGUsIG90aGVyd2lzZVxuICAvLyBwdXQgaXQgaW4gdGhlIG90aGVyIHBpbGUgKGlmIHdlIGhpdCBoeXBlcnBsYW5lIG9uIHRoZSBub3NlLCBmbGlwIGEgY29pbilcbiAgbGV0IG5MZWZ0ID0gMDtcbiAgbGV0IG5SaWdodCA9IDA7XG4gIGNvbnN0IHNpZGUgPSB1dGlscy56ZXJvcyhpbmRpY2VzLmxlbmd0aCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkrKykge1xuICAgIGxldCBtYXJnaW4gPSBoeXBlcnBsYW5lT2Zmc2V0O1xuICAgIFxuICAgICAgbWFyZ2luICs9IGh5cGVycGxhbmVWZWN0b3IgKiBkYXRhW2luZGljZXNbaV1dO1xuICAgIFxuICAgIGlmIChtYXJnaW4gPT09IDApIHtcbiAgICAgIHNpZGVbaV0gPSB1dGlscy50YXVSYW5kSW50KDIsIHJhbmRvbSk7XG4gICAgICBpZiAoc2lkZVtpXSA9PT0gMCkge1xuICAgICAgICBuTGVmdCArPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgblJpZ2h0ICs9IDE7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChtYXJnaW4gPiAwKSB7XG4gICAgICBzaWRlW2ldID0gMDtcbiAgICAgIG5MZWZ0ICs9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNpZGVbaV0gPSAxO1xuICAgICAgblJpZ2h0ICs9IDE7XG4gICAgfVxuICB9XG5cbiAgLy8gTm93IHRoYXQgd2UgaGF2ZSB0aGUgY291bnRzLCBhbGxvY2F0ZSBhcnJheXNcbiAgY29uc3QgaW5kaWNlc0xlZnQgPSB1dGlscy56ZXJvcyhuTGVmdCk7XG4gIGNvbnN0IGluZGljZXNSaWdodCA9IHV0aWxzLnplcm9zKG5SaWdodCk7XG5cbiAgLy8gUG9wdWxhdGUgdGhlIGFycmF5cyB3aXRoIGluZGljZXMgYWNjb3JkaW5nIHRvIHdoaWNoIHNpZGUgdGhleSBmZWxsIG9uXG4gIG5MZWZ0ID0gMDtcbiAgblJpZ2h0ID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaWRlLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHNpZGVbaV0gPT09IDApIHtcbiAgICAgIGluZGljZXNMZWZ0W25MZWZ0XSA9IGluZGljZXNbaV07XG4gICAgICBuTGVmdCArPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBpbmRpY2VzUmlnaHRbblJpZ2h0XSA9IGluZGljZXNbaV07XG4gICAgICBuUmlnaHQgKz0gMTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGluZGljZXNMZWZ0LFxuICAgIGluZGljZXNSaWdodCxcbiAgICBoeXBlcnBsYW5lOiBoeXBlcnBsYW5lVmVjdG9yLFxuICAgIG9mZnNldDogaHlwZXJwbGFuZU9mZnNldCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZmxhdHRlblRyZWUodHJlZTogUmFuZG9tUHJvamVjdGlvblRyZWVOb2RlLCBsZWFmU2l6ZTogbnVtYmVyKSB7XG4gIGNvbnN0IG5Ob2RlcyA9IG51bU5vZGVzKHRyZWUpO1xuICBjb25zdCBuTGVhdmVzID0gbnVtTGVhdmVzKHRyZWUpO1xuXG4gIC8vIFRPRE86IFZlcmlmeSB0aGF0IHNwYXJzZSBjb2RlIGlzIG5vdCByZWxldmFudC4uLlxuICBjb25zdCBoeXBlcnBsYW5lcyA9IHV0aWxzXG4gICAgLnJhbmdlKG5Ob2RlcylcbiAgICAubWFwKCgpID0+IHRyZWUuaHlwZXJwbGFuZSA/IDEgOiAwKTtcblxuICBjb25zdCBvZmZzZXRzID0gdXRpbHMuemVyb3Mobk5vZGVzKTtcbiAgY29uc3QgY2hpbGRyZW4gPSB1dGlscy5yYW5nZShuTm9kZXMpLm1hcCgoKSA9PiBbLTEsIC0xXSk7XG4gIGNvbnN0IGluZGljZXMgPSB1dGlsc1xuICAgIC5yYW5nZShuTGVhdmVzKVxuICAgIC5tYXAoKCkgPT4gdXRpbHMucmFuZ2UobGVhZlNpemUpLm1hcCgoKSA9PiAtMSkpO1xuICByZWN1cnNpdmVGbGF0dGVuKHRyZWUsIGh5cGVycGxhbmVzLCBvZmZzZXRzLCBjaGlsZHJlbiwgaW5kaWNlcywgMCwgMCk7XG4gIHJldHVybiBuZXcgRmxhdFRyZWUoaHlwZXJwbGFuZXMsIG9mZnNldHMsIGNoaWxkcmVuLCBpbmRpY2VzKTtcbn1cblxuZnVuY3Rpb24gcmVjdXJzaXZlRmxhdHRlbihcbiAgdHJlZTogUmFuZG9tUHJvamVjdGlvblRyZWVOb2RlLFxuICBoeXBlcnBsYW5lczogbnVtYmVyW10sXG4gIG9mZnNldHM6IG51bWJlcltdLFxuICBjaGlsZHJlbjogbnVtYmVyW11bXSxcbiAgaW5kaWNlczogbnVtYmVyW11bXSxcbiAgbm9kZU51bTogbnVtYmVyLFxuICBsZWFmTnVtOiBudW1iZXJcbik6IHsgbm9kZU51bTogbnVtYmVyOyBsZWFmTnVtOiBudW1iZXIgfSB7XG4gIGlmICh0cmVlLmlzTGVhZikge1xuICAgIGNoaWxkcmVuW25vZGVOdW1dWzBdID0gLWxlYWZOdW07XG5cbiAgICAvLyBUT0RPOiBUcmlwbGUgY2hlY2sgdGhpcyBvcGVyYXRpb24gY29ycmVzcG9uZHMgdG9cbiAgICAvLyBpbmRpY2VzW2xlYWZOdW0gOiB0cmVlLmluZGljZXMuc2hhcGVbMF1dID0gdHJlZS5pbmRpY2VzXG4gICAgaW5kaWNlc1tsZWFmTnVtXS5zcGxpY2UoMCwgdHJlZS5pbmRpY2VzIS5sZW5ndGgsIC4uLnRyZWUuaW5kaWNlcyEpO1xuICAgIGxlYWZOdW0gKz0gMTtcbiAgICByZXR1cm4geyBub2RlTnVtLCBsZWFmTnVtIH07XG4gIH0gZWxzZSB7XG4gICAgaHlwZXJwbGFuZXNbbm9kZU51bV0gPSB0cmVlLmh5cGVycGxhbmUhO1xuICAgIG9mZnNldHNbbm9kZU51bV0gPSB0cmVlLm9mZnNldCE7XG4gICAgY2hpbGRyZW5bbm9kZU51bV1bMF0gPSBub2RlTnVtICsgMTtcbiAgICBjb25zdCBvbGROb2RlTnVtID0gbm9kZU51bTtcblxuICAgIGxldCByZXMgPSByZWN1cnNpdmVGbGF0dGVuKFxuICAgICAgdHJlZS5sZWZ0Q2hpbGQhLFxuICAgICAgaHlwZXJwbGFuZXMsXG4gICAgICBvZmZzZXRzLFxuICAgICAgY2hpbGRyZW4sXG4gICAgICBpbmRpY2VzLFxuICAgICAgbm9kZU51bSArIDEsXG4gICAgICBsZWFmTnVtXG4gICAgKTtcbiAgICBub2RlTnVtID0gcmVzLm5vZGVOdW07XG4gICAgbGVhZk51bSA9IHJlcy5sZWFmTnVtO1xuXG4gICAgY2hpbGRyZW5bb2xkTm9kZU51bV1bMV0gPSBub2RlTnVtICsgMTtcblxuICAgIHJlcyA9IHJlY3Vyc2l2ZUZsYXR0ZW4oXG4gICAgICB0cmVlLnJpZ2h0Q2hpbGQhLFxuICAgICAgaHlwZXJwbGFuZXMsXG4gICAgICBvZmZzZXRzLFxuICAgICAgY2hpbGRyZW4sXG4gICAgICBpbmRpY2VzLFxuICAgICAgbm9kZU51bSArIDEsXG4gICAgICBsZWFmTnVtXG4gICAgKTtcbiAgICByZXR1cm4geyBub2RlTnVtOiByZXMubm9kZU51bSwgbGVhZk51bTogcmVzLmxlYWZOdW0gfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBudW1Ob2Rlcyh0cmVlOiBSYW5kb21Qcm9qZWN0aW9uVHJlZU5vZGUpOiBudW1iZXIge1xuICBpZiAodHJlZS5pc0xlYWYpIHtcbiAgICByZXR1cm4gMTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gMSArIG51bU5vZGVzKHRyZWUubGVmdENoaWxkISkgKyBudW1Ob2Rlcyh0cmVlLnJpZ2h0Q2hpbGQhKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBudW1MZWF2ZXModHJlZTogUmFuZG9tUHJvamVjdGlvblRyZWVOb2RlKTogbnVtYmVyIHtcbiAgaWYgKHRyZWUuaXNMZWFmKSB7XG4gICAgcmV0dXJuIDE7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG51bUxlYXZlcyh0cmVlLmxlZnRDaGlsZCEpICsgbnVtTGVhdmVzKHRyZWUucmlnaHRDaGlsZCEpO1xuICB9XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYW4gYXJyYXkgb2Ygc2V0cyBvZiBjYW5kaWRhdGUgbmVhcmVzdCBuZWlnaGJvcnMgYnlcbiAqIGNvbnN0cnVjdGluZyBhIHJhbmRvbSBwcm9qZWN0aW9uIGZvcmVzdCBhbmQgdGFraW5nIHRoZSBsZWF2ZXMgb2YgYWxsIHRoZVxuICogdHJlZXMuIEFueSBnaXZlbiB0cmVlIGhhcyBsZWF2ZXMgdGhhdCBhcmUgYSBzZXQgb2YgcG90ZW50aWFsIG5lYXJlc3RcbiAqIG5laWdoYm9ycy4gR2l2ZW4gZW5vdWdoIHRyZWVzIHRoZSBzZXQgb2YgYWxsIHN1Y2ggbGVhdmVzIGdpdmVzIGEgZ29vZFxuICogbGlrZWxpaG9vZCBvZiBnZXR0aW5nIGEgZ29vZCBzZXQgb2YgbmVhcmVzdCBuZWlnaGJvcnMgaW4gY29tcG9zaXRlLiBTaW5jZVxuICogc3VjaCBhIHJhbmRvbSBwcm9qZWN0aW9uIGZvcmVzdCBpcyBpbmV4cGVuc2l2ZSB0byBjb21wdXRlLCB0aGlzIGNhbiBiZSBhXG4gKiB1c2VmdWwgbWVhbnMgb2Ygc2VlZGluZyBvdGhlciBuZWFyZXN0IG5laWdoYm9yIGFsZ29yaXRobXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYWtlTGVhZkFycmF5KHJwRm9yZXN0OiBGbGF0VHJlZVtdKTogbnVtYmVyW11bXSB7XG4gIGlmIChycEZvcmVzdC5sZW5ndGggPiAwKSB7XG4gICAgY29uc3Qgb3V0cHV0OiBudW1iZXJbXVtdID0gW107XG4gICAgZm9yIChsZXQgdHJlZSBvZiBycEZvcmVzdCkge1xuICAgICAgb3V0cHV0LnB1c2goLi4udHJlZS5pbmRpY2VzISk7XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFtbLTFdXTtcbiAgfVxufVxuXG4vKipcbiAqIFNlbGVjdHMgdGhlIHNpZGUgb2YgdGhlIHRyZWUgdG8gc2VhcmNoIGR1cmluZyBmbGF0IHRyZWUgc2VhcmNoLlxuICovXG5mdW5jdGlvbiBzZWxlY3RTaWRlKFxuICBoeXBlcnBsYW5lOiBudW1iZXIsXG4gIG9mZnNldDogbnVtYmVyLFxuICBwb2ludDogbnVtYmVyLFxuICByYW5kb206IFJhbmRvbUZuXG4pIHtcbiAgbGV0IG1hcmdpbiA9IG9mZnNldDtcblxuICAgIG1hcmdpbiArPSBoeXBlcnBsYW5lICogcG9pbnQ7XG4gIFxuXG4gIGlmIChtYXJnaW4gPT09IDApIHtcbiAgICBjb25zdCBzaWRlID0gdXRpbHMudGF1UmFuZEludCgyLCByYW5kb20pO1xuICAgIHJldHVybiBzaWRlO1xuICB9IGVsc2UgaWYgKG1hcmdpbiA+IDApIHtcbiAgICByZXR1cm4gMDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gMTtcbiAgfVxufVxuXG4vKipcbiAqIFNlYXJjaGVzIGEgZmxhdHRlbmVkIHJwLXRyZWUgZm9yIGEgcG9pbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZWFyY2hGbGF0VHJlZShcbiAgcG9pbnQ6IG51bWJlcixcbiAgdHJlZTogRmxhdFRyZWUsXG4gIHJhbmRvbTogUmFuZG9tRm5cbikge1xuICBsZXQgbm9kZSA9IDA7XG4gIHdoaWxlICh0cmVlLmNoaWxkcmVuW25vZGVdWzBdID4gMCkge1xuICAgIGNvbnN0IHNpZGUgPSBzZWxlY3RTaWRlKFxuICAgICAgdHJlZS5oeXBlcnBsYW5lc1tub2RlXSxcbiAgICAgIHRyZWUub2Zmc2V0c1tub2RlXSxcbiAgICAgIHBvaW50LFxuICAgICAgcmFuZG9tXG4gICAgKTtcbiAgICBpZiAoc2lkZSA9PT0gMCkge1xuICAgICAgbm9kZSA9IHRyZWUuY2hpbGRyZW5bbm9kZV1bMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIG5vZGUgPSB0cmVlLmNoaWxkcmVuW25vZGVdWzFdO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGluZGV4ID0gLTEgKiB0cmVlLmNoaWxkcmVuW25vZGVdWzBdO1xuICByZXR1cm4gdHJlZS5pbmRpY2VzW2luZGV4XTtcbn1cbiJdfQ==","const toString = Object.prototype.toString;\n\nexport default function isAnyArray(object) {\n return toString.call(object).endsWith('Array]');\n}\n","/**\n * Calculate current error\n * @ignore\n * @param {{x:Array<number>, y:Array<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {Array<number>} parameters - Array of current parameter values\n * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter\n * @return {number}\n */\nexport default function errorCalculation(\n data,\n parameters,\n parameterizedFunction,\n) {\n let error = 0;\n const func = parameterizedFunction(parameters);\n\n for (let i = 0; i < data.x.length; i++) {\n error += Math.abs(data.y[i] - func(data.x[i]));\n }\n\n return error;\n}\n","const toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array).\n *\n * @param {any} value - Object to check.\n * @returns {boolean} True if the object is an array.\n */\nexport function isAnyArray(value) {\n return toString.call(value).endsWith('Array]');\n}\n//# sourceMappingURL=index.js.map","const toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array).\n *\n * @param {any} value - Object to check.\n * @returns {boolean} True if the object is an array.\n */\nexport function isAnyArray(value) {\n return toString.call(value).endsWith('Array]');\n}\n//# sourceMappingURL=index.js.map","const toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array).\n *\n * @param {any} value - Object to check.\n * @returns {boolean} True if the object is an array.\n */\nexport function isAnyArray(value) {\n return toString.call(value).endsWith('Array]');\n}\n//# sourceMappingURL=index.js.map","const toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array).\n *\n * @param {any} value - Object to check.\n * @returns {boolean} True if the object is an array.\n */\nexport function isAnyArray(value) {\n return toString.call(value).endsWith('Array]');\n}\n//# sourceMappingURL=index.js.map","import { isAnyArray } from 'is-any-array';\nimport max from 'ml-array-max';\nimport min from 'ml-array-min';\n\nfunction rescale(input) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n if (!isAnyArray(input)) {\n throw new TypeError('input must be an array');\n } else if (input.length === 0) {\n throw new TypeError('input must not be empty');\n }\n\n var output;\n\n if (options.output !== undefined) {\n if (!isAnyArray(options.output)) {\n throw new TypeError('output option must be an array if specified');\n }\n\n output = options.output;\n } else {\n output = new Array(input.length);\n }\n\n var currentMin = min(input);\n var currentMax = max(input);\n\n if (currentMin === currentMax) {\n throw new RangeError('minimum and maximum input values are equal. Cannot rescale a constant array');\n }\n\n var _options$min = options.min,\n minValue = _options$min === void 0 ? options.autoMinMax ? currentMin : 0 : _options$min,\n _options$max = options.max,\n maxValue = _options$max === void 0 ? options.autoMinMax ? currentMax : 1 : _options$max;\n\n if (minValue >= maxValue) {\n throw new RangeError('min option must be smaller than max option');\n }\n\n var factor = (maxValue - minValue) / (currentMax - currentMin);\n\n for (var i = 0; i < input.length; i++) {\n output[i] = (input[i] - currentMin) * factor + minValue;\n }\n\n return output;\n}\n\nexport { rescale as default };\n","import { isAnyArray } from 'is-any-array';\n\nfunction min(input) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n if (!isAnyArray(input)) {\n throw new TypeError('input must be an array');\n }\n\n if (input.length === 0) {\n throw new TypeError('input must not be empty');\n }\n\n var _options$fromIndex = options.fromIndex,\n fromIndex = _options$fromIndex === void 0 ? 0 : _options$fromIndex,\n _options$toIndex = options.toIndex,\n toIndex = _options$toIndex === void 0 ? input.length : _options$toIndex;\n\n if (fromIndex < 0 || fromIndex >= input.length || !Number.isInteger(fromIndex)) {\n throw new Error('fromIndex must be a positive integer smaller than length');\n }\n\n if (toIndex <= fromIndex || toIndex > input.length || !Number.isInteger(toIndex)) {\n throw new Error('toIndex must be an integer greater than fromIndex and at most equal to length');\n }\n\n var minValue = input[fromIndex];\n\n for (var i = fromIndex + 1; i < toIndex; i++) {\n if (input[i] < minValue) minValue = input[i];\n }\n\n return minValue;\n}\n\nexport { min as default };\n","import { isAnyArray } from 'is-any-array';\n\nfunction max(input) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n if (!isAnyArray(input)) {\n throw new TypeError('input must be an array');\n }\n\n if (input.length === 0) {\n throw new TypeError('input must not be empty');\n }\n\n var _options$fromIndex = options.fromIndex,\n fromIndex = _options$fromIndex === void 0 ? 0 : _options$fromIndex,\n _options$toIndex = options.toIndex,\n toIndex = _options$toIndex === void 0 ? input.length : _options$toIndex;\n\n if (fromIndex < 0 || fromIndex >= input.length || !Number.isInteger(fromIndex)) {\n throw new Error('fromIndex must be a positive integer smaller than length');\n }\n\n if (toIndex <= fromIndex || toIndex > input.length || !Number.isInteger(toIndex)) {\n throw new Error('toIndex must be an integer greater than fromIndex and at most equal to length');\n }\n\n var maxValue = input[fromIndex];\n\n for (var i = fromIndex + 1; i < toIndex; i++) {\n if (input[i] > maxValue) maxValue = input[i];\n }\n\n return maxValue;\n}\n\nexport { max as default };\n","const indent = ' '.repeat(2);\nconst indentData = ' '.repeat(4);\n\nexport function inspectMatrix() {\n return inspectMatrixWithOptions(this);\n}\n\nexport function inspectMatrixWithOptions(matrix, options = {}) {\n const {\n maxRows = 15,\n maxColumns = 10,\n maxNumSize = 8,\n padMinus = 'auto',\n } = options;\n return `${matrix.constructor.name} {\n${indent}[\n${indentData}${inspectData(matrix, maxRows, maxColumns, maxNumSize, padMinus)}\n${indent}]\n${indent}rows: ${matrix.rows}\n${indent}columns: ${matrix.columns}\n}`;\n}\n\nfunction inspectData(matrix, maxRows, maxColumns, maxNumSize, padMinus) {\n const { rows, columns } = matrix;\n const maxI = Math.min(rows, maxRows);\n const maxJ = Math.min(columns, maxColumns);\n const result = [];\n\n if (padMinus === 'auto') {\n padMinus = false;\n loop: for (let i = 0; i < maxI; i++) {\n for (let j = 0; j < maxJ; j++) {\n if (matrix.get(i, j) < 0) {\n padMinus = true;\n break loop;\n }\n }\n }\n }\n\n for (let i = 0; i < maxI; i++) {\n let line = [];\n for (let j = 0; j < maxJ; j++) {\n line.push(formatNumber(matrix.get(i, j), maxNumSize, padMinus));\n }\n result.push(`${line.join(' ')}`);\n }\n if (maxJ !== columns) {\n result[result.length - 1] += ` ... ${columns - maxColumns} more columns`;\n }\n if (maxI !== rows) {\n result.push(`... ${rows - maxRows} more rows`);\n }\n return result.join(`\\n${indentData}`);\n}\n\nfunction formatNumber(num, maxNumSize, padMinus) {\n return (\n num >= 0 && padMinus\n ? ` ${formatNumber2(num, maxNumSize - 1)}`\n : formatNumber2(num, maxNumSize)\n ).padEnd(maxNumSize);\n}\n\nfunction formatNumber2(num, len) {\n // small.length numbers should be as is\n let str = num.toString();\n if (str.length <= len) return str;\n\n // (7)'0.00123' is better then (7)'1.23e-2'\n // (8)'0.000123' is worse then (7)'1.23e-3',\n let fix = num.toFixed(len);\n if (fix.length > len) {\n fix = num.toFixed(Math.max(0, len - (fix.length - len)));\n }\n if (\n fix.length <= len &&\n !fix.startsWith('0.000') &&\n !fix.startsWith('-0.000')\n ) {\n return fix;\n }\n\n // well, if it's still too long the user should've used longer numbers\n let exp = num.toExponential(len);\n if (exp.length > len) {\n exp = num.toExponential(Math.max(0, len - (exp.length - len)));\n }\n return exp.slice(0);\n}\n","import { isAnyArray } from 'is-any-array';\n\n/**\n * @private\n * Check that a row index is not out of bounds\n * @param {Matrix} matrix\n * @param {number} index\n * @param {boolean} [outer]\n */\nexport function checkRowIndex(matrix, index, outer) {\n let max = outer ? matrix.rows : matrix.rows - 1;\n if (index < 0 || index > max) {\n throw new RangeError('Row index out of range');\n }\n}\n\n/**\n * @private\n * Check that a column index is not out of bounds\n * @param {Matrix} matrix\n * @param {number} index\n * @param {boolean} [outer]\n */\nexport function checkColumnIndex(matrix, index, outer) {\n let max = outer ? matrix.columns : matrix.columns - 1;\n if (index < 0 || index > max) {\n throw new RangeError('Column index out of range');\n }\n}\n\n/**\n * @private\n * Check that the provided vector is an array with the right length\n * @param {Matrix} matrix\n * @param {Array|Matrix} vector\n * @return {Array}\n * @throws {RangeError}\n */\nexport function checkRowVector(matrix, vector) {\n if (vector.to1DArray) {\n vector = vector.to1DArray();\n }\n if (vector.length !== matrix.columns) {\n throw new RangeError(\n 'vector size must be the same as the number of columns',\n );\n }\n return vector;\n}\n\n/**\n * @private\n * Check that the provided vector is an array with the right length\n * @param {Matrix} matrix\n * @param {Array|Matrix} vector\n * @return {Array}\n * @throws {RangeError}\n */\nexport function checkColumnVector(matrix, vector) {\n if (vector.to1DArray) {\n vector = vector.to1DArray();\n }\n if (vector.length !== matrix.rows) {\n throw new RangeError('vector size must be the same as the number of rows');\n }\n return vector;\n}\n\nexport function checkRowIndices(matrix, rowIndices) {\n if (!isAnyArray(rowIndices)) {\n throw new TypeError('row indices must be an array');\n }\n\n for (let i = 0; i < rowIndices.length; i++) {\n if (rowIndices[i] < 0 || rowIndices[i] >= matrix.rows) {\n throw new RangeError('row indices are out of range');\n }\n }\n}\n\nexport function checkColumnIndices(matrix, columnIndices) {\n if (!isAnyArray(columnIndices)) {\n throw new TypeError('column indices must be an array');\n }\n\n for (let i = 0; i < columnIndices.length; i++) {\n if (columnIndices[i] < 0 || columnIndices[i] >= matrix.columns) {\n throw new RangeError('column indices are out of range');\n }\n }\n}\n\nexport function checkRange(matrix, startRow, endRow, startColumn, endColumn) {\n if (arguments.length !== 5) {\n throw new RangeError('expected 4 arguments');\n }\n checkNumber('startRow', startRow);\n checkNumber('endRow', endRow);\n checkNumber('startColumn', startColumn);\n checkNumber('endColumn', endColumn);\n if (\n startRow > endRow ||\n startColumn > endColumn ||\n startRow < 0 ||\n startRow >= matrix.rows ||\n endRow < 0 ||\n endRow >= matrix.rows ||\n startColumn < 0 ||\n startColumn >= matrix.columns ||\n endColumn < 0 ||\n endColumn >= matrix.columns\n ) {\n throw new RangeError('Submatrix indices are out of range');\n }\n}\n\nexport function newArray(length, value = 0) {\n let array = [];\n for (let i = 0; i < length; i++) {\n array.push(value);\n }\n return array;\n}\n\nfunction checkNumber(name, value) {\n if (typeof value !== 'number') {\n throw new TypeError(`${name} must be a number`);\n }\n}\n\nexport function checkNonEmpty(matrix) {\n if (matrix.isEmpty()) {\n throw new Error('Empty matrix has no elements to index');\n }\n}\n","import { isAnyArray } from 'is-any-array';\nimport rescale from 'ml-array-rescale';\n\nimport { inspectMatrix, inspectMatrixWithOptions } from './inspect';\nimport { installMathOperations } from './mathOperations';\nimport {\n sumByRow,\n sumByColumn,\n sumAll,\n productByRow,\n productByColumn,\n productAll,\n varianceByRow,\n varianceByColumn,\n varianceAll,\n centerByRow,\n centerByColumn,\n centerAll,\n scaleByRow,\n scaleByColumn,\n scaleAll,\n getScaleByRow,\n getScaleByColumn,\n getScaleAll,\n} from './stat';\nimport {\n checkRowVector,\n checkRowIndex,\n checkColumnIndex,\n checkColumnVector,\n checkRange,\n checkNonEmpty,\n checkRowIndices,\n checkColumnIndices,\n} from './util';\n\nexport class AbstractMatrix {\n static from1DArray(newRows, newColumns, newData) {\n let length = newRows * newColumns;\n if (length !== newData.length) {\n throw new RangeError('data length does not match given dimensions');\n }\n let newMatrix = new Matrix(newRows, newColumns);\n for (let row = 0; row < newRows; row++) {\n for (let column = 0; column < newColumns; column++) {\n newMatrix.set(row, column, newData[row * newColumns + column]);\n }\n }\n return newMatrix;\n }\n\n static rowVector(newData) {\n let vector = new Matrix(1, newData.length);\n for (let i = 0; i < newData.length; i++) {\n vector.set(0, i, newData[i]);\n }\n return vector;\n }\n\n static columnVector(newData) {\n let vector = new Matrix(newData.length, 1);\n for (let i = 0; i < newData.length; i++) {\n vector.set(i, 0, newData[i]);\n }\n return vector;\n }\n\n static zeros(rows, columns) {\n return new Matrix(rows, columns);\n }\n\n static ones(rows, columns) {\n return new Matrix(rows, columns).fill(1);\n }\n\n static rand(rows, columns, options = {}) {\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { random = Math.random } = options;\n let matrix = new Matrix(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n matrix.set(i, j, random());\n }\n }\n return matrix;\n }\n\n static randInt(rows, columns, options = {}) {\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { min = 0, max = 1000, random = Math.random } = options;\n if (!Number.isInteger(min)) throw new TypeError('min must be an integer');\n if (!Number.isInteger(max)) throw new TypeError('max must be an integer');\n if (min >= max) throw new RangeError('min must be smaller than max');\n let interval = max - min;\n let matrix = new Matrix(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n let value = min + Math.round(random() * interval);\n matrix.set(i, j, value);\n }\n }\n return matrix;\n }\n\n static eye(rows, columns, value) {\n if (columns === undefined) columns = rows;\n if (value === undefined) value = 1;\n let min = Math.min(rows, columns);\n let matrix = this.zeros(rows, columns);\n for (let i = 0; i < min; i++) {\n matrix.set(i, i, value);\n }\n return matrix;\n }\n\n static diag(data, rows, columns) {\n let l = data.length;\n if (rows === undefined) rows = l;\n if (columns === undefined) columns = rows;\n let min = Math.min(l, rows, columns);\n let matrix = this.zeros(rows, columns);\n for (let i = 0; i < min; i++) {\n matrix.set(i, i, data[i]);\n }\n return matrix;\n }\n\n static min(matrix1, matrix2) {\n matrix1 = this.checkMatrix(matrix1);\n matrix2 = this.checkMatrix(matrix2);\n let rows = matrix1.rows;\n let columns = matrix1.columns;\n let result = new Matrix(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n result.set(i, j, Math.min(matrix1.get(i, j), matrix2.get(i, j)));\n }\n }\n return result;\n }\n\n static max(matrix1, matrix2) {\n matrix1 = this.checkMatrix(matrix1);\n matrix2 = this.checkMatrix(matrix2);\n let rows = matrix1.rows;\n let columns = matrix1.columns;\n let result = new this(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n result.set(i, j, Math.max(matrix1.get(i, j), matrix2.get(i, j)));\n }\n }\n return result;\n }\n\n static checkMatrix(value) {\n return AbstractMatrix.isMatrix(value) ? value : new Matrix(value);\n }\n\n static isMatrix(value) {\n return value != null && value.klass === 'Matrix';\n }\n\n get size() {\n return this.rows * this.columns;\n }\n\n apply(callback) {\n if (typeof callback !== 'function') {\n throw new TypeError('callback must be a function');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n callback.call(this, i, j);\n }\n }\n return this;\n }\n\n to1DArray() {\n let array = [];\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n array.push(this.get(i, j));\n }\n }\n return array;\n }\n\n to2DArray() {\n let copy = [];\n for (let i = 0; i < this.rows; i++) {\n copy.push([]);\n for (let j = 0; j < this.columns; j++) {\n copy[i].push(this.get(i, j));\n }\n }\n return copy;\n }\n\n toJSON() {\n return this.to2DArray();\n }\n\n isRowVector() {\n return this.rows === 1;\n }\n\n isColumnVector() {\n return this.columns === 1;\n }\n\n isVector() {\n return this.rows === 1 || this.columns === 1;\n }\n\n isSquare() {\n return this.rows === this.columns;\n }\n\n isEmpty() {\n return this.rows === 0 || this.columns === 0;\n }\n\n isSymmetric() {\n if (this.isSquare()) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j <= i; j++) {\n if (this.get(i, j) !== this.get(j, i)) {\n return false;\n }\n }\n }\n return true;\n }\n return false;\n }\n\n isEchelonForm() {\n let i = 0;\n let j = 0;\n let previousColumn = -1;\n let isEchelonForm = true;\n let checked = false;\n while (i < this.rows && isEchelonForm) {\n j = 0;\n checked = false;\n while (j < this.columns && checked === false) {\n if (this.get(i, j) === 0) {\n j++;\n } else if (this.get(i, j) === 1 && j > previousColumn) {\n checked = true;\n previousColumn = j;\n } else {\n isEchelonForm = false;\n checked = true;\n }\n }\n i++;\n }\n return isEchelonForm;\n }\n\n isReducedEchelonForm() {\n let i = 0;\n let j = 0;\n let previousColumn = -1;\n let isReducedEchelonForm = true;\n let checked = false;\n while (i < this.rows && isReducedEchelonForm) {\n j = 0;\n checked = false;\n while (j < this.columns && checked === false) {\n if (this.get(i, j) === 0) {\n j++;\n } else if (this.get(i, j) === 1 && j > previousColumn) {\n checked = true;\n previousColumn = j;\n } else {\n isReducedEchelonForm = false;\n checked = true;\n }\n }\n for (let k = j + 1; k < this.rows; k++) {\n if (this.get(i, k) !== 0) {\n isReducedEchelonForm = false;\n }\n }\n i++;\n }\n return isReducedEchelonForm;\n }\n\n echelonForm() {\n let result = this.clone();\n let h = 0;\n let k = 0;\n while (h < result.rows && k < result.columns) {\n let iMax = h;\n for (let i = h; i < result.rows; i++) {\n if (result.get(i, k) > result.get(iMax, k)) {\n iMax = i;\n }\n }\n if (result.get(iMax, k) === 0) {\n k++;\n } else {\n result.swapRows(h, iMax);\n let tmp = result.get(h, k);\n for (let j = k; j < result.columns; j++) {\n result.set(h, j, result.get(h, j) / tmp);\n }\n for (let i = h + 1; i < result.rows; i++) {\n let factor = result.get(i, k) / result.get(h, k);\n result.set(i, k, 0);\n for (let j = k + 1; j < result.columns; j++) {\n result.set(i, j, result.get(i, j) - result.get(h, j) * factor);\n }\n }\n h++;\n k++;\n }\n }\n return result;\n }\n\n reducedEchelonForm() {\n let result = this.echelonForm();\n let m = result.columns;\n let n = result.rows;\n let h = n - 1;\n while (h >= 0) {\n if (result.maxRow(h) === 0) {\n h--;\n } else {\n let p = 0;\n let pivot = false;\n while (p < n && pivot === false) {\n if (result.get(h, p) === 1) {\n pivot = true;\n } else {\n p++;\n }\n }\n for (let i = 0; i < h; i++) {\n let factor = result.get(i, p);\n for (let j = p; j < m; j++) {\n let tmp = result.get(i, j) - factor * result.get(h, j);\n result.set(i, j, tmp);\n }\n }\n h--;\n }\n }\n return result;\n }\n\n set() {\n throw new Error('set method is unimplemented');\n }\n\n get() {\n throw new Error('get method is unimplemented');\n }\n\n repeat(options = {}) {\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { rows = 1, columns = 1 } = options;\n if (!Number.isInteger(rows) || rows <= 0) {\n throw new TypeError('rows must be a positive integer');\n }\n if (!Number.isInteger(columns) || columns <= 0) {\n throw new TypeError('columns must be a positive integer');\n }\n let matrix = new Matrix(this.rows * rows, this.columns * columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n matrix.setSubMatrix(this, this.rows * i, this.columns * j);\n }\n }\n return matrix;\n }\n\n fill(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, value);\n }\n }\n return this;\n }\n\n neg() {\n return this.mulS(-1);\n }\n\n getRow(index) {\n checkRowIndex(this, index);\n let row = [];\n for (let i = 0; i < this.columns; i++) {\n row.push(this.get(index, i));\n }\n return row;\n }\n\n getRowVector(index) {\n return Matrix.rowVector(this.getRow(index));\n }\n\n setRow(index, array) {\n checkRowIndex(this, index);\n array = checkRowVector(this, array);\n for (let i = 0; i < this.columns; i++) {\n this.set(index, i, array[i]);\n }\n return this;\n }\n\n swapRows(row1, row2) {\n checkRowIndex(this, row1);\n checkRowIndex(this, row2);\n for (let i = 0; i < this.columns; i++) {\n let temp = this.get(row1, i);\n this.set(row1, i, this.get(row2, i));\n this.set(row2, i, temp);\n }\n return this;\n }\n\n getColumn(index) {\n checkColumnIndex(this, index);\n let column = [];\n for (let i = 0; i < this.rows; i++) {\n column.push(this.get(i, index));\n }\n return column;\n }\n\n getColumnVector(index) {\n return Matrix.columnVector(this.getColumn(index));\n }\n\n setColumn(index, array) {\n checkColumnIndex(this, index);\n array = checkColumnVector(this, array);\n for (let i = 0; i < this.rows; i++) {\n this.set(i, index, array[i]);\n }\n return this;\n }\n\n swapColumns(column1, column2) {\n checkColumnIndex(this, column1);\n checkColumnIndex(this, column2);\n for (let i = 0; i < this.rows; i++) {\n let temp = this.get(i, column1);\n this.set(i, column1, this.get(i, column2));\n this.set(i, column2, temp);\n }\n return this;\n }\n\n addRowVector(vector) {\n vector = checkRowVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) + vector[j]);\n }\n }\n return this;\n }\n\n subRowVector(vector) {\n vector = checkRowVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) - vector[j]);\n }\n }\n return this;\n }\n\n mulRowVector(vector) {\n vector = checkRowVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) * vector[j]);\n }\n }\n return this;\n }\n\n divRowVector(vector) {\n vector = checkRowVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) / vector[j]);\n }\n }\n return this;\n }\n\n addColumnVector(vector) {\n vector = checkColumnVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) + vector[i]);\n }\n }\n return this;\n }\n\n subColumnVector(vector) {\n vector = checkColumnVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) - vector[i]);\n }\n }\n return this;\n }\n\n mulColumnVector(vector) {\n vector = checkColumnVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) * vector[i]);\n }\n }\n return this;\n }\n\n divColumnVector(vector) {\n vector = checkColumnVector(this, vector);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) / vector[i]);\n }\n }\n return this;\n }\n\n mulRow(index, value) {\n checkRowIndex(this, index);\n for (let i = 0; i < this.columns; i++) {\n this.set(index, i, this.get(index, i) * value);\n }\n return this;\n }\n\n mulColumn(index, value) {\n checkColumnIndex(this, index);\n for (let i = 0; i < this.rows; i++) {\n this.set(i, index, this.get(i, index) * value);\n }\n return this;\n }\n\n max(by) {\n if (this.isEmpty()) {\n return NaN;\n }\n switch (by) {\n case 'row': {\n const max = new Array(this.rows).fill(Number.NEGATIVE_INFINITY);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) > max[row]) {\n max[row] = this.get(row, column);\n }\n }\n }\n return max;\n }\n case 'column': {\n const max = new Array(this.columns).fill(Number.NEGATIVE_INFINITY);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) > max[column]) {\n max[column] = this.get(row, column);\n }\n }\n }\n return max;\n }\n case undefined: {\n let max = this.get(0, 0);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) > max) {\n max = this.get(row, column);\n }\n }\n }\n return max;\n }\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n maxIndex() {\n checkNonEmpty(this);\n let v = this.get(0, 0);\n let idx = [0, 0];\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n if (this.get(i, j) > v) {\n v = this.get(i, j);\n idx[0] = i;\n idx[1] = j;\n }\n }\n }\n return idx;\n }\n\n min(by) {\n if (this.isEmpty()) {\n return NaN;\n }\n\n switch (by) {\n case 'row': {\n const min = new Array(this.rows).fill(Number.POSITIVE_INFINITY);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) < min[row]) {\n min[row] = this.get(row, column);\n }\n }\n }\n return min;\n }\n case 'column': {\n const min = new Array(this.columns).fill(Number.POSITIVE_INFINITY);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) < min[column]) {\n min[column] = this.get(row, column);\n }\n }\n }\n return min;\n }\n case undefined: {\n let min = this.get(0, 0);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n if (this.get(row, column) < min) {\n min = this.get(row, column);\n }\n }\n }\n return min;\n }\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n minIndex() {\n checkNonEmpty(this);\n let v = this.get(0, 0);\n let idx = [0, 0];\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n if (this.get(i, j) < v) {\n v = this.get(i, j);\n idx[0] = i;\n idx[1] = j;\n }\n }\n }\n return idx;\n }\n\n maxRow(row) {\n checkRowIndex(this, row);\n if (this.isEmpty()) {\n return NaN;\n }\n let v = this.get(row, 0);\n for (let i = 1; i < this.columns; i++) {\n if (this.get(row, i) > v) {\n v = this.get(row, i);\n }\n }\n return v;\n }\n\n maxRowIndex(row) {\n checkRowIndex(this, row);\n checkNonEmpty(this);\n let v = this.get(row, 0);\n let idx = [row, 0];\n for (let i = 1; i < this.columns; i++) {\n if (this.get(row, i) > v) {\n v = this.get(row, i);\n idx[1] = i;\n }\n }\n return idx;\n }\n\n minRow(row) {\n checkRowIndex(this, row);\n if (this.isEmpty()) {\n return NaN;\n }\n let v = this.get(row, 0);\n for (let i = 1; i < this.columns; i++) {\n if (this.get(row, i) < v) {\n v = this.get(row, i);\n }\n }\n return v;\n }\n\n minRowIndex(row) {\n checkRowIndex(this, row);\n checkNonEmpty(this);\n let v = this.get(row, 0);\n let idx = [row, 0];\n for (let i = 1; i < this.columns; i++) {\n if (this.get(row, i) < v) {\n v = this.get(row, i);\n idx[1] = i;\n }\n }\n return idx;\n }\n\n maxColumn(column) {\n checkColumnIndex(this, column);\n if (this.isEmpty()) {\n return NaN;\n }\n let v = this.get(0, column);\n for (let i = 1; i < this.rows; i++) {\n if (this.get(i, column) > v) {\n v = this.get(i, column);\n }\n }\n return v;\n }\n\n maxColumnIndex(column) {\n checkColumnIndex(this, column);\n checkNonEmpty(this);\n let v = this.get(0, column);\n let idx = [0, column];\n for (let i = 1; i < this.rows; i++) {\n if (this.get(i, column) > v) {\n v = this.get(i, column);\n idx[0] = i;\n }\n }\n return idx;\n }\n\n minColumn(column) {\n checkColumnIndex(this, column);\n if (this.isEmpty()) {\n return NaN;\n }\n let v = this.get(0, column);\n for (let i = 1; i < this.rows; i++) {\n if (this.get(i, column) < v) {\n v = this.get(i, column);\n }\n }\n return v;\n }\n\n minColumnIndex(column) {\n checkColumnIndex(this, column);\n checkNonEmpty(this);\n let v = this.get(0, column);\n let idx = [0, column];\n for (let i = 1; i < this.rows; i++) {\n if (this.get(i, column) < v) {\n v = this.get(i, column);\n idx[0] = i;\n }\n }\n return idx;\n }\n\n diag() {\n let min = Math.min(this.rows, this.columns);\n let diag = [];\n for (let i = 0; i < min; i++) {\n diag.push(this.get(i, i));\n }\n return diag;\n }\n\n norm(type = 'frobenius') {\n let result = 0;\n if (type === 'max') {\n return this.max();\n } else if (type === 'frobenius') {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n result = result + this.get(i, j) * this.get(i, j);\n }\n }\n return Math.sqrt(result);\n } else {\n throw new RangeError(`unknown norm type: ${type}`);\n }\n }\n\n cumulativeSum() {\n let sum = 0;\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n sum += this.get(i, j);\n this.set(i, j, sum);\n }\n }\n return this;\n }\n\n dot(vector2) {\n if (AbstractMatrix.isMatrix(vector2)) vector2 = vector2.to1DArray();\n let vector1 = this.to1DArray();\n if (vector1.length !== vector2.length) {\n throw new RangeError('vectors do not have the same size');\n }\n let dot = 0;\n for (let i = 0; i < vector1.length; i++) {\n dot += vector1[i] * vector2[i];\n }\n return dot;\n }\n\n mmul(other) {\n other = Matrix.checkMatrix(other);\n\n let m = this.rows;\n let n = this.columns;\n let p = other.columns;\n\n let result = new Matrix(m, p);\n\n let Bcolj = new Float64Array(n);\n for (let j = 0; j < p; j++) {\n for (let k = 0; k < n; k++) {\n Bcolj[k] = other.get(k, j);\n }\n\n for (let i = 0; i < m; i++) {\n let s = 0;\n for (let k = 0; k < n; k++) {\n s += this.get(i, k) * Bcolj[k];\n }\n\n result.set(i, j, s);\n }\n }\n return result;\n }\n\n strassen2x2(other) {\n other = Matrix.checkMatrix(other);\n let result = new Matrix(2, 2);\n const a11 = this.get(0, 0);\n const b11 = other.get(0, 0);\n const a12 = this.get(0, 1);\n const b12 = other.get(0, 1);\n const a21 = this.get(1, 0);\n const b21 = other.get(1, 0);\n const a22 = this.get(1, 1);\n const b22 = other.get(1, 1);\n\n // Compute intermediate values.\n const m1 = (a11 + a22) * (b11 + b22);\n const m2 = (a21 + a22) * b11;\n const m3 = a11 * (b12 - b22);\n const m4 = a22 * (b21 - b11);\n const m5 = (a11 + a12) * b22;\n const m6 = (a21 - a11) * (b11 + b12);\n const m7 = (a12 - a22) * (b21 + b22);\n\n // Combine intermediate values into the output.\n const c00 = m1 + m4 - m5 + m7;\n const c01 = m3 + m5;\n const c10 = m2 + m4;\n const c11 = m1 - m2 + m3 + m6;\n\n result.set(0, 0, c00);\n result.set(0, 1, c01);\n result.set(1, 0, c10);\n result.set(1, 1, c11);\n return result;\n }\n\n strassen3x3(other) {\n other = Matrix.checkMatrix(other);\n let result = new Matrix(3, 3);\n\n const a00 = this.get(0, 0);\n const a01 = this.get(0, 1);\n const a02 = this.get(0, 2);\n const a10 = this.get(1, 0);\n const a11 = this.get(1, 1);\n const a12 = this.get(1, 2);\n const a20 = this.get(2, 0);\n const a21 = this.get(2, 1);\n const a22 = this.get(2, 2);\n\n const b00 = other.get(0, 0);\n const b01 = other.get(0, 1);\n const b02 = other.get(0, 2);\n const b10 = other.get(1, 0);\n const b11 = other.get(1, 1);\n const b12 = other.get(1, 2);\n const b20 = other.get(2, 0);\n const b21 = other.get(2, 1);\n const b22 = other.get(2, 2);\n\n const m1 = (a00 + a01 + a02 - a10 - a11 - a21 - a22) * b11;\n const m2 = (a00 - a10) * (-b01 + b11);\n const m3 = a11 * (-b00 + b01 + b10 - b11 - b12 - b20 + b22);\n const m4 = (-a00 + a10 + a11) * (b00 - b01 + b11);\n const m5 = (a10 + a11) * (-b00 + b01);\n const m6 = a00 * b00;\n const m7 = (-a00 + a20 + a21) * (b00 - b02 + b12);\n const m8 = (-a00 + a20) * (b02 - b12);\n const m9 = (a20 + a21) * (-b00 + b02);\n const m10 = (a00 + a01 + a02 - a11 - a12 - a20 - a21) * b12;\n const m11 = a21 * (-b00 + b02 + b10 - b11 - b12 - b20 + b21);\n const m12 = (-a02 + a21 + a22) * (b11 + b20 - b21);\n const m13 = (a02 - a22) * (b11 - b21);\n const m14 = a02 * b20;\n const m15 = (a21 + a22) * (-b20 + b21);\n const m16 = (-a02 + a11 + a12) * (b12 + b20 - b22);\n const m17 = (a02 - a12) * (b12 - b22);\n const m18 = (a11 + a12) * (-b20 + b22);\n const m19 = a01 * b10;\n const m20 = a12 * b21;\n const m21 = a10 * b02;\n const m22 = a20 * b01;\n const m23 = a22 * b22;\n\n const c00 = m6 + m14 + m19;\n const c01 = m1 + m4 + m5 + m6 + m12 + m14 + m15;\n const c02 = m6 + m7 + m9 + m10 + m14 + m16 + m18;\n const c10 = m2 + m3 + m4 + m6 + m14 + m16 + m17;\n const c11 = m2 + m4 + m5 + m6 + m20;\n const c12 = m14 + m16 + m17 + m18 + m21;\n const c20 = m6 + m7 + m8 + m11 + m12 + m13 + m14;\n const c21 = m12 + m13 + m14 + m15 + m22;\n const c22 = m6 + m7 + m8 + m9 + m23;\n\n result.set(0, 0, c00);\n result.set(0, 1, c01);\n result.set(0, 2, c02);\n result.set(1, 0, c10);\n result.set(1, 1, c11);\n result.set(1, 2, c12);\n result.set(2, 0, c20);\n result.set(2, 1, c21);\n result.set(2, 2, c22);\n return result;\n }\n\n mmulStrassen(y) {\n y = Matrix.checkMatrix(y);\n let x = this.clone();\n let r1 = x.rows;\n let c1 = x.columns;\n let r2 = y.rows;\n let c2 = y.columns;\n if (c1 !== r2) {\n // eslint-disable-next-line no-console\n console.warn(\n `Multiplying ${r1} x ${c1} and ${r2} x ${c2} matrix: dimensions do not match.`,\n );\n }\n\n // Put a matrix into the top left of a matrix of zeros.\n // `rows` and `cols` are the dimensions of the output matrix.\n function embed(mat, rows, cols) {\n let r = mat.rows;\n let c = mat.columns;\n if (r === rows && c === cols) {\n return mat;\n } else {\n let resultat = AbstractMatrix.zeros(rows, cols);\n resultat = resultat.setSubMatrix(mat, 0, 0);\n return resultat;\n }\n }\n\n // Make sure both matrices are the same size.\n // This is exclusively for simplicity:\n // this algorithm can be implemented with matrices of different sizes.\n\n let r = Math.max(r1, r2);\n let c = Math.max(c1, c2);\n x = embed(x, r, c);\n y = embed(y, r, c);\n\n // Our recursive multiplication function.\n function blockMult(a, b, rows, cols) {\n // For small matrices, resort to naive multiplication.\n if (rows <= 512 || cols <= 512) {\n return a.mmul(b); // a is equivalent to this\n }\n\n // Apply dynamic padding.\n if (rows % 2 === 1 && cols % 2 === 1) {\n a = embed(a, rows + 1, cols + 1);\n b = embed(b, rows + 1, cols + 1);\n } else if (rows % 2 === 1) {\n a = embed(a, rows + 1, cols);\n b = embed(b, rows + 1, cols);\n } else if (cols % 2 === 1) {\n a = embed(a, rows, cols + 1);\n b = embed(b, rows, cols + 1);\n }\n\n let halfRows = parseInt(a.rows / 2, 10);\n let halfCols = parseInt(a.columns / 2, 10);\n // Subdivide input matrices.\n let a11 = a.subMatrix(0, halfRows - 1, 0, halfCols - 1);\n let b11 = b.subMatrix(0, halfRows - 1, 0, halfCols - 1);\n\n let a12 = a.subMatrix(0, halfRows - 1, halfCols, a.columns - 1);\n let b12 = b.subMatrix(0, halfRows - 1, halfCols, b.columns - 1);\n\n let a21 = a.subMatrix(halfRows, a.rows - 1, 0, halfCols - 1);\n let b21 = b.subMatrix(halfRows, b.rows - 1, 0, halfCols - 1);\n\n let a22 = a.subMatrix(halfRows, a.rows - 1, halfCols, a.columns - 1);\n let b22 = b.subMatrix(halfRows, b.rows - 1, halfCols, b.columns - 1);\n\n // Compute intermediate values.\n let m1 = blockMult(\n AbstractMatrix.add(a11, a22),\n AbstractMatrix.add(b11, b22),\n halfRows,\n halfCols,\n );\n let m2 = blockMult(AbstractMatrix.add(a21, a22), b11, halfRows, halfCols);\n let m3 = blockMult(a11, AbstractMatrix.sub(b12, b22), halfRows, halfCols);\n let m4 = blockMult(a22, AbstractMatrix.sub(b21, b11), halfRows, halfCols);\n let m5 = blockMult(AbstractMatrix.add(a11, a12), b22, halfRows, halfCols);\n let m6 = blockMult(\n AbstractMatrix.sub(a21, a11),\n AbstractMatrix.add(b11, b12),\n halfRows,\n halfCols,\n );\n let m7 = blockMult(\n AbstractMatrix.sub(a12, a22),\n AbstractMatrix.add(b21, b22),\n halfRows,\n halfCols,\n );\n\n // Combine intermediate values into the output.\n let c11 = AbstractMatrix.add(m1, m4);\n c11.sub(m5);\n c11.add(m7);\n let c12 = AbstractMatrix.add(m3, m5);\n let c21 = AbstractMatrix.add(m2, m4);\n let c22 = AbstractMatrix.sub(m1, m2);\n c22.add(m3);\n c22.add(m6);\n\n // Crop output to the desired size (undo dynamic padding).\n let resultat = AbstractMatrix.zeros(2 * c11.rows, 2 * c11.columns);\n resultat = resultat.setSubMatrix(c11, 0, 0);\n resultat = resultat.setSubMatrix(c12, c11.rows, 0);\n resultat = resultat.setSubMatrix(c21, 0, c11.columns);\n resultat = resultat.setSubMatrix(c22, c11.rows, c11.columns);\n return resultat.subMatrix(0, rows - 1, 0, cols - 1);\n }\n\n return blockMult(x, y, r, c);\n }\n\n scaleRows(options = {}) {\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { min = 0, max = 1 } = options;\n if (!Number.isFinite(min)) throw new TypeError('min must be a number');\n if (!Number.isFinite(max)) throw new TypeError('max must be a number');\n if (min >= max) throw new RangeError('min must be smaller than max');\n let newMatrix = new Matrix(this.rows, this.columns);\n for (let i = 0; i < this.rows; i++) {\n const row = this.getRow(i);\n if (row.length > 0) {\n rescale(row, { min, max, output: row });\n }\n newMatrix.setRow(i, row);\n }\n return newMatrix;\n }\n\n scaleColumns(options = {}) {\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { min = 0, max = 1 } = options;\n if (!Number.isFinite(min)) throw new TypeError('min must be a number');\n if (!Number.isFinite(max)) throw new TypeError('max must be a number');\n if (min >= max) throw new RangeError('min must be smaller than max');\n let newMatrix = new Matrix(this.rows, this.columns);\n for (let i = 0; i < this.columns; i++) {\n const column = this.getColumn(i);\n if (column.length) {\n rescale(column, {\n min: min,\n max: max,\n output: column,\n });\n }\n newMatrix.setColumn(i, column);\n }\n return newMatrix;\n }\n\n flipRows() {\n const middle = Math.ceil(this.columns / 2);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < middle; j++) {\n let first = this.get(i, j);\n let last = this.get(i, this.columns - 1 - j);\n this.set(i, j, last);\n this.set(i, this.columns - 1 - j, first);\n }\n }\n return this;\n }\n\n flipColumns() {\n const middle = Math.ceil(this.rows / 2);\n for (let j = 0; j < this.columns; j++) {\n for (let i = 0; i < middle; i++) {\n let first = this.get(i, j);\n let last = this.get(this.rows - 1 - i, j);\n this.set(i, j, last);\n this.set(this.rows - 1 - i, j, first);\n }\n }\n return this;\n }\n\n kroneckerProduct(other) {\n other = Matrix.checkMatrix(other);\n\n let m = this.rows;\n let n = this.columns;\n let p = other.rows;\n let q = other.columns;\n\n let result = new Matrix(m * p, n * q);\n for (let i = 0; i < m; i++) {\n for (let j = 0; j < n; j++) {\n for (let k = 0; k < p; k++) {\n for (let l = 0; l < q; l++) {\n result.set(p * i + k, q * j + l, this.get(i, j) * other.get(k, l));\n }\n }\n }\n }\n return result;\n }\n\n kroneckerSum(other) {\n other = Matrix.checkMatrix(other);\n if (!this.isSquare() || !other.isSquare()) {\n throw new Error('Kronecker Sum needs two Square Matrices');\n }\n let m = this.rows;\n let n = other.rows;\n let AxI = this.kroneckerProduct(Matrix.eye(n, n));\n let IxB = Matrix.eye(m, m).kroneckerProduct(other);\n return AxI.add(IxB);\n }\n\n transpose() {\n let result = new Matrix(this.columns, this.rows);\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n result.set(j, i, this.get(i, j));\n }\n }\n return result;\n }\n\n sortRows(compareFunction = compareNumbers) {\n for (let i = 0; i < this.rows; i++) {\n this.setRow(i, this.getRow(i).sort(compareFunction));\n }\n return this;\n }\n\n sortColumns(compareFunction = compareNumbers) {\n for (let i = 0; i < this.columns; i++) {\n this.setColumn(i, this.getColumn(i).sort(compareFunction));\n }\n return this;\n }\n\n subMatrix(startRow, endRow, startColumn, endColumn) {\n checkRange(this, startRow, endRow, startColumn, endColumn);\n let newMatrix = new Matrix(\n endRow - startRow + 1,\n endColumn - startColumn + 1,\n );\n for (let i = startRow; i <= endRow; i++) {\n for (let j = startColumn; j <= endColumn; j++) {\n newMatrix.set(i - startRow, j - startColumn, this.get(i, j));\n }\n }\n return newMatrix;\n }\n\n subMatrixRow(indices, startColumn, endColumn) {\n if (startColumn === undefined) startColumn = 0;\n if (endColumn === undefined) endColumn = this.columns - 1;\n if (\n startColumn > endColumn ||\n startColumn < 0 ||\n startColumn >= this.columns ||\n endColumn < 0 ||\n endColumn >= this.columns\n ) {\n throw new RangeError('Argument out of range');\n }\n\n let newMatrix = new Matrix(indices.length, endColumn - startColumn + 1);\n for (let i = 0; i < indices.length; i++) {\n for (let j = startColumn; j <= endColumn; j++) {\n if (indices[i] < 0 || indices[i] >= this.rows) {\n throw new RangeError(`Row index out of range: ${indices[i]}`);\n }\n newMatrix.set(i, j - startColumn, this.get(indices[i], j));\n }\n }\n return newMatrix;\n }\n\n subMatrixColumn(indices, startRow, endRow) {\n if (startRow === undefined) startRow = 0;\n if (endRow === undefined) endRow = this.rows - 1;\n if (\n startRow > endRow ||\n startRow < 0 ||\n startRow >= this.rows ||\n endRow < 0 ||\n endRow >= this.rows\n ) {\n throw new RangeError('Argument out of range');\n }\n\n let newMatrix = new Matrix(endRow - startRow + 1, indices.length);\n for (let i = 0; i < indices.length; i++) {\n for (let j = startRow; j <= endRow; j++) {\n if (indices[i] < 0 || indices[i] >= this.columns) {\n throw new RangeError(`Column index out of range: ${indices[i]}`);\n }\n newMatrix.set(j - startRow, i, this.get(j, indices[i]));\n }\n }\n return newMatrix;\n }\n\n setSubMatrix(matrix, startRow, startColumn) {\n matrix = Matrix.checkMatrix(matrix);\n if (matrix.isEmpty()) {\n return this;\n }\n let endRow = startRow + matrix.rows - 1;\n let endColumn = startColumn + matrix.columns - 1;\n checkRange(this, startRow, endRow, startColumn, endColumn);\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n this.set(startRow + i, startColumn + j, matrix.get(i, j));\n }\n }\n return this;\n }\n\n selection(rowIndices, columnIndices) {\n checkRowIndices(this, rowIndices);\n checkColumnIndices(this, columnIndices);\n let newMatrix = new Matrix(rowIndices.length, columnIndices.length);\n for (let i = 0; i < rowIndices.length; i++) {\n let rowIndex = rowIndices[i];\n for (let j = 0; j < columnIndices.length; j++) {\n let columnIndex = columnIndices[j];\n newMatrix.set(i, j, this.get(rowIndex, columnIndex));\n }\n }\n return newMatrix;\n }\n\n trace() {\n let min = Math.min(this.rows, this.columns);\n let trace = 0;\n for (let i = 0; i < min; i++) {\n trace += this.get(i, i);\n }\n return trace;\n }\n\n clone() {\n let newMatrix = new Matrix(this.rows, this.columns);\n for (let row = 0; row < this.rows; row++) {\n for (let column = 0; column < this.columns; column++) {\n newMatrix.set(row, column, this.get(row, column));\n }\n }\n return newMatrix;\n }\n\n sum(by) {\n switch (by) {\n case 'row':\n return sumByRow(this);\n case 'column':\n return sumByColumn(this);\n case undefined:\n return sumAll(this);\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n product(by) {\n switch (by) {\n case 'row':\n return productByRow(this);\n case 'column':\n return productByColumn(this);\n case undefined:\n return productAll(this);\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n mean(by) {\n const sum = this.sum(by);\n switch (by) {\n case 'row': {\n for (let i = 0; i < this.rows; i++) {\n sum[i] /= this.columns;\n }\n return sum;\n }\n case 'column': {\n for (let i = 0; i < this.columns; i++) {\n sum[i] /= this.rows;\n }\n return sum;\n }\n case undefined:\n return sum / this.size;\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n variance(by, options = {}) {\n if (typeof by === 'object') {\n options = by;\n by = undefined;\n }\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { unbiased = true, mean = this.mean(by) } = options;\n if (typeof unbiased !== 'boolean') {\n throw new TypeError('unbiased must be a boolean');\n }\n switch (by) {\n case 'row': {\n if (!isAnyArray(mean)) {\n throw new TypeError('mean must be an array');\n }\n return varianceByRow(this, unbiased, mean);\n }\n case 'column': {\n if (!isAnyArray(mean)) {\n throw new TypeError('mean must be an array');\n }\n return varianceByColumn(this, unbiased, mean);\n }\n case undefined: {\n if (typeof mean !== 'number') {\n throw new TypeError('mean must be a number');\n }\n return varianceAll(this, unbiased, mean);\n }\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n standardDeviation(by, options) {\n if (typeof by === 'object') {\n options = by;\n by = undefined;\n }\n const variance = this.variance(by, options);\n if (by === undefined) {\n return Math.sqrt(variance);\n } else {\n for (let i = 0; i < variance.length; i++) {\n variance[i] = Math.sqrt(variance[i]);\n }\n return variance;\n }\n }\n\n center(by, options = {}) {\n if (typeof by === 'object') {\n options = by;\n by = undefined;\n }\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n const { center = this.mean(by) } = options;\n switch (by) {\n case 'row': {\n if (!isAnyArray(center)) {\n throw new TypeError('center must be an array');\n }\n centerByRow(this, center);\n return this;\n }\n case 'column': {\n if (!isAnyArray(center)) {\n throw new TypeError('center must be an array');\n }\n centerByColumn(this, center);\n return this;\n }\n case undefined: {\n if (typeof center !== 'number') {\n throw new TypeError('center must be a number');\n }\n centerAll(this, center);\n return this;\n }\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n scale(by, options = {}) {\n if (typeof by === 'object') {\n options = by;\n by = undefined;\n }\n if (typeof options !== 'object') {\n throw new TypeError('options must be an object');\n }\n let scale = options.scale;\n switch (by) {\n case 'row': {\n if (scale === undefined) {\n scale = getScaleByRow(this);\n } else if (!isAnyArray(scale)) {\n throw new TypeError('scale must be an array');\n }\n scaleByRow(this, scale);\n return this;\n }\n case 'column': {\n if (scale === undefined) {\n scale = getScaleByColumn(this);\n } else if (!isAnyArray(scale)) {\n throw new TypeError('scale must be an array');\n }\n scaleByColumn(this, scale);\n return this;\n }\n case undefined: {\n if (scale === undefined) {\n scale = getScaleAll(this);\n } else if (typeof scale !== 'number') {\n throw new TypeError('scale must be a number');\n }\n scaleAll(this, scale);\n return this;\n }\n default:\n throw new Error(`invalid option: ${by}`);\n }\n }\n\n toString(options) {\n return inspectMatrixWithOptions(this, options);\n }\n}\n\nAbstractMatrix.prototype.klass = 'Matrix';\nif (typeof Symbol !== 'undefined') {\n AbstractMatrix.prototype[Symbol.for('nodejs.util.inspect.custom')] =\n inspectMatrix;\n}\n\nfunction compareNumbers(a, b) {\n return a - b;\n}\n\nfunction isArrayOfNumbers(array) {\n return array.every((element) => {\n return typeof element === 'number';\n });\n}\n\n// Synonyms\nAbstractMatrix.random = AbstractMatrix.rand;\nAbstractMatrix.randomInt = AbstractMatrix.randInt;\nAbstractMatrix.diagonal = AbstractMatrix.diag;\nAbstractMatrix.prototype.diagonal = AbstractMatrix.prototype.diag;\nAbstractMatrix.identity = AbstractMatrix.eye;\nAbstractMatrix.prototype.negate = AbstractMatrix.prototype.neg;\nAbstractMatrix.prototype.tensorProduct =\n AbstractMatrix.prototype.kroneckerProduct;\n\nexport default class Matrix extends AbstractMatrix {\n constructor(nRows, nColumns) {\n super();\n if (Matrix.isMatrix(nRows)) {\n // eslint-disable-next-line no-constructor-return\n return nRows.clone();\n } else if (Number.isInteger(nRows) && nRows >= 0) {\n // Create an empty matrix\n this.data = [];\n if (Number.isInteger(nColumns) && nColumns >= 0) {\n for (let i = 0; i < nRows; i++) {\n this.data.push(new Float64Array(nColumns));\n }\n } else {\n throw new TypeError('nColumns must be a positive integer');\n }\n } else if (isAnyArray(nRows)) {\n // Copy the values from the 2D array\n const arrayData = nRows;\n nRows = arrayData.length;\n nColumns = nRows ? arrayData[0].length : 0;\n if (typeof nColumns !== 'number') {\n throw new TypeError(\n 'Data must be a 2D array with at least one element',\n );\n }\n this.data = [];\n for (let i = 0; i < nRows; i++) {\n if (arrayData[i].length !== nColumns) {\n throw new RangeError('Inconsistent array dimensions');\n }\n if (!isArrayOfNumbers(arrayData[i])) {\n throw new TypeError('Input data contains non-numeric values');\n }\n this.data.push(Float64Array.from(arrayData[i]));\n }\n } else {\n throw new TypeError(\n 'First argument must be a positive number or an array',\n );\n }\n this.rows = nRows;\n this.columns = nColumns;\n }\n\n set(rowIndex, columnIndex, value) {\n this.data[rowIndex][columnIndex] = value;\n return this;\n }\n\n get(rowIndex, columnIndex) {\n return this.data[rowIndex][columnIndex];\n }\n\n removeRow(index) {\n checkRowIndex(this, index);\n this.data.splice(index, 1);\n this.rows -= 1;\n return this;\n }\n\n addRow(index, array) {\n if (array === undefined) {\n array = index;\n index = this.rows;\n }\n checkRowIndex(this, index, true);\n array = Float64Array.from(checkRowVector(this, array));\n this.data.splice(index, 0, array);\n this.rows += 1;\n return this;\n }\n\n removeColumn(index) {\n checkColumnIndex(this, index);\n for (let i = 0; i < this.rows; i++) {\n const newRow = new Float64Array(this.columns - 1);\n for (let j = 0; j < index; j++) {\n newRow[j] = this.data[i][j];\n }\n for (let j = index + 1; j < this.columns; j++) {\n newRow[j - 1] = this.data[i][j];\n }\n this.data[i] = newRow;\n }\n this.columns -= 1;\n return this;\n }\n\n addColumn(index, array) {\n if (typeof array === 'undefined') {\n array = index;\n index = this.columns;\n }\n checkColumnIndex(this, index, true);\n array = checkColumnVector(this, array);\n for (let i = 0; i < this.rows; i++) {\n const newRow = new Float64Array(this.columns + 1);\n let j = 0;\n for (; j < index; j++) {\n newRow[j] = this.data[i][j];\n }\n newRow[j++] = array[i];\n for (; j < this.columns + 1; j++) {\n newRow[j] = this.data[i][j - 1];\n }\n this.data[i] = newRow;\n }\n this.columns += 1;\n return this;\n }\n}\n\ninstallMathOperations(AbstractMatrix, Matrix);\n","import { newArray } from './util';\n\nexport function sumByRow(matrix) {\n let sum = newArray(matrix.rows);\n for (let i = 0; i < matrix.rows; ++i) {\n for (let j = 0; j < matrix.columns; ++j) {\n sum[i] += matrix.get(i, j);\n }\n }\n return sum;\n}\n\nexport function sumByColumn(matrix) {\n let sum = newArray(matrix.columns);\n for (let i = 0; i < matrix.rows; ++i) {\n for (let j = 0; j < matrix.columns; ++j) {\n sum[j] += matrix.get(i, j);\n }\n }\n return sum;\n}\n\nexport function sumAll(matrix) {\n let v = 0;\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n v += matrix.get(i, j);\n }\n }\n return v;\n}\n\nexport function productByRow(matrix) {\n let sum = newArray(matrix.rows, 1);\n for (let i = 0; i < matrix.rows; ++i) {\n for (let j = 0; j < matrix.columns; ++j) {\n sum[i] *= matrix.get(i, j);\n }\n }\n return sum;\n}\n\nexport function productByColumn(matrix) {\n let sum = newArray(matrix.columns, 1);\n for (let i = 0; i < matrix.rows; ++i) {\n for (let j = 0; j < matrix.columns; ++j) {\n sum[j] *= matrix.get(i, j);\n }\n }\n return sum;\n}\n\nexport function productAll(matrix) {\n let v = 1;\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n v *= matrix.get(i, j);\n }\n }\n return v;\n}\n\nexport function varianceByRow(matrix, unbiased, mean) {\n const rows = matrix.rows;\n const cols = matrix.columns;\n const variance = [];\n\n for (let i = 0; i < rows; i++) {\n let sum1 = 0;\n let sum2 = 0;\n let x = 0;\n for (let j = 0; j < cols; j++) {\n x = matrix.get(i, j) - mean[i];\n sum1 += x;\n sum2 += x * x;\n }\n if (unbiased) {\n variance.push((sum2 - (sum1 * sum1) / cols) / (cols - 1));\n } else {\n variance.push((sum2 - (sum1 * sum1) / cols) / cols);\n }\n }\n return variance;\n}\n\nexport function varianceByColumn(matrix, unbiased, mean) {\n const rows = matrix.rows;\n const cols = matrix.columns;\n const variance = [];\n\n for (let j = 0; j < cols; j++) {\n let sum1 = 0;\n let sum2 = 0;\n let x = 0;\n for (let i = 0; i < rows; i++) {\n x = matrix.get(i, j) - mean[j];\n sum1 += x;\n sum2 += x * x;\n }\n if (unbiased) {\n variance.push((sum2 - (sum1 * sum1) / rows) / (rows - 1));\n } else {\n variance.push((sum2 - (sum1 * sum1) / rows) / rows);\n }\n }\n return variance;\n}\n\nexport function varianceAll(matrix, unbiased, mean) {\n const rows = matrix.rows;\n const cols = matrix.columns;\n const size = rows * cols;\n\n let sum1 = 0;\n let sum2 = 0;\n let x = 0;\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < cols; j++) {\n x = matrix.get(i, j) - mean;\n sum1 += x;\n sum2 += x * x;\n }\n }\n if (unbiased) {\n return (sum2 - (sum1 * sum1) / size) / (size - 1);\n } else {\n return (sum2 - (sum1 * sum1) / size) / size;\n }\n}\n\nexport function centerByRow(matrix, mean) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) - mean[i]);\n }\n }\n}\n\nexport function centerByColumn(matrix, mean) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) - mean[j]);\n }\n }\n}\n\nexport function centerAll(matrix, mean) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) - mean);\n }\n }\n}\n\nexport function getScaleByRow(matrix) {\n const scale = [];\n for (let i = 0; i < matrix.rows; i++) {\n let sum = 0;\n for (let j = 0; j < matrix.columns; j++) {\n sum += Math.pow(matrix.get(i, j), 2) / (matrix.columns - 1);\n }\n scale.push(Math.sqrt(sum));\n }\n return scale;\n}\n\nexport function scaleByRow(matrix, scale) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) / scale[i]);\n }\n }\n}\n\nexport function getScaleByColumn(matrix) {\n const scale = [];\n for (let j = 0; j < matrix.columns; j++) {\n let sum = 0;\n for (let i = 0; i < matrix.rows; i++) {\n sum += Math.pow(matrix.get(i, j), 2) / (matrix.rows - 1);\n }\n scale.push(Math.sqrt(sum));\n }\n return scale;\n}\n\nexport function scaleByColumn(matrix, scale) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) / scale[j]);\n }\n }\n}\n\nexport function getScaleAll(matrix) {\n const divider = matrix.size - 1;\n let sum = 0;\n for (let j = 0; j < matrix.columns; j++) {\n for (let i = 0; i < matrix.rows; i++) {\n sum += Math.pow(matrix.get(i, j), 2) / divider;\n }\n }\n return Math.sqrt(sum);\n}\n\nexport function scaleAll(matrix, scale) {\n for (let i = 0; i < matrix.rows; i++) {\n for (let j = 0; j < matrix.columns; j++) {\n matrix.set(i, j, matrix.get(i, j) / scale);\n }\n }\n}\n","export function installMathOperations(AbstractMatrix, Matrix) {\n AbstractMatrix.prototype.add = function add(value) {\n if (typeof value === 'number') return this.addS(value);\n return this.addM(value);\n };\n\n AbstractMatrix.prototype.addS = function addS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) + value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.addM = function addM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) + matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.add = function add(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.add(value);\n };\n\n AbstractMatrix.prototype.sub = function sub(value) {\n if (typeof value === 'number') return this.subS(value);\n return this.subM(value);\n };\n\n AbstractMatrix.prototype.subS = function subS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) - value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.subM = function subM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) - matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.sub = function sub(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.sub(value);\n };\n AbstractMatrix.prototype.subtract = AbstractMatrix.prototype.sub;\n AbstractMatrix.prototype.subtractS = AbstractMatrix.prototype.subS;\n AbstractMatrix.prototype.subtractM = AbstractMatrix.prototype.subM;\n AbstractMatrix.subtract = AbstractMatrix.sub;\n\n AbstractMatrix.prototype.mul = function mul(value) {\n if (typeof value === 'number') return this.mulS(value);\n return this.mulM(value);\n };\n\n AbstractMatrix.prototype.mulS = function mulS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) * value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.mulM = function mulM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) * matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.mul = function mul(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.mul(value);\n };\n AbstractMatrix.prototype.multiply = AbstractMatrix.prototype.mul;\n AbstractMatrix.prototype.multiplyS = AbstractMatrix.prototype.mulS;\n AbstractMatrix.prototype.multiplyM = AbstractMatrix.prototype.mulM;\n AbstractMatrix.multiply = AbstractMatrix.mul;\n\n AbstractMatrix.prototype.div = function div(value) {\n if (typeof value === 'number') return this.divS(value);\n return this.divM(value);\n };\n\n AbstractMatrix.prototype.divS = function divS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) / value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.divM = function divM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) / matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.div = function div(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.div(value);\n };\n AbstractMatrix.prototype.divide = AbstractMatrix.prototype.div;\n AbstractMatrix.prototype.divideS = AbstractMatrix.prototype.divS;\n AbstractMatrix.prototype.divideM = AbstractMatrix.prototype.divM;\n AbstractMatrix.divide = AbstractMatrix.div;\n\n AbstractMatrix.prototype.mod = function mod(value) {\n if (typeof value === 'number') return this.modS(value);\n return this.modM(value);\n };\n\n AbstractMatrix.prototype.modS = function modS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) % value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.modM = function modM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) % matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.mod = function mod(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.mod(value);\n };\n AbstractMatrix.prototype.modulus = AbstractMatrix.prototype.mod;\n AbstractMatrix.prototype.modulusS = AbstractMatrix.prototype.modS;\n AbstractMatrix.prototype.modulusM = AbstractMatrix.prototype.modM;\n AbstractMatrix.modulus = AbstractMatrix.mod;\n\n AbstractMatrix.prototype.and = function and(value) {\n if (typeof value === 'number') return this.andS(value);\n return this.andM(value);\n };\n\n AbstractMatrix.prototype.andS = function andS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) & value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.andM = function andM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) & matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.and = function and(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.and(value);\n };\n\n AbstractMatrix.prototype.or = function or(value) {\n if (typeof value === 'number') return this.orS(value);\n return this.orM(value);\n };\n\n AbstractMatrix.prototype.orS = function orS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) | value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.orM = function orM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) | matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.or = function or(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.or(value);\n };\n\n AbstractMatrix.prototype.xor = function xor(value) {\n if (typeof value === 'number') return this.xorS(value);\n return this.xorM(value);\n };\n\n AbstractMatrix.prototype.xorS = function xorS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) ^ value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.xorM = function xorM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) ^ matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.xor = function xor(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.xor(value);\n };\n\n AbstractMatrix.prototype.leftShift = function leftShift(value) {\n if (typeof value === 'number') return this.leftShiftS(value);\n return this.leftShiftM(value);\n };\n\n AbstractMatrix.prototype.leftShiftS = function leftShiftS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) << value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.leftShiftM = function leftShiftM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) << matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.leftShift = function leftShift(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.leftShift(value);\n };\n\n AbstractMatrix.prototype.signPropagatingRightShift = function signPropagatingRightShift(value) {\n if (typeof value === 'number') return this.signPropagatingRightShiftS(value);\n return this.signPropagatingRightShiftM(value);\n };\n\n AbstractMatrix.prototype.signPropagatingRightShiftS = function signPropagatingRightShiftS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) >> value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.signPropagatingRightShiftM = function signPropagatingRightShiftM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) >> matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.signPropagatingRightShift = function signPropagatingRightShift(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.signPropagatingRightShift(value);\n };\n\n AbstractMatrix.prototype.rightShift = function rightShift(value) {\n if (typeof value === 'number') return this.rightShiftS(value);\n return this.rightShiftM(value);\n };\n\n AbstractMatrix.prototype.rightShiftS = function rightShiftS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) >>> value);\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.rightShiftM = function rightShiftM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, this.get(i, j) >>> matrix.get(i, j));\n }\n }\n return this;\n };\n\n AbstractMatrix.rightShift = function rightShift(matrix, value) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.rightShift(value);\n };\n AbstractMatrix.prototype.zeroFillRightShift = AbstractMatrix.prototype.rightShift;\n AbstractMatrix.prototype.zeroFillRightShiftS = AbstractMatrix.prototype.rightShiftS;\n AbstractMatrix.prototype.zeroFillRightShiftM = AbstractMatrix.prototype.rightShiftM;\n AbstractMatrix.zeroFillRightShift = AbstractMatrix.rightShift;\n\n AbstractMatrix.prototype.not = function not() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, ~(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.not = function not(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.not();\n };\n\n AbstractMatrix.prototype.abs = function abs() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.abs(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.abs = function abs(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.abs();\n };\n\n AbstractMatrix.prototype.acos = function acos() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.acos(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.acos = function acos(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.acos();\n };\n\n AbstractMatrix.prototype.acosh = function acosh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.acosh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.acosh = function acosh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.acosh();\n };\n\n AbstractMatrix.prototype.asin = function asin() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.asin(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.asin = function asin(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.asin();\n };\n\n AbstractMatrix.prototype.asinh = function asinh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.asinh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.asinh = function asinh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.asinh();\n };\n\n AbstractMatrix.prototype.atan = function atan() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.atan(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.atan = function atan(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.atan();\n };\n\n AbstractMatrix.prototype.atanh = function atanh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.atanh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.atanh = function atanh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.atanh();\n };\n\n AbstractMatrix.prototype.cbrt = function cbrt() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.cbrt(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.cbrt = function cbrt(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.cbrt();\n };\n\n AbstractMatrix.prototype.ceil = function ceil() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.ceil(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.ceil = function ceil(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.ceil();\n };\n\n AbstractMatrix.prototype.clz32 = function clz32() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.clz32(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.clz32 = function clz32(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.clz32();\n };\n\n AbstractMatrix.prototype.cos = function cos() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.cos(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.cos = function cos(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.cos();\n };\n\n AbstractMatrix.prototype.cosh = function cosh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.cosh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.cosh = function cosh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.cosh();\n };\n\n AbstractMatrix.prototype.exp = function exp() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.exp(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.exp = function exp(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.exp();\n };\n\n AbstractMatrix.prototype.expm1 = function expm1() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.expm1(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.expm1 = function expm1(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.expm1();\n };\n\n AbstractMatrix.prototype.floor = function floor() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.floor(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.floor = function floor(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.floor();\n };\n\n AbstractMatrix.prototype.fround = function fround() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.fround(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.fround = function fround(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.fround();\n };\n\n AbstractMatrix.prototype.log = function log() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.log(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.log = function log(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.log();\n };\n\n AbstractMatrix.prototype.log1p = function log1p() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.log1p(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.log1p = function log1p(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.log1p();\n };\n\n AbstractMatrix.prototype.log10 = function log10() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.log10(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.log10 = function log10(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.log10();\n };\n\n AbstractMatrix.prototype.log2 = function log2() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.log2(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.log2 = function log2(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.log2();\n };\n\n AbstractMatrix.prototype.round = function round() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.round(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.round = function round(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.round();\n };\n\n AbstractMatrix.prototype.sign = function sign() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.sign(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.sign = function sign(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.sign();\n };\n\n AbstractMatrix.prototype.sin = function sin() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.sin(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.sin = function sin(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.sin();\n };\n\n AbstractMatrix.prototype.sinh = function sinh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.sinh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.sinh = function sinh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.sinh();\n };\n\n AbstractMatrix.prototype.sqrt = function sqrt() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.sqrt(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.sqrt = function sqrt(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.sqrt();\n };\n\n AbstractMatrix.prototype.tan = function tan() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.tan(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.tan = function tan(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.tan();\n };\n\n AbstractMatrix.prototype.tanh = function tanh() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.tanh(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.tanh = function tanh(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.tanh();\n };\n\n AbstractMatrix.prototype.trunc = function trunc() {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.trunc(this.get(i, j)));\n }\n }\n return this;\n };\n\n AbstractMatrix.trunc = function trunc(matrix) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.trunc();\n };\n\n AbstractMatrix.pow = function pow(matrix, arg0) {\n const newMatrix = new Matrix(matrix);\n return newMatrix.pow(arg0);\n };\n\n AbstractMatrix.prototype.pow = function pow(value) {\n if (typeof value === 'number') return this.powS(value);\n return this.powM(value);\n };\n\n AbstractMatrix.prototype.powS = function powS(value) {\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.pow(this.get(i, j), value));\n }\n }\n return this;\n };\n\n AbstractMatrix.prototype.powM = function powM(matrix) {\n matrix = Matrix.checkMatrix(matrix);\n if (this.rows !== matrix.rows ||\n this.columns !== matrix.columns) {\n throw new RangeError('Matrices dimensions must be equal');\n }\n for (let i = 0; i < this.rows; i++) {\n for (let j = 0; j < this.columns; j++) {\n this.set(i, j, Math.pow(this.get(i, j), matrix.get(i, j)));\n }\n }\n return this;\n };\n}\n","import { AbstractMatrix } from '../matrix';\n\nexport default class WrapperMatrix2D extends AbstractMatrix {\n constructor(data) {\n super();\n this.data = data;\n this.rows = data.length;\n this.columns = data[0].length;\n }\n\n set(rowIndex, columnIndex, value) {\n this.data[rowIndex][columnIndex] = value;\n return this;\n }\n\n get(rowIndex, columnIndex) {\n return this.data[rowIndex][columnIndex];\n }\n}\n","import Matrix from '../matrix';\nimport WrapperMatrix2D from '../wrap/WrapperMatrix2D';\n\nexport default class LuDecomposition {\n constructor(matrix) {\n matrix = WrapperMatrix2D.checkMatrix(matrix);\n\n let lu = matrix.clone();\n let rows = lu.rows;\n let columns = lu.columns;\n let pivotVector = new Float64Array(rows);\n let pivotSign = 1;\n let i, j, k, p, s, t, v;\n let LUcolj, kmax;\n\n for (i = 0; i < rows; i++) {\n pivotVector[i] = i;\n }\n\n LUcolj = new Float64Array(rows);\n\n for (j = 0; j < columns; j++) {\n for (i = 0; i < rows; i++) {\n LUcolj[i] = lu.get(i, j);\n }\n\n for (i = 0; i < rows; i++) {\n kmax = Math.min(i, j);\n s = 0;\n for (k = 0; k < kmax; k++) {\n s += lu.get(i, k) * LUcolj[k];\n }\n LUcolj[i] -= s;\n lu.set(i, j, LUcolj[i]);\n }\n\n p = j;\n for (i = j + 1; i < rows; i++) {\n if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p])) {\n p = i;\n }\n }\n\n if (p !== j) {\n for (k = 0; k < columns; k++) {\n t = lu.get(p, k);\n lu.set(p, k, lu.get(j, k));\n lu.set(j, k, t);\n }\n\n v = pivotVector[p];\n pivotVector[p] = pivotVector[j];\n pivotVector[j] = v;\n\n pivotSign = -pivotSign;\n }\n\n if (j < rows && lu.get(j, j) !== 0) {\n for (i = j + 1; i < rows; i++) {\n lu.set(i, j, lu.get(i, j) / lu.get(j, j));\n }\n }\n }\n\n this.LU = lu;\n this.pivotVector = pivotVector;\n this.pivotSign = pivotSign;\n }\n\n isSingular() {\n let data = this.LU;\n let col = data.columns;\n for (let j = 0; j < col; j++) {\n if (data.get(j, j) === 0) {\n return true;\n }\n }\n return false;\n }\n\n solve(value) {\n value = Matrix.checkMatrix(value);\n\n let lu = this.LU;\n let rows = lu.rows;\n\n if (rows !== value.rows) {\n throw new Error('Invalid matrix dimensions');\n }\n if (this.isSingular()) {\n throw new Error('LU matrix is singular');\n }\n\n let count = value.columns;\n let X = value.subMatrixRow(this.pivotVector, 0, count - 1);\n let columns = lu.columns;\n let i, j, k;\n\n for (k = 0; k < columns; k++) {\n for (i = k + 1; i < columns; i++) {\n for (j = 0; j < count; j++) {\n X.set(i, j, X.get(i, j) - X.get(k, j) * lu.get(i, k));\n }\n }\n }\n for (k = columns - 1; k >= 0; k--) {\n for (j = 0; j < count; j++) {\n X.set(k, j, X.get(k, j) / lu.get(k, k));\n }\n for (i = 0; i < k; i++) {\n for (j = 0; j < count; j++) {\n X.set(i, j, X.get(i, j) - X.get(k, j) * lu.get(i, k));\n }\n }\n }\n return X;\n }\n\n get determinant() {\n let data = this.LU;\n if (!data.isSquare()) {\n throw new Error('Matrix must be square');\n }\n let determinant = this.pivotSign;\n let col = data.columns;\n for (let j = 0; j < col; j++) {\n determinant *= data.get(j, j);\n }\n return determinant;\n }\n\n get lowerTriangularMatrix() {\n let data = this.LU;\n let rows = data.rows;\n let columns = data.columns;\n let X = new Matrix(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n if (i > j) {\n X.set(i, j, data.get(i, j));\n } else if (i === j) {\n X.set(i, j, 1);\n } else {\n X.set(i, j, 0);\n }\n }\n }\n return X;\n }\n\n get upperTriangularMatrix() {\n let data = this.LU;\n let rows = data.rows;\n let columns = data.columns;\n let X = new Matrix(rows, columns);\n for (let i = 0; i < rows; i++) {\n for (let j = 0; j < columns; j++) {\n if (i <= j) {\n X.set(i, j, data.get(i, j));\n } else {\n X.set(i, j, 0);\n }\n }\n }\n return X;\n }\n\n get pivotPermutationVector() {\n return Array.from(this.pivotVector);\n }\n}\n","export function hypotenuse(a, b) {\n let r = 0;\n if (Math.abs(a) > Math.abs(b)) {\n r = b / a;\n return Math.abs(a) * Math.sqrt(1 + r * r);\n }\n if (b !== 0) {\n r = a / b;\n return Math.abs(b) * Math.sqrt(1 + r * r);\n }\n return 0;\n}\n","import Matrix from '../matrix';\nimport WrapperMatrix2D from '../wrap/WrapperMatrix2D';\n\nimport { hypotenuse } from './util';\n\nexport default class QrDecomposition {\n constructor(value) {\n value = WrapperMatrix2D.checkMatrix(value);\n\n let qr = value.clone();\n let m = value.rows;\n let n = value.columns;\n let rdiag = new Float64Array(n);\n let i, j, k, s;\n\n for (k = 0; k < n; k++) {\n let nrm = 0;\n for (i = k; i < m; i++) {\n nrm = hypotenuse(nrm, qr.get(i, k));\n }\n if (nrm !== 0) {\n if (qr.get(k, k) < 0) {\n nrm = -nrm;\n }\n for (i = k; i < m; i++) {\n qr.set(i, k, qr.get(i, k) / nrm);\n }\n qr.set(k, k, qr.get(k, k) + 1);\n for (j = k + 1; j < n; j++) {\n s = 0;\n for (i = k; i < m; i++) {\n s += qr.get(i, k) * qr.get(i, j);\n }\n s = -s / qr.get(k, k);\n for (i = k; i < m; i++) {\n qr.set(i, j, qr.get(i, j) + s * qr.get(i, k));\n }\n }\n }\n rdiag[k] = -nrm;\n }\n\n this.QR = qr;\n this.Rdiag = rdiag;\n }\n\n solve(value) {\n value = Matrix.checkMatrix(value);\n\n let qr = this.QR;\n let m = qr.rows;\n\n if (value.rows !== m) {\n throw new Error('Matrix row dimensions must agree');\n }\n if (!this.isFullRank()) {\n throw new Error('Matrix is rank deficient');\n }\n\n let count = value.columns;\n let X = value.clone();\n let n = qr.columns;\n let i, j, k, s;\n\n for (k = 0; k < n; k++) {\n for (j = 0; j < count; j++) {\n s = 0;\n for (i = k; i < m; i++) {\n s += qr.get(i, k) * X.get(i, j);\n }\n s = -s / qr.get(k, k);\n for (i = k; i < m; i++) {\n X.set(i, j, X.get(i, j) + s * qr.get(i, k));\n }\n }\n }\n for (k = n - 1; k >= 0; k--) {\n for (j = 0; j < count; j++) {\n X.set(k, j, X.get(k, j) / this.Rdiag[k]);\n }\n for (i = 0; i < k; i++) {\n for (j = 0; j < count; j++) {\n X.set(i, j, X.get(i, j) - X.get(k, j) * qr.get(i, k));\n }\n }\n }\n\n return X.subMatrix(0, n - 1, 0, count - 1);\n }\n\n isFullRank() {\n let columns = this.QR.columns;\n for (let i = 0; i < columns; i++) {\n if (this.Rdiag[i] === 0) {\n return false;\n }\n }\n return true;\n }\n\n get upperTriangularMatrix() {\n let qr = this.QR;\n let n = qr.columns;\n let X = new Matrix(n, n);\n let i, j;\n for (i = 0; i < n; i++) {\n for (j = 0; j < n; j++) {\n if (i < j) {\n X.set(i, j, qr.get(i, j));\n } else if (i === j) {\n X.set(i, j, this.Rdiag[i]);\n } else {\n X.set(i, j, 0);\n }\n }\n }\n return X;\n }\n\n get orthogonalMatrix() {\n let qr = this.QR;\n let rows = qr.rows;\n let columns = qr.columns;\n let X = new Matrix(rows, columns);\n let i, j, k, s;\n\n for (k = columns - 1; k >= 0; k--) {\n for (i = 0; i < rows; i++) {\n X.set(i, k, 0);\n }\n X.set(k, k, 1);\n for (j = k; j < columns; j++) {\n if (qr.get(k, k) !== 0) {\n s = 0;\n for (i = k; i < rows; i++) {\n s += qr.get(i, k) * X.get(i, j);\n }\n\n s = -s / qr.get(k, k);\n\n for (i = k; i < rows; i++) {\n X.set(i, j, X.get(i, j) + s * qr.get(i, k));\n }\n }\n }\n }\n return X;\n }\n}\n","import Matrix from '../matrix';\nimport WrapperMatrix2D from '../wrap/WrapperMatrix2D';\n\nimport { hypotenuse } from './util';\n\nexport default class SingularValueDecomposition {\n constructor(value, options = {}) {\n value = WrapperMatrix2D.checkMatrix(value);\n\n if (value.isEmpty()) {\n throw new Error('Matrix must be non-empty');\n }\n\n let m = value.rows;\n let n = value.columns;\n\n const {\n computeLeftSingularVectors = true,\n computeRightSingularVectors = true,\n autoTranspose = false,\n } = options;\n\n let wantu = Boolean(computeLeftSingularVectors);\n let wantv = Boolean(computeRightSingularVectors);\n\n let swapped = false;\n let a;\n if (m < n) {\n if (!autoTranspose) {\n a = value.clone();\n // eslint-disable-next-line no-console\n console.warn(\n 'Computing SVD on a matrix with more columns than rows. Consider enabling autoTranspose',\n );\n } else {\n a = value.transpose();\n m = a.rows;\n n = a.columns;\n swapped = true;\n let aux = wantu;\n wantu = wantv;\n wantv = aux;\n }\n } else {\n a = value.clone();\n }\n\n let nu = Math.min(m, n);\n let ni = Math.min(m + 1, n);\n let s = new Float64Array(ni);\n let U = new Matrix(m, nu);\n let V = new Matrix(n, n);\n\n let e = new Float64Array(n);\n let work = new Float64Array(m);\n\n let si = new Float64Array(ni);\n for (let i = 0; i < ni; i++) si[i] = i;\n\n let nct = Math.min(m - 1, n);\n let nrt = Math.max(0, Math.min(n - 2, m));\n let mrc = Math.max(nct, nrt);\n\n for (let k = 0; k < mrc; k++) {\n if (k < nct) {\n s[k] = 0;\n for (let i = k; i < m; i++) {\n s[k] = hypotenuse(s[k], a.get(i, k));\n }\n if (s[k] !== 0) {\n if (a.get(k, k) < 0) {\n s[k] = -s[k];\n }\n for (let i = k; i < m; i++) {\n a.set(i, k, a.get(i, k) / s[k]);\n }\n a.set(k, k, a.get(k, k) + 1);\n }\n s[k] = -s[k];\n }\n\n for (let j = k + 1; j < n; j++) {\n if (k < nct && s[k] !== 0) {\n let t = 0;\n for (let i = k; i < m; i++) {\n t += a.get(i, k) * a.get(i, j);\n }\n t = -t / a.get(k, k);\n for (let i = k; i < m; i++) {\n a.set(i, j, a.get(i, j) + t * a.get(i, k));\n }\n }\n e[j] = a.get(k, j);\n }\n\n if (wantu && k < nct) {\n for (let i = k; i < m; i++) {\n U.set(i, k, a.get(i, k));\n }\n }\n\n if (k < nrt) {\n e[k] = 0;\n for (let i = k + 1; i < n; i++) {\n e[k] = hypotenuse(e[k], e[i]);\n }\n if (e[k] !== 0) {\n if (e[k + 1] < 0) {\n e[k] = 0 - e[k];\n }\n for (let i = k + 1; i < n; i++) {\n e[i] /= e[k];\n }\n e[k + 1] += 1;\n }\n e[k] = -e[k];\n if (k + 1 < m && e[k] !== 0) {\n for (let i = k + 1; i < m; i++) {\n work[i] = 0;\n }\n for (let i = k + 1; i < m; i++) {\n for (let j = k + 1; j < n; j++) {\n work[i] += e[j] * a.get(i, j);\n }\n }\n for (let j = k + 1; j < n; j++) {\n let t = -e[j] / e[k + 1];\n for (let i = k + 1; i < m; i++) {\n a.set(i, j, a.get(i, j) + t * work[i]);\n }\n }\n }\n if (wantv) {\n for (let i = k + 1; i < n; i++) {\n V.set(i, k, e[i]);\n }\n }\n }\n }\n\n let p = Math.min(n, m + 1);\n if (nct < n) {\n s[nct] = a.get(nct, nct);\n }\n if (m < p) {\n s[p - 1] = 0;\n }\n if (nrt + 1 < p) {\n e[nrt] = a.get(nrt, p - 1);\n }\n e[p - 1] = 0;\n\n if (wantu) {\n for (let j = nct; j < nu; j++) {\n for (let i = 0; i < m; i++) {\n U.set(i, j, 0);\n }\n U.set(j, j, 1);\n }\n for (let k = nct - 1; k >= 0; k--) {\n if (s[k] !== 0) {\n for (let j = k + 1; j < nu; j++) {\n let t = 0;\n for (let i = k; i < m; i++) {\n t += U.get(i, k) * U.get(i, j);\n }\n t = -t / U.get(k, k);\n for (let i = k; i < m; i++) {\n U.set(i, j, U.get(i, j) + t * U.get(i, k));\n }\n }\n for (let i = k; i < m; i++) {\n U.set(i, k, -U.get(i, k));\n }\n U.set(k, k, 1 + U.get(k, k));\n for (let i = 0; i < k - 1; i++) {\n U.set(i, k, 0);\n }\n } else {\n for (let i = 0; i < m; i++) {\n U.set(i, k, 0);\n }\n U.set(k, k, 1);\n }\n }\n }\n\n if (wantv) {\n for (let k = n - 1; k >= 0; k--) {\n if (k < nrt && e[k] !== 0) {\n for (let j = k + 1; j < n; j++) {\n let t = 0;\n for (let i = k + 1; i < n; i++) {\n t += V.get(i, k) * V.get(i, j);\n }\n t = -t / V.get(k + 1, k);\n for (let i = k + 1; i < n; i++) {\n V.set(i, j, V.get(i, j) + t * V.get(i, k));\n }\n }\n }\n for (let i = 0; i < n; i++) {\n V.set(i, k, 0);\n }\n V.set(k, k, 1);\n }\n }\n\n let pp = p - 1;\n let iter = 0;\n let eps = Number.EPSILON;\n while (p > 0) {\n let k, kase;\n for (k = p - 2; k >= -1; k--) {\n if (k === -1) {\n break;\n }\n const alpha =\n Number.MIN_VALUE + eps * Math.abs(s[k] + Math.abs(s[k + 1]));\n if (Math.abs(e[k]) <= alpha || Number.isNaN(e[k])) {\n e[k] = 0;\n break;\n }\n }\n if (k === p - 2) {\n kase = 4;\n } else {\n let ks;\n for (ks = p - 1; ks >= k; ks--) {\n if (ks === k) {\n break;\n }\n let t =\n (ks !== p ? Math.abs(e[ks]) : 0) +\n (ks !== k + 1 ? Math.abs(e[ks - 1]) : 0);\n if (Math.abs(s[ks]) <= eps * t) {\n s[ks] = 0;\n break;\n }\n }\n if (ks === k) {\n kase = 3;\n } else if (ks === p - 1) {\n kase = 1;\n } else {\n kase = 2;\n k = ks;\n }\n }\n\n k++;\n\n switch (kase) {\n case 1: {\n let f = e[p - 2];\n e[p - 2] = 0;\n for (let j = p - 2; j >= k; j--) {\n let t = hypotenuse(s[j], f);\n let cs = s[j] / t;\n let sn = f / t;\n s[j] = t;\n if (j !== k) {\n f = -sn * e[j - 1];\n e[j - 1] = cs * e[j - 1];\n }\n if (wantv) {\n for (let i = 0; i < n; i++) {\n t = cs * V.get(i, j) + sn * V.get(i, p - 1);\n V.set(i, p - 1, -sn * V.get(i, j) + cs * V.get(i, p - 1));\n V.set(i, j, t);\n }\n }\n }\n break;\n }\n case 2: {\n let f = e[k - 1];\n e[k - 1] = 0;\n for (let j = k; j < p; j++) {\n let t = hypotenuse(s[j], f);\n let cs = s[j] / t;\n let sn = f / t;\n s[j] = t;\n f = -sn * e[j];\n e[j] = cs * e[j];\n if (wantu) {\n for (let i = 0; i < m; i++) {\n t = cs * U.get(i, j) + sn * U.get(i, k - 1);\n U.set(i, k - 1, -sn * U.get(i, j) + cs * U.get(i, k - 1));\n U.set(i, j, t);\n }\n }\n }\n break;\n }\n case 3: {\n const scale = Math.max(\n Math.abs(s[p - 1]),\n Math.abs(s[p - 2]),\n Math.abs(e[p - 2]),\n Math.abs(s[k]),\n Math.abs(e[k]),\n );\n const sp = s[p - 1] / scale;\n const spm1 = s[p - 2] / scale;\n const epm1 = e[p - 2] / scale;\n const sk = s[k] / scale;\n const ek = e[k] / scale;\n const b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2;\n const c = sp * epm1 * (sp * epm1);\n let shift = 0;\n if (b !== 0 || c !== 0) {\n if (b < 0) {\n shift = 0 - Math.sqrt(b * b + c);\n } else {\n shift = Math.sqrt(b * b + c);\n }\n shift = c / (b + shift);\n }\n let f = (sk + sp) * (sk - sp) + shift;\n let g = sk * ek;\n for (let j = k; j < p - 1; j++) {\n let t = hypotenuse(f, g);\n if (t === 0) t = Number.MIN_VALUE;\n let cs = f / t;\n let sn = g / t;\n if (j !== k) {\n e[j - 1] = t;\n }\n f = cs * s[j] + sn * e[j];\n e[j] = cs * e[j] - sn * s[j];\n g = sn * s[j + 1];\n s[j + 1] = cs * s[j + 1];\n if (wantv) {\n for (let i = 0; i < n; i++) {\n t = cs * V.get(i, j) + sn * V.get(i, j + 1);\n V.set(i, j + 1, -sn * V.get(i, j) + cs * V.get(i, j + 1));\n V.set(i, j, t);\n }\n }\n t = hypotenuse(f, g);\n if (t === 0) t = Number.MIN_VALUE;\n cs = f / t;\n sn = g / t;\n s[j] = t;\n f = cs * e[j] + sn * s[j + 1];\n s[j + 1] = -sn * e[j] + cs * s[j + 1];\n g = sn * e[j + 1];\n e[j + 1] = cs * e[j + 1];\n if (wantu && j < m - 1) {\n for (let i = 0; i < m; i++) {\n t = cs * U.get(i, j) + sn * U.get(i, j + 1);\n U.set(i, j + 1, -sn * U.get(i, j) + cs * U.get(i, j + 1));\n U.set(i, j, t);\n }\n }\n }\n e[p - 2] = f;\n iter = iter + 1;\n break;\n }\n case 4: {\n if (s[k] <= 0) {\n s[k] = s[k] < 0 ? -s[k] : 0;\n if (wantv) {\n for (let i = 0; i <= pp; i++) {\n V.set(i, k, -V.get(i, k));\n }\n }\n }\n while (k < pp) {\n if (s[k] >= s[k + 1]) {\n break;\n }\n let t = s[k];\n s[k] = s[k + 1];\n s[k + 1] = t;\n if (wantv && k < n - 1) {\n for (let i = 0; i < n; i++) {\n t = V.get(i, k + 1);\n V.set(i, k + 1, V.get(i, k));\n V.set(i, k, t);\n }\n }\n if (wantu && k < m - 1) {\n for (let i = 0; i < m; i++) {\n t = U.get(i, k + 1);\n U.set(i, k + 1, U.get(i, k));\n U.set(i, k, t);\n }\n }\n k++;\n }\n iter = 0;\n p--;\n break;\n }\n // no default\n }\n }\n\n if (swapped) {\n let tmp = V;\n V = U;\n U = tmp;\n }\n\n this.m = m;\n this.n = n;\n this.s = s;\n this.U = U;\n this.V = V;\n }\n\n solve(value) {\n let Y = value;\n let e = this.threshold;\n let scols = this.s.length;\n let Ls = Matrix.zeros(scols, scols);\n\n for (let i = 0; i < scols; i++) {\n if (Math.abs(this.s[i]) <= e) {\n Ls.set(i, i, 0);\n } else {\n Ls.set(i, i, 1 / this.s[i]);\n }\n }\n\n let U = this.U;\n let V = this.rightSingularVectors;\n\n let VL = V.mmul(Ls);\n let vrows = V.rows;\n let urows = U.rows;\n let VLU = Matrix.zeros(vrows, urows);\n\n for (let i = 0; i < vrows; i++) {\n for (let j = 0; j < urows; j++) {\n let sum = 0;\n for (let k = 0; k < scols; k++) {\n sum += VL.get(i, k) * U.get(j, k);\n }\n VLU.set(i, j, sum);\n }\n }\n\n return VLU.mmul(Y);\n }\n\n solveForDiagonal(value) {\n return this.solve(Matrix.diag(value));\n }\n\n inverse() {\n let V = this.V;\n let e = this.threshold;\n let vrows = V.rows;\n let vcols = V.columns;\n let X = new Matrix(vrows, this.s.length);\n\n for (let i = 0; i < vrows; i++) {\n for (let j = 0; j < vcols; j++) {\n if (Math.abs(this.s[j]) > e) {\n X.set(i, j, V.get(i, j) / this.s[j]);\n }\n }\n }\n\n let U = this.U;\n\n let urows = U.rows;\n let ucols = U.columns;\n let Y = new Matrix(vrows, urows);\n\n for (let i = 0; i < vrows; i++) {\n for (let j = 0; j < urows; j++) {\n let sum = 0;\n for (let k = 0; k < ucols; k++) {\n sum += X.get(i, k) * U.get(j, k);\n }\n Y.set(i, j, sum);\n }\n }\n\n return Y;\n }\n\n get condition() {\n return this.s[0] / this.s[Math.min(this.m, this.n) - 1];\n }\n\n get norm2() {\n return this.s[0];\n }\n\n get rank() {\n let tol = Math.max(this.m, this.n) * this.s[0] * Number.EPSILON;\n let r = 0;\n let s = this.s;\n for (let i = 0, ii = s.length; i < ii; i++) {\n if (s[i] > tol) {\n r++;\n }\n }\n return r;\n }\n\n get diagonal() {\n return Array.from(this.s);\n }\n\n get threshold() {\n return (Number.EPSILON / 2) * Math.max(this.m, this.n) * this.s[0];\n }\n\n get leftSingularVectors() {\n return this.U;\n }\n\n get rightSingularVectors() {\n return this.V;\n }\n\n get diagonalMatrix() {\n return Matrix.diag(this.s);\n }\n}\n","import { inverse, Matrix } from 'ml-matrix';\n\n/**\n * Difference of the matrix function over the parameters\n * @ignore\n * @param {{x:Array<number>, y:Array<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {Array<number>} evaluatedData - Array of previous evaluated function values\n * @param {Array<number>} params - Array of previous parameter values\n * @param {number} gradientDifference - Adjustment for decrease the damping parameter\n * @param {function} paramFunction - The parameters and returns a function with the independent variable as a parameter\n * @return {Matrix}\n */\nfunction gradientFunction(\n data,\n evaluatedData,\n params,\n gradientDifference,\n paramFunction,\n) {\n const n = params.length;\n const m = data.x.length;\n\n let ans = new Array(n);\n\n for (let param = 0; param < n; param++) {\n ans[param] = new Array(m);\n let auxParams = params.slice();\n auxParams[param] += gradientDifference;\n let funcParam = paramFunction(auxParams);\n\n for (let point = 0; point < m; point++) {\n ans[param][point] = evaluatedData[point] - funcParam(data.x[point]);\n }\n }\n return new Matrix(ans);\n}\n\n/**\n * Matrix function over the samples\n * @ignore\n * @param {{x:Array<number>, y:Array<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {Array<number>} evaluatedData - Array of previous evaluated function values\n * @return {Matrix}\n */\nfunction matrixFunction(data, evaluatedData) {\n const m = data.x.length;\n\n let ans = new Array(m);\n\n for (let point = 0; point < m; point++) {\n ans[point] = [data.y[point] - evaluatedData[point]];\n }\n\n return new Matrix(ans);\n}\n\n/**\n * Iteration for Levenberg-Marquardt\n * @ignore\n * @param {{x:Array<number>, y:Array<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {Array<number>} params - Array of previous parameter values\n * @param {number} damping - Levenberg-Marquardt parameter\n * @param {number} gradientDifference - Adjustment for decrease the damping parameter\n * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter\n * @return {Array<number>}\n */\nexport default function step(\n data,\n params,\n damping,\n gradientDifference,\n parameterizedFunction,\n) {\n let value = damping * gradientDifference * gradientDifference;\n let identity = Matrix.eye(params.length, params.length, value);\n\n const func = parameterizedFunction(params);\n\n let evaluatedData = new Float64Array(data.x.length);\n for (let i = 0; i < data.x.length; i++) {\n evaluatedData[i] = func(data.x[i]);\n }\n\n let gradientFunc = gradientFunction(\n data,\n evaluatedData,\n params,\n gradientDifference,\n parameterizedFunction,\n );\n let matrixFunc = matrixFunction(data, evaluatedData);\n let inverseMatrix = inverse(\n identity.add(gradientFunc.mmul(gradientFunc.transpose())),\n );\n\n params = new Matrix([params]);\n params = params.sub(\n inverseMatrix\n .mmul(gradientFunc)\n .mmul(matrixFunc)\n .mul(gradientDifference)\n .transpose(),\n );\n\n return params.to1DArray();\n}\n","import LuDecomposition from './dc/lu';\nimport QrDecomposition from './dc/qr';\nimport SingularValueDecomposition from './dc/svd';\nimport Matrix from './matrix';\nimport WrapperMatrix2D from './wrap/WrapperMatrix2D';\n\nexport function inverse(matrix, useSVD = false) {\n matrix = WrapperMatrix2D.checkMatrix(matrix);\n if (useSVD) {\n return new SingularValueDecomposition(matrix).inverse();\n } else {\n return solve(matrix, Matrix.eye(matrix.rows));\n }\n}\n\nexport function solve(leftHandSide, rightHandSide, useSVD = false) {\n leftHandSide = WrapperMatrix2D.checkMatrix(leftHandSide);\n rightHandSide = WrapperMatrix2D.checkMatrix(rightHandSide);\n if (useSVD) {\n return new SingularValueDecomposition(leftHandSide).solve(rightHandSide);\n } else {\n return leftHandSide.isSquare()\n ? new LuDecomposition(leftHandSide).solve(rightHandSide)\n : new QrDecomposition(leftHandSide).solve(rightHandSide);\n }\n}\n","/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\n/**\n * This is a JavaScript reimplementation of UMAP (original license below), from\n * the python implementation found at https://github.com/lmcinnes/umap.\n *\n * @author andycoenen@google.com (Andy Coenen)\n */\n/**\n * @license\n * BSD 3-Clause License\n *\n * Copyright (c) 2017, Leland McInnes\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * * Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n *\n * * Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * * Neither the name of the copyright holder nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport * as heap from './heap';\nimport * as matrix from './matrix';\nimport * as nnDescent from './nn_descent';\nimport * as tree from './tree';\nimport * as utils from './utils';\nimport LM from 'ml-levenberg-marquardt';\nconst SMOOTH_K_TOLERANCE = 1e-5;\nconst MIN_K_DIST_SCALE = 1e-3;\n/**\n * UMAP projection system, based on the python implementation from McInnes, L,\n * Healy, J, UMAP: Uniform Manifold Approximation and Projection for Dimension\n * Reduction (https://github.com/lmcinnes/umap).\n *\n * This implementation differs in a few regards:\n * a) The initialization of the embedding for optimization is not computed using\n * a spectral method, rather it is initialized randomly. This avoids some\n * computationally intensive matrix eigen computations that aren't easily\n * ported to JavaScript.\n * b) A lot of \"extra\" functionality has been omitted from this implementation,\n * most notably a great deal of alternate distance functions.\n *\n * This implementation provides three methods of reducing dimensionality:\n * 1) fit: fit the data synchronously\n * 2) fitAsync: fit the data asynchronously, with a callback function provided\n * that is invoked on each optimization step.\n * 3) initializeFit / step: manually initialize the algorithm then explictly\n * step through each epoch of the SGD optimization\n */\nexport class UMAP {\n get neighbors() {\n return this.nNeighbors;\n }\n constructor(params = {}) {\n this.learningRate = 1.0;\n this.localConnectivity = 1.0;\n this.minDist = 0.1;\n this.nComponents = 2;\n this.nEpochs = 0;\n this.nNeighbors = 15;\n this.negativeSampleRate = 5;\n this.random = Math.random;\n this.repulsionStrength = 1.0;\n this.setOpMixRatio = 1.0;\n this.spread = 1.0;\n this.transformQueueSize = 4.0;\n // Supervised projection params\n this.targetMetric = \"categorical\" /* TargetMetric.categorical */;\n this.targetWeight = 0.5;\n this.targetNNeighbors = this.nNeighbors;\n this.distanceFn = numeric;\n this.isInitialized = false;\n this.rpForest = [];\n // Projected embedding\n this.embedding = [];\n this.optimizationState = new OptimizationState();\n const setParam = (key) => {\n //@ts-ignore\n if (params[key] !== undefined)\n this[key] = params[key];\n };\n setParam('distanceFn');\n setParam('learningRate');\n setParam('localConnectivity');\n setParam('minDist');\n setParam('nComponents');\n setParam('nEpochs');\n setParam('nNeighbors');\n setParam('negativeSampleRate');\n setParam('random');\n setParam('repulsionStrength');\n setParam('setOpMixRatio');\n setParam('spread');\n setParam('transformQueueSize');\n }\n /**\n * Fit the data to a projected embedding space synchronously.\n */\n fit(X) {\n this.initializeFit(X);\n this.optimizeLayout();\n return this.embedding;\n }\n /**\n * Fit the data to a projected embedding space asynchronously, with a callback\n * function invoked on every epoch of optimization.\n */\n async fitAsync(X, callback = () => true) {\n this.initializeFit(X);\n await this.optimizeLayoutAsync(callback);\n return this.embedding;\n }\n /**\n * Initializes parameters needed for supervised projection.\n */\n setSupervisedProjection(Y, params = {}) {\n this.Y = Y;\n this.targetMetric = params.targetMetric || this.targetMetric;\n this.targetWeight = params.targetWeight || this.targetWeight;\n this.targetNNeighbors = params.targetNNeighbors || this.targetNNeighbors;\n }\n /**\n * Initializes umap with precomputed KNN indices and distances.\n */\n setPrecomputedKNN(knnIndices, knnDistances) {\n this.knnIndices = knnIndices;\n this.knnDistances = knnDistances;\n }\n /**\n * Initializes fit by computing KNN and a fuzzy simplicial set, as well as\n * initializing the projected embeddings. Sets the optimization state ahead\n * of optimization steps. Returns the number of epochs to be used for the\n * SGD optimization.\n */\n initializeFit(X) {\n if (X.length <= this.nNeighbors) {\n throw new Error(`Not enough data points (${X.length}) to create nNeighbors: ${this.nNeighbors}. Add more data points or adjust the configuration.`);\n }\n // We don't need to reinitialize if we've already initialized for this data.\n if (this.X === X && this.isInitialized) {\n return this.getNEpochs();\n }\n this.X = X;\n if (!this.knnIndices && !this.knnDistances) {\n const knnResults = this.nearestNeighbors(X);\n this.knnIndices = knnResults.knnIndices;\n this.knnDistances = knnResults.knnDistances;\n }\n this.graph = this.fuzzySimplicialSet(X, this.nNeighbors, this.setOpMixRatio);\n // Set up the search graph for subsequent transformation.\n this.makeSearchFns();\n this.searchGraph = this.makeSearchGraph(X);\n // Check if supervised projection, then adjust the graph.\n this.processGraphForSupervisedProjection();\n const { head, tail, epochsPerSample, } = this.initializeSimplicialSetEmbedding();\n // Set the optimization routine state\n this.optimizationState.head = head;\n this.optimizationState.tail = tail;\n this.optimizationState.epochsPerSample = epochsPerSample;\n // Now, initialize the optimization steps\n this.initializeOptimization();\n this.prepareForOptimizationLoop();\n this.isInitialized = true;\n return this.getNEpochs();\n }\n makeSearchFns() {\n const { initFromTree, initFromRandom } = nnDescent.makeInitializations(this.distanceFn);\n this.initFromTree = initFromTree;\n this.initFromRandom = initFromRandom;\n this.search = nnDescent.makeInitializedNNSearch(this.distanceFn);\n }\n makeSearchGraph(X) {\n const knnIndices = this.knnIndices;\n const knnDistances = this.knnDistances;\n const dims = [X.length, X.length];\n const searchGraph = new matrix.SparseMatrix([], [], [], dims);\n for (let i = 0; i < knnIndices.length; i++) {\n const knn = knnIndices[i];\n const distances = knnDistances[i];\n for (let j = 0; j < knn.length; j++) {\n const neighbor = knn[j];\n const distance = distances[j];\n if (distance > 0) {\n searchGraph.set(i, neighbor, distance);\n }\n }\n }\n const transpose = matrix.transpose(searchGraph);\n return matrix.maximum(searchGraph, transpose);\n }\n /**\n * Transforms data to the existing embedding space.\n */\n transform(toTransform) {\n // Use the previous rawData\n const rawData = this.X;\n if (rawData === undefined || rawData.length === 0) {\n throw new Error('No data has been fit.');\n }\n let nNeighbors = Math.floor(this.nNeighbors * this.transformQueueSize);\n nNeighbors = Math.min(rawData.length, nNeighbors);\n const init = nnDescent.initializeSearch(this.rpForest, rawData, toTransform, nNeighbors, this.initFromRandom, this.initFromTree, this.random);\n const result = this.search(rawData, this.searchGraph, init, toTransform);\n let { indices, weights: distances } = heap.deheapSort(result);\n indices = indices.map(x => x.slice(0, this.nNeighbors));\n distances = distances.map(x => x.slice(0, this.nNeighbors));\n const adjustedLocalConnectivity = Math.max(0, this.localConnectivity - 1);\n const { sigmas, rhos } = this.smoothKNNDistance(distances, this.nNeighbors, adjustedLocalConnectivity);\n const { rows, cols, vals } = this.computeMembershipStrengths(indices, distances, sigmas, rhos);\n const size = [toTransform.length, rawData.length];\n let graph = new matrix.SparseMatrix(rows, cols, vals, size);\n // This was a very specially constructed graph with constant degree.\n // That lets us do fancy unpacking by reshaping the csr matrix indices\n // and data. Doing so relies on the constant degree assumption!\n const normed = matrix.normalize(graph, \"l1\" /* matrix.NormType.l1 */);\n const csrMatrix = matrix.getCSR(normed);\n const nPoints = toTransform.length;\n const eIndices = utils.reshape2d(csrMatrix.indices, nPoints, this.nNeighbors);\n const eWeights = utils.reshape2d(csrMatrix.values, nPoints, this.nNeighbors);\n const embedding = initTransform(eIndices, eWeights, this.embedding);\n const nEpochs = this.nEpochs\n ? this.nEpochs / 3\n : graph.nRows <= 10000\n ? 100\n : 30;\n const graphMax = graph\n .getValues()\n .reduce((max, val) => (val > max ? val : max), 0);\n graph = graph.map(value => (value < graphMax / nEpochs ? 0 : value));\n graph = matrix.eliminateZeros(graph);\n const epochsPerSample = this.makeEpochsPerSample(graph.getValues(), nEpochs);\n const head = graph.getRows();\n const tail = graph.getCols();\n // Initialize optimization slightly differently than the fit method.\n this.assignOptimizationStateParameters({\n headEmbedding: embedding,\n tailEmbedding: this.embedding,\n head,\n tail,\n currentEpoch: 0,\n nEpochs,\n nVertices: graph.getDims()[1],\n epochsPerSample,\n });\n this.prepareForOptimizationLoop();\n return this.optimizeLayout();\n }\n /**\n * Checks if we're using supervised projection, then process the graph\n * accordingly.\n */\n processGraphForSupervisedProjection() {\n const { Y, X } = this;\n if (Y) {\n if (Y.length !== X.length) {\n throw new Error('Length of X and y must be equal');\n }\n if (this.targetMetric === \"categorical\" /* TargetMetric.categorical */) {\n const lt = this.targetWeight < 1.0;\n const farDist = lt ? 2.5 * (1.0 / (1.0 - this.targetWeight)) : 1.0e12;\n this.graph = this.categoricalSimplicialSetIntersection(this.graph, Y, farDist);\n }\n // TODO (andycoenen@): add non-categorical supervised embeddings.\n }\n }\n /**\n * Manually step through the optimization process one epoch at a time.\n */\n step() {\n const { currentEpoch } = this.optimizationState;\n if (currentEpoch < this.getNEpochs()) {\n this.optimizeLayoutStep(currentEpoch);\n }\n return this.optimizationState.currentEpoch;\n }\n /**\n * Returns the computed projected embedding.\n */\n getEmbedding() {\n return this.embedding;\n }\n /**\n * Compute the ``nNeighbors`` nearest points for each data point in ``X``\n * This may be exact, but more likely is approximated via nearest neighbor\n * descent.\n */\n nearestNeighbors(X) {\n const { distanceFn, nNeighbors } = this;\n const log2 = (n) => Math.log(n) / Math.log(2);\n const metricNNDescent = nnDescent.makeNNDescent(distanceFn, this.random);\n // Handle python3 rounding down from 0.5 discrpancy\n const round = (n) => {\n return n === 0.5 ? 0 : Math.round(n);\n };\n const nTrees = 5 + Math.floor(round(X.length ** 0.5 / 20.0));\n const nIters = Math.max(5, Math.floor(Math.round(log2(X.length))));\n this.rpForest = tree.makeForest(X, nNeighbors, nTrees, this.random);\n const leafArray = tree.makeLeafArray(this.rpForest);\n const { indices, weights } = metricNNDescent(X, leafArray, nNeighbors, nIters);\n return { knnIndices: indices, knnDistances: weights };\n }\n /**\n * Given a set of data X, a neighborhood size, and a measure of distance\n * compute the fuzzy simplicial set (here represented as a fuzzy graph in\n * the form of a sparse matrix) associated to the data. This is done by\n * locally approximating geodesic distance at each point, creating a fuzzy\n * simplicial set for each such point, and then combining all the local\n * fuzzy simplicial sets into a global one via a fuzzy union.\n */\n fuzzySimplicialSet(X, nNeighbors, setOpMixRatio = 1.0) {\n const { knnIndices = [], knnDistances = [], localConnectivity } = this;\n const { sigmas, rhos } = this.smoothKNNDistance(knnDistances, nNeighbors, localConnectivity);\n const { rows, cols, vals } = this.computeMembershipStrengths(knnIndices, knnDistances, sigmas, rhos);\n const size = [X.length, X.length];\n const sparseMatrix = new matrix.SparseMatrix(rows, cols, vals, size);\n const transpose = matrix.transpose(sparseMatrix);\n const prodMatrix = matrix.pairwiseMultiply(sparseMatrix, transpose);\n const a = matrix.subtract(matrix.add(sparseMatrix, transpose), prodMatrix);\n const b = matrix.multiplyScalar(a, setOpMixRatio);\n const c = matrix.multiplyScalar(prodMatrix, 1.0 - setOpMixRatio);\n const result = matrix.add(b, c);\n return result;\n }\n /**\n * Combine a fuzzy simplicial set with another fuzzy simplicial set\n * generated from categorical data using categorical distances. The target\n * data is assumed to be categorical label data (a vector of labels),\n * and this will update the fuzzy simplicial set to respect that label data.\n */\n categoricalSimplicialSetIntersection(simplicialSet, target, farDist, unknownDist = 1.0) {\n let intersection = fastIntersection(simplicialSet, target, unknownDist, farDist);\n intersection = matrix.eliminateZeros(intersection);\n return resetLocalConnectivity(intersection);\n }\n /**\n * Compute a continuous version of the distance to the kth nearest\n * neighbor. That is, this is similar to knn-distance but allows continuous\n * k values rather than requiring an integral k. In esscence we are simply\n * computing the distance such that the cardinality of fuzzy set we generate\n * is k.\n */\n smoothKNNDistance(distances, k, localConnectivity = 1.0, nIter = 64, bandwidth = 1.0) {\n const target = (Math.log(k) / Math.log(2)) * bandwidth;\n const rho = utils.zeros(distances.length);\n const result = utils.zeros(distances.length);\n for (let i = 0; i < distances.length; i++) {\n let lo = 0.0;\n let hi = Infinity;\n let mid = 1.0;\n // TODO: This is very inefficient, but will do for now. FIXME\n const ithDistances = distances[i];\n const nonZeroDists = ithDistances.filter(d => d > 0.0);\n if (nonZeroDists.length >= localConnectivity) {\n let index = Math.floor(localConnectivity);\n let interpolation = localConnectivity - index;\n if (index > 0) {\n rho[i] = nonZeroDists[index - 1];\n if (interpolation > SMOOTH_K_TOLERANCE) {\n rho[i] +=\n interpolation * (nonZeroDists[index] - nonZeroDists[index - 1]);\n }\n }\n else {\n rho[i] = interpolation * nonZeroDists[0];\n }\n }\n else if (nonZeroDists.length > 0) {\n rho[i] = utils.max(nonZeroDists);\n }\n for (let n = 0; n < nIter; n++) {\n let psum = 0.0;\n for (let j = 1; j < distances[i].length; j++) {\n const d = distances[i][j] - rho[i];\n if (d > 0) {\n psum += Math.exp(-(d / mid));\n }\n else {\n psum += 1.0;\n }\n }\n if (Math.abs(psum - target) < SMOOTH_K_TOLERANCE) {\n break;\n }\n if (psum > target) {\n hi = mid;\n mid = (lo + hi) / 2.0;\n }\n else {\n lo = mid;\n if (hi === Infinity) {\n mid *= 2;\n }\n else {\n mid = (lo + hi) / 2.0;\n }\n }\n }\n result[i] = mid;\n // TODO: This is very inefficient, but will do for now. FIXME\n if (rho[i] > 0.0) {\n const meanIthDistances = utils.mean(ithDistances);\n if (result[i] < MIN_K_DIST_SCALE * meanIthDistances) {\n result[i] = MIN_K_DIST_SCALE * meanIthDistances;\n }\n }\n else {\n const meanDistances = utils.mean(distances.map(utils.mean));\n if (result[i] < MIN_K_DIST_SCALE * meanDistances) {\n result[i] = MIN_K_DIST_SCALE * meanDistances;\n }\n }\n }\n return { sigmas: result, rhos: rho };\n }\n /**\n * Construct the membership strength data for the 1-skeleton of each local\n * fuzzy simplicial set -- this is formed as a sparse matrix where each row is\n * a local fuzzy simplicial set, with a membership strength for the\n * 1-simplex to each other data point.\n */\n computeMembershipStrengths(knnIndices, knnDistances, sigmas, rhos) {\n const nSamples = knnIndices.length;\n const nNeighbors = knnIndices[0].length;\n const rows = utils.zeros(nSamples * nNeighbors);\n const cols = utils.zeros(nSamples * nNeighbors);\n const vals = utils.zeros(nSamples * nNeighbors);\n for (let i = 0; i < nSamples; i++) {\n for (let j = 0; j < nNeighbors; j++) {\n let val = 0;\n if (knnIndices[i][j] === -1) {\n continue; // We didn't get the full knn for i\n }\n if (knnIndices[i][j] === i) {\n val = 0.0;\n }\n else if (knnDistances[i][j] - rhos[i] <= 0.0) {\n val = 1.0;\n }\n else {\n val = Math.exp(-((knnDistances[i][j] - rhos[i]) / sigmas[i]));\n }\n rows[i * nNeighbors + j] = i;\n cols[i * nNeighbors + j] = knnIndices[i][j];\n vals[i * nNeighbors + j] = val;\n }\n }\n return { rows, cols, vals };\n }\n /**\n * Initialize a fuzzy simplicial set embedding, using a specified\n * initialisation method and then minimizing the fuzzy set cross entropy\n * between the 1-skeletons of the high and low dimensional fuzzy simplicial\n * sets.\n */\n initializeSimplicialSetEmbedding() {\n const nEpochs = this.getNEpochs();\n const { nComponents } = this;\n const graphValues = this.graph.getValues();\n let graphMax = 0;\n for (let i = 0; i < graphValues.length; i++) {\n const value = graphValues[i];\n if (graphMax < graphValues[i]) {\n graphMax = value;\n }\n }\n const graph = this.graph.map(value => {\n if (value < graphMax / nEpochs) {\n return 0;\n }\n else {\n return value;\n }\n });\n // We're not computing the spectral initialization in this implementation\n // until we determine a better eigenvalue/eigenvector computation\n // approach\n this.embedding = utils.zeros(graph.nRows).map(() => {\n return utils.zeros(nComponents).map(() => {\n return utils.tauRand(this.random) * 20 + -10; // Random from -10 to 10\n });\n });\n // Get graph data in ordered way...\n const weights = [];\n const head = [];\n const tail = [];\n const rowColValues = graph.getAll();\n for (let i = 0; i < rowColValues.length; i++) {\n const entry = rowColValues[i];\n if (entry.value) {\n weights.push(entry.value);\n tail.push(entry.row);\n head.push(entry.col);\n }\n }\n const epochsPerSample = this.makeEpochsPerSample(weights, nEpochs);\n return { head, tail, epochsPerSample };\n }\n /**\n * Given a set of weights and number of epochs generate the number of\n * epochs per sample for each weight.\n */\n makeEpochsPerSample(weights, nEpochs) {\n const result = utils.filled(weights.length, -1.0);\n const max = utils.max(weights);\n const nSamples = weights.map(w => (w / max) * nEpochs);\n nSamples.forEach((n, i) => {\n if (n > 0)\n result[i] = nEpochs / nSamples[i];\n });\n return result;\n }\n /**\n * Assigns optimization state parameters from a partial optimization state.\n */\n assignOptimizationStateParameters(state) {\n Object.assign(this.optimizationState, state);\n }\n /**\n * Sets a few optimization state parameters that are necessary before entering\n * the optimization step loop.\n */\n prepareForOptimizationLoop() {\n // Hyperparameters\n const { repulsionStrength, learningRate, negativeSampleRate } = this;\n const { epochsPerSample, headEmbedding, tailEmbedding, } = this.optimizationState;\n const dim = headEmbedding[0].length;\n const moveOther = headEmbedding.length === tailEmbedding.length;\n const epochsPerNegativeSample = epochsPerSample.map(e => e / negativeSampleRate);\n const epochOfNextNegativeSample = [...epochsPerNegativeSample];\n const epochOfNextSample = [...epochsPerSample];\n this.assignOptimizationStateParameters({\n epochOfNextSample,\n epochOfNextNegativeSample,\n epochsPerNegativeSample,\n moveOther,\n initialAlpha: learningRate,\n alpha: learningRate,\n gamma: repulsionStrength,\n dim,\n });\n }\n /**\n * Initializes optimization state for stepwise optimization.\n */\n initializeOptimization() {\n // Algorithm state\n const headEmbedding = this.embedding;\n const tailEmbedding = this.embedding;\n // Initialized in initializeSimplicialSetEmbedding()\n const { head, tail, epochsPerSample } = this.optimizationState;\n const nEpochs = this.getNEpochs();\n const nVertices = this.graph.nCols;\n const { a, b } = findABParams(this.spread, this.minDist);\n this.assignOptimizationStateParameters({\n headEmbedding,\n tailEmbedding,\n head,\n tail,\n epochsPerSample,\n a,\n b,\n nEpochs,\n nVertices,\n });\n }\n /**\n * Improve an embedding using stochastic gradient descent to minimize the\n * fuzzy set cross entropy between the 1-skeletons of the high dimensional\n * and low dimensional fuzzy simplicial sets. In practice this is done by\n * sampling edges based on their membership strength (with the (1-p) terms\n * coming from negative sampling similar to word2vec).\n */\n optimizeLayoutStep(n) {\n const { optimizationState } = this;\n const { head, tail, headEmbedding, tailEmbedding, epochsPerSample, epochOfNextSample, epochOfNextNegativeSample, epochsPerNegativeSample, moveOther, initialAlpha, alpha, gamma, a, b, dim, nEpochs, nVertices, } = optimizationState;\n const clipValue = 4.0;\n for (let i = 0; i < epochsPerSample.length; i++) {\n if (epochOfNextSample[i] > n) {\n continue;\n }\n const j = head[i];\n const k = tail[i];\n const current = headEmbedding[j];\n const other = tailEmbedding[k];\n const distSquared = rDist(current, other);\n let gradCoeff = 0;\n if (distSquared > 0) {\n gradCoeff = -2.0 * a * b * Math.pow(distSquared, b - 1.0);\n gradCoeff /= a * Math.pow(distSquared, b) + 1.0;\n }\n for (let d = 0; d < dim; d++) {\n const gradD = clip(gradCoeff * (current[d] - other[d]), clipValue);\n current[d] += gradD * alpha;\n if (moveOther) {\n other[d] += -gradD * alpha;\n }\n }\n epochOfNextSample[i] += epochsPerSample[i];\n const nNegSamples = Math.floor((n - epochOfNextNegativeSample[i]) / epochsPerNegativeSample[i]);\n for (let p = 0; p < nNegSamples; p++) {\n const k = utils.tauRandInt(nVertices, this.random);\n const other = tailEmbedding[k];\n const distSquared = rDist(current, other);\n let gradCoeff = 0.0;\n if (distSquared > 0.0) {\n gradCoeff = 2.0 * gamma * b;\n gradCoeff /=\n (0.001 + distSquared) * (a * Math.pow(distSquared, b) + 1);\n }\n else if (j === k) {\n continue;\n }\n for (let d = 0; d < dim; d++) {\n let gradD = 4.0;\n if (gradCoeff > 0.0) {\n gradD = clip(gradCoeff * (current[d] - other[d]), clipValue);\n }\n current[d] += gradD * alpha;\n }\n }\n epochOfNextNegativeSample[i] += nNegSamples * epochsPerNegativeSample[i];\n }\n optimizationState.alpha = initialAlpha * (1.0 - n / nEpochs);\n optimizationState.currentEpoch += 1;\n return headEmbedding;\n }\n /**\n * Improve an embedding using stochastic gradient descent to minimize the\n * fuzzy set cross entropy between the 1-skeletons of the high dimensional\n * and low dimensional fuzzy simplicial sets. In practice this is done by\n * sampling edges based on their membership strength (with the (1-p) terms\n * coming from negative sampling similar to word2vec).\n */\n optimizeLayoutAsync(epochCallback = () => true) {\n return new Promise((resolve, reject) => {\n const step = async () => {\n try {\n const { nEpochs, currentEpoch } = this.optimizationState;\n this.embedding = this.optimizeLayoutStep(currentEpoch);\n const epochCompleted = this.optimizationState.currentEpoch;\n const shouldStop = epochCallback(epochCompleted) === false;\n const isFinished = epochCompleted === nEpochs;\n if (!shouldStop && !isFinished) {\n setTimeout(() => step(), 0);\n }\n else {\n return resolve(isFinished);\n }\n }\n catch (err) {\n reject(err);\n }\n };\n setTimeout(() => step(), 0);\n });\n }\n /**\n * Improve an embedding using stochastic gradient descent to minimize the\n * fuzzy set cross entropy between the 1-skeletons of the high dimensional\n * and low dimensional fuzzy simplicial sets. In practice this is done by\n * sampling edges based on their membership strength (with the (1-p) terms\n * coming from negative sampling similar to word2vec).\n */\n optimizeLayout(epochCallback = () => true) {\n let isFinished = false;\n let embedding = [];\n while (!isFinished) {\n const { nEpochs, currentEpoch } = this.optimizationState;\n embedding = this.optimizeLayoutStep(currentEpoch);\n const epochCompleted = this.optimizationState.currentEpoch;\n const shouldStop = epochCallback(epochCompleted) === false;\n isFinished = epochCompleted === nEpochs || shouldStop;\n }\n return embedding;\n }\n /**\n * Gets the number of epochs for optimizing the projection.\n * NOTE: This heuristic differs from the python version\n */\n getNEpochs() {\n const graph = this.graph;\n if (this.nEpochs > 0) {\n return this.nEpochs;\n }\n if (!graph) {\n return 200;\n }\n const length = graph.nRows;\n if (length <= 2500) {\n return 500;\n }\n else if (length <= 5000) {\n return 400;\n }\n else if (length <= 7500) {\n return 300;\n }\n else {\n return 200;\n }\n }\n}\nexport function euclidean(x, y) {\n let result = 0;\n for (let i = 0; i < x.length; i++) {\n result += (x[i] - y[i]) ** 2;\n }\n return Math.sqrt(result);\n}\nexport function numeric(x, y) {\n const result = Math.abs(x - y);\n return result;\n}\nexport function cosine(x, y) {\n let result = 0.0;\n let normX = 0.0;\n let normY = 0.0;\n for (let i = 0; i < x.length; i++) {\n result += x[i] * y[i];\n normX += x[i] ** 2;\n normY += y[i] ** 2;\n }\n if (normX === 0 && normY === 0) {\n return 0;\n }\n else if (normX === 0 || normY === 0) {\n return 1.0;\n }\n else {\n return 1.0 - result / Math.sqrt(normX * normY);\n }\n}\n/**\n * An interface representing the optimization state tracked between steps of\n * the SGD optimization\n */\nclass OptimizationState {\n constructor() {\n this.currentEpoch = 0;\n // Data tracked during optimization steps.\n this.headEmbedding = [];\n this.tailEmbedding = [];\n this.head = [];\n this.tail = [];\n this.epochsPerSample = [];\n this.epochOfNextSample = [];\n this.epochOfNextNegativeSample = [];\n this.epochsPerNegativeSample = [];\n this.moveOther = true;\n this.initialAlpha = 1.0;\n this.alpha = 1.0;\n this.gamma = 1.0;\n this.a = 1.5769434603113077;\n this.b = 0.8950608779109733;\n this.dim = 2;\n this.nEpochs = 500;\n this.nVertices = 0;\n }\n}\n/**\n * Standard clamping of a value into a fixed range\n */\nfunction clip(x, clipValue) {\n if (x > clipValue)\n return clipValue;\n else if (x < -clipValue)\n return -clipValue;\n else\n return x;\n}\n/**\n * Reduced Euclidean distance.\n */\nfunction rDist(x, y) {\n let result = 0.0;\n for (let i = 0; i < x.length; i++) {\n result += Math.pow(x[i] - y[i], 2);\n }\n return result;\n}\n/**\n * Fit a, b params for the differentiable curve used in lower\n * dimensional fuzzy simplicial complex construction. We want the\n * smooth curve (from a pre-defined family with simple gradient) that\n * best matches an offset exponential decay.\n */\nexport function findABParams(spread, minDist) {\n const curve = ([a, b]) => (x) => {\n return 1.0 / (1.0 + a * x ** (2 * b));\n };\n const xv = utils\n .linear(0, spread * 3, 300)\n .map(val => (val < minDist ? 1.0 : val));\n const yv = utils.zeros(xv.length).map((val, index) => {\n const gte = xv[index] >= minDist;\n return gte ? Math.exp(-(xv[index] - minDist) / spread) : val;\n });\n const initialValues = [0.5, 0.5];\n const data = { x: xv, y: yv };\n // Default options for the algorithm (from github example)\n const options = {\n damping: 1.5,\n initialValues,\n gradientDifference: 10e-2,\n maxIterations: 100,\n errorTolerance: 10e-3,\n };\n const { parameterValues } = LM(data, curve, options);\n const [a, b] = parameterValues;\n return { a, b };\n}\n/**\n * Under the assumption of categorical distance for the intersecting\n * simplicial set perform a fast intersection.\n */\nexport function fastIntersection(graph, target, unknownDist = 1.0, farDist = 5.0) {\n return graph.map((value, row, col) => {\n if (target[row] === -1 || target[col] === -1) {\n return value * Math.exp(-unknownDist);\n }\n else if (target[row] !== target[col]) {\n return value * Math.exp(-farDist);\n }\n else {\n return value;\n }\n });\n}\n/**\n * Reset the local connectivity requirement -- each data sample should\n * have complete confidence in at least one 1-simplex in the simplicial set.\n * We can enforce this by locally rescaling confidences, and then remerging the\n * different local simplicial sets together.\n */\nexport function resetLocalConnectivity(simplicialSet) {\n simplicialSet = matrix.normalize(simplicialSet, \"max\" /* matrix.NormType.max */);\n const transpose = matrix.transpose(simplicialSet);\n const prodMatrix = matrix.pairwiseMultiply(transpose, simplicialSet);\n simplicialSet = matrix.add(simplicialSet, matrix.subtract(transpose, prodMatrix));\n return matrix.eliminateZeros(simplicialSet);\n}\n/**\n * Given indices and weights and an original embeddings\n * initialize the positions of new points relative to the\n * indices and weights (of their neighbors in the source data).\n */\nexport function initTransform(indices, weights, embedding) {\n const result = utils\n .zeros(indices.length)\n .map(z => utils.zeros(embedding[0].length));\n for (let i = 0; i < indices.length; i++) {\n for (let j = 0; j < indices[0].length; j++) {\n for (let d = 0; d < embedding[0].length; d++) {\n const a = indices[i][j];\n result[i][d] += weights[i][j] * embedding[a][d];\n }\n }\n }\n return result;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW1hcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInVtYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBRUg7Ozs7O0dBS0c7QUFFSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCRztBQUVILE9BQU8sS0FBSyxJQUFJLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxNQUFNLE1BQU0sVUFBVSxDQUFDO0FBQ25DLE9BQU8sS0FBSyxTQUFTLE1BQU0sY0FBYyxDQUFDO0FBQzFDLE9BQU8sS0FBSyxJQUFJLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBYXhDLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDO0FBQ2hDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO0FBbUg5Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sT0FBTyxJQUFJO0lBMkNmLElBQUksU0FBUztRQUNYLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUN6QixDQUFDO0lBQ0QsWUFBWSxTQUF5QixFQUFFO1FBN0MvQixpQkFBWSxHQUFHLEdBQUcsQ0FBQztRQUNuQixzQkFBaUIsR0FBRyxHQUFHLENBQUM7UUFDeEIsWUFBTyxHQUFHLEdBQUcsQ0FBQztRQUNkLGdCQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCLFlBQU8sR0FBRyxDQUFDLENBQUM7UUFDWixlQUFVLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLHVCQUFrQixHQUFHLENBQUMsQ0FBQztRQUN2QixXQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUNyQixzQkFBaUIsR0FBRyxHQUFHLENBQUM7UUFDeEIsa0JBQWEsR0FBRyxHQUFHLENBQUM7UUFDcEIsV0FBTSxHQUFHLEdBQUcsQ0FBQztRQUNiLHVCQUFrQixHQUFH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QUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDNUMsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN4QixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNqRDtTQUNGO0tBQ0Y7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICpcbiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuLyoqXG4gKiBUaGlzIGlzIGEgSmF2YVNjcmlwdCByZWltcGxlbWVudGF0aW9uIG9mIFVNQVAgKG9yaWdpbmFsIGxpY2Vuc2UgYmVsb3cpLCBmcm9tXG4gKiB0aGUgcHl0aG9uIGltcGxlbWVudGF0aW9uIGZvdW5kIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9sbWNpbm5lcy91bWFwLlxuICpcbiAqIEBhdXRob3IgYW5keWNvZW5lbkBnb29nbGUuY29tIChBbmR5IENvZW5lbilcbiAqL1xuXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBCU0QgMy1DbGF1c2UgTGljZW5zZVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxNywgTGVsYW5kIE1jSW5uZXNcbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuICogICBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxuICogICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAqXG4gKiAqIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGNvcHlyaWdodCBob2xkZXIgbm9yIHRoZSBuYW1lcyBvZiBpdHNcbiAqICAgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb21cbiAqICAgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbiAqXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFXG4gKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTFxuICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1JcbiAqIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSXG4gKiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLFxuICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0VcbiAqIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKi9cblxuaW1wb3J0ICogYXMgaGVhcCBmcm9tICcuL2hlYXAnO1xuaW1wb3J0ICogYXMgbWF0cml4IGZyb20gJy4vbWF0cml4JztcbmltcG9ydCAqIGFzIG5uRGVzY2VudCBmcm9tICcuL25uX2Rlc2NlbnQnO1xuaW1wb3J0ICogYXMgdHJlZSBmcm9tICcuL3RyZWUnO1xuaW1wb3J0ICogYXMgdXRpbHMgZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgTE0gZnJvbSAnbWwtbGV2ZW5iZXJnLW1hcnF1YXJkdCc7XG5cbmV4cG9ydCB0eXBlIERpc3RhbmNlRm4gPSAoeDogbnVtYmVyLCB5OiBudW1iZXIpID0+IG51bWJlcjtcbmV4cG9ydCB0eXBlIFJhbmRvbUZuID0gKCkgPT4gbnVtYmVyO1xuZXhwb3J0IHR5cGUgRXBvY2hDYWxsYmFjayA9IChlcG9jaDogbnVtYmVyKSA9PiBib29sZWFuIHwgdm9pZDtcbmV4cG9ydCB0eXBlIFZlY3RvciA9IG51bWJlcltdO1xuZXhwb3J0IHR5cGUgVmVjdG9ycyA9IFZlY3RvcltdO1xuZXhwb3J0IGNvbnN0IGVudW0gVGFyZ2V0TWV0cmljIHtcbiAgY2F0ZWdvcmljYWwgPSAnY2F0ZWdvcmljYWwnLFxuICBsMSA9ICdsMScsXG4gIGwyID0gJ2wyJyxcbn1cblxuY29uc3QgU01PT1RIX0tfVE9MRVJBTkNFID0gMWUtNTtcbmNvbnN0IE1JTl9LX0RJU1RfU0NBTEUgPSAxZS0zO1xuXG5leHBvcnQgaW50ZXJmYWNlIFVNQVBQYXJhbWV0ZXJzIHtcbiAgLyoqXG4gICAqIFRoZSBkaXN0YW5jZSBmdW5jdGlvbiB3aXRoIHdoaWNoIHRvIGFzc2VzcyBuZWFyZXN0IG5laWdoYm9ycywgZGVmYXVsdHNcbiAgICogdG8gZXVjbGlkZWFuIGRpc3RhbmNlLlxuICAgKi9cbiAgZGlzdGFuY2VGbj86IERpc3RhbmNlRm47XG4gIC8qKlxuICAgKiBUaGUgaW5pdGlhbCBsZWFybmluZyByYXRlIGZvciB0aGUgZW1iZWRkaW5nIG9wdGltaXphdGlvbi5cbiAgICovXG4gIGxlYXJuaW5nUmF0ZT86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBsb2NhbCBjb25uZWN0aXZpdHkgcmVxdWlyZWQgLS0gaS5lLiB0aGUgbnVtYmVyIG9mIG5lYXJlc3RcbiAgICogbmVpZ2hib3JzIHRoYXQgc2hvdWxkIGJlIGFzc3VtZWQgdG8gYmUgY29ubmVjdGVkIGF0IGEgbG9jYWwgbGV2ZWwuXG4gICAqIFRoZSBoaWdoZXIgdGhpcyB2YWx1ZSB0aGUgbW9yZSBjb25uZWN0ZWQgdGhlIG1hbmlmb2xkIGJlY29tZXNcbiAgICogbG9jYWxseS4gSW4gcHJhY3RpY2UgdGhpcyBzaG91bGQgYmUgbm90IG1vcmUgdGhhbiB0aGUgbG9jYWwgaW50cmluc2ljXG4gICAqIGRpbWVuc2lvbiBvZiB0aGUgbWFuaWZvbGQuXG4gICAqL1xuICBsb2NhbENvbm5lY3Rpdml0eT86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBlZmZlY3RpdmUgbWluaW11bSBkaXN0YW5jZSBiZXR3ZWVuIGVtYmVkZGVkIHBvaW50cy4gU21hbGxlciB2YWx1ZXNcbiAgICogd2lsbCByZXN1bHQgaW4gYSBtb3JlIGNsdXN0ZXJlZC9jbHVtcGVkIGVtYmVkZGluZyB3aGVyZSBuZWFyYnkgcG9pbnRzXG4gICAqIG9uIHRoZSBtYW5pZm9sZCBhcmUgZHJhd24gY2xvc2VyIHRvZ2V0aGVyLCB3aGlsZSBsYXJnZXIgdmFsdWVzIHdpbGxcbiAgICogcmVzdWx0IG9uIGEgbW9yZSBldmVuIGRpc3BlcnNhbCBvZiBwb2ludHMuIFRoZSB2YWx1ZSBzaG91bGQgYmUgc2V0XG4gICAqIHJlbGF0aXZlIHRvIHRoZSBgYHNwcmVhZGBgIHZhbHVlLCB3aGljaCBkZXRlcm1pbmVzIHRoZSBzY2FsZSBhdCB3aGljaFxuICAgKiBlbWJlZGRlZCBwb2ludHMgd2lsbCBiZSBzcHJlYWQgb3V0LlxuICAgKi9cbiAgbWluRGlzdD86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBkaW1lbnNpb24gb2YgdGhlIHNwYWNlIHRvIGVtYmVkIGludG8uIFRoaXMgZGVmYXVsdHMgdG8gMiB0b1xuICAgKiBwcm92aWRlIGVhc3kgdmlzdWFsaXphdGlvbiwgYnV0IGNhbiByZWFzb25hYmx5IGJlIHNldCB0byBhbnlcbiAgICogaW50ZWdlciB2YWx1ZSBpbiB0aGUgcmFuZ2UgMiB0byAxMDAuXG4gICAqL1xuICBuQ29tcG9uZW50cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgdHJhaW5pbmcgZXBvY2hzIHRvIGJlIHVzZWQgaW4gb3B0aW1pemluZyB0aGVcbiAgICogbG93IGRpbWVuc2lvbmFsIGVtYmVkZGluZy4gTGFyZ2VyIHZhbHVlcyByZXN1bHQgaW4gbW9yZSBhY2N1cmF0ZVxuICAgKiBlbWJlZGRpbmdzLiBJZiBOb25lIGlzIHNwZWNpZmllZCBhIHZhbHVlIHdpbGwgYmUgc2VsZWN0ZWQgYmFzZWQgb25cbiAgICogdGhlIHNpemUgb2YgdGhlIGlucHV0IGRhdGFzZXQgKDIwMCBmb3IgbGFyZ2UgZGF0YXNldHMsIDUwMCBmb3Igc21hbGwpLlxuICAgKi9cbiAgbkVwb2Nocz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBzaXplIG9mIGxvY2FsIG5laWdoYm9yaG9vZCAoaW4gdGVybXMgb2YgbnVtYmVyIG9mIG5laWdoYm9yaW5nXG4gICAqIHNhbXBsZSBwb2ludHMpIHVzZWQgZm9yIG1hbmlmb2xkIGFwcHJveGltYXRpb24uIExhcmdlciB2YWx1ZXNcbiAgICogcmVzdWx0IGluIG1vcmUgZ2xvYmFsIHZpZXdzIG9mIHRoZSBtYW5pZm9sZCwgd2hpbGUgc21hbGxlclxuICAgKiB2YWx1ZXMgcmVzdWx0IGluIG1vcmUgbG9jYWwgZGF0YSBiZWluZyBwcmVzZXJ2ZWQuIEluIGdlbmVyYWxcbiAgICogdmFsdWVzIHNob3VsZCBiZSBpbiB0aGUgcmFuZ2UgMiB0byAxMDAuXG4gICAqL1xuICBuTmVpZ2hib3JzPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBuZWdhdGl2ZSBzYW1wbGVzIHRvIHNlbGVjdCBwZXIgcG9zaXRpdmUgc2FtcGxlXG4gICAqIGluIHRoZSBvcHRpbWl6YXRpb24gcHJvY2Vzcy4gSW5jcmVhc2luZyB0aGlzIHZhbHVlIHdpbGwgcmVzdWx0XG4gICAqIGluIGdyZWF0ZXIgcmVwdWxzaXZlIGZvcmNlIGJlaW5nIGFwcGxpZWQsIGdyZWF0ZXIgb3B0aW1pemF0aW9uXG4gICAqIGNvc3QsIGJ1dCBzbGlnaHRseSBtb3JlIGFjY3VyYWN5LlxuICAgKi9cbiAgbmVnYXRpdmVTYW1wbGVSYXRlPzogbnVtYmVyO1xuICAvKipcbiAgICogV2VpZ2h0aW5nIGFwcGxpZWQgdG8gbmVnYXRpdmUgc2FtcGxlcyBpbiBsb3cgZGltZW5zaW9uYWwgZW1iZWRkaW5nXG4gICAqIG9wdGltaXphdGlvbi4gVmFsdWVzIGhpZ2hlciB0aGFuIG9uZSB3aWxsIHJlc3VsdCBpbiBncmVhdGVyIHdlaWdodFxuICAgKiBiZWluZyBnaXZlbiB0byBuZWdhdGl2ZSBzYW1wbGVzLlxuICAgKi9cbiAgcmVwdWxzaW9uU3RyZW5ndGg/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgcHNldWRvLXJhbmRvbSBudW1iZXIgZ2VuZXJhdG9yIHVzZWQgYnkgdGhlIHN0b2NoYXN0aWMgcGFydHMgb2YgdGhlXG4gICAqIGFsZ29yaXRobS5cbiAgICovXG4gIHJhbmRvbT86IFJhbmRvbUZuO1xuICAvKipcbiAgICogSW50ZXJwb2xhdGUgYmV0d2VlbiAoZnV6enkpIHVuaW9uIGFuZCBpbnRlcnNlY3Rpb24gYXMgdGhlIHNldCBvcGVyYXRpb25cbiAgICogdXNlZCB0byBjb21iaW5lIGxvY2FsIGZ1enp5IHNpbXBsaWNpYWwgc2V0cyB0byBvYnRhaW4gYSBnbG9iYWwgZnV6enlcbiAgICogc2ltcGxpY2lhbCBzZXRzLiBCb3RoIGZ1enp5IHNldCBvcGVyYXRpb25zIHVzZSB0aGUgcHJvZHVjdCB0LW5vcm0uXG4gICAqIFRoZSB2YWx1ZSBvZiB0aGlzIHBhcmFtZXRlciBzaG91bGQgYmUgYmV0d2VlbiAwLjAgYW5kIDEuMDsgYSB2YWx1ZSBvZlxuICAgKiAxLjAgd2lsbCB1c2UgYSBwdXJlIGZ1enp5IHVuaW9uLCB3aGlsZSAwLjAgd2lsbCB1c2UgYSBwdXJlIGZ1enp5XG4gICAqIGludGVyc2VjdGlvbi5cbiAgICovXG4gIHNldE9wTWl4UmF0aW8/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgZWZmZWN0aXZlIHNjYWxlIG9mIGVtYmVkZGVkIHBvaW50cy4gSW4gY29tYmluYXRpb24gd2l0aCBgYG1pbl9kaXN0YGBcbiAgICogdGhpcyBkZXRlcm1pbmVzIGhvdyBjbHVzdGVyZWQvY2x1bXBlZCB0aGUgZW1iZWRkZWQgcG9pbnRzIGFyZS5cbiAgICovXG4gIHNwcmVhZD86IG51bWJlcjtcbiAgLyoqXG4gICAqIEZvciB0cmFuc2Zvcm0gb3BlcmF0aW9ucyAoZW1iZWRkaW5nIG5ldyBwb2ludHMgdXNpbmcgYSB0cmFpbmVkIG1vZGVsKVxuICAgKiB0aGlzIHdpbGwgY29udHJvbCBob3cgYWdncmVzc2l2ZWx5IHRvIHNlYXJjaCBmb3IgbmVhcmVzdCBuZWlnaGJvcnMuXG4gICAqIExhcmdlciB2YWx1ZXMgd2lsbCByZXN1bHQgaW4gc2xvd2VyIHBlcmZvcm1hbmNlIGJ1dCBtb3JlIGFjY3VyYXRlXG4gICAqIG5lYXJlc3QgbmVpZ2hib3IgZXZhbHVhdGlvbi5cbiAgICovXG4gIHRyYW5zZm9ybVF1ZXVlU2l6ZT86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVTUFQU3VwZXJ2aXNlZFBhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgbWV0cmljIHVzZWQgdG8gbWVhc3VyZSBkaXN0YW5jZSBmb3IgYSB0YXJnZXQgYXJyYXkgaXMgdXNpbmcgc3VwZXJ2aXNlZFxuICAgKiBkaW1lbnNpb24gcmVkdWN0aW9uLiBCeSBkZWZhdWx0IHRoaXMgaXMgJ2NhdGVnb3JpY2FsJyB3aGljaCB3aWxsIG1lYXN1cmVcbiAgICogZGlzdGFuY2UgaW4gdGVybXMgb2Ygd2hldGhlciBjYXRlZ29yaWVzIG1hdGNoIG9yIGFyZSBkaWZmZXJlbnQuIEZ1cnRoZXJtb3JlLFxuICAgKiBpZiBzZW1pLXN1cGVydmlzZWQgaXMgcmVxdWlyZWQgdGFyZ2V0IHZhbHVlcyBvZiAtMSB3aWxsIGJlIHRyZWF0ZWQgYXNcbiAgICogdW5sYWJlbGxlZCB1bmRlciB0aGUgJ2NhdGVnb3JpY2FsJyBtZXRyaWMuIElmIHRoZSB0YXJnZXQgYXJyYXkgdGFrZXNcbiAgICogY29udGludW91cyB2YWx1ZXMgKGUuZy4gZm9yIGEgcmVncmVzc2lvbiBwcm9ibGVtKSB0aGVuIG1ldHJpYyBvZiAnbDEnXG4gICAqIG9yICdsMicgaXMgcHJvYmFibHkgbW9yZSBhcHByb3ByaWF0ZS5cbiAgICovXG4gIHRhcmdldE1ldHJpYz86IFRhcmdldE1ldHJpYztcbiAgLyoqXG4gICAqIFdlaWdodGluZyBmYWN0b3IgYmV0d2VlbiBkYXRhIHRvcG9sb2d5IGFuZCB0YXJnZXQgdG9wb2xvZ3kuIEEgdmFsdWUgb2ZcbiAgICogMC4wIHdlaWdodHMgZW50aXJlbHkgb24gZGF0YSwgYSB2YWx1ZSBvZiAxLjAgd2VpZ2h0cyBlbnRpcmVseSBvbiB0YXJnZXQuXG4gICAqIFRoZSBkZWZhdWx0IG9mIDAuNSBiYWxhbmNlcyB0aGUgd2VpZ2h0aW5nIGVxdWFsbHkgYmV0d2VlbiBkYXRhIGFuZCB0YXJnZXQuXG4gICAqL1xuICB0YXJnZXRXZWlnaHQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIG5lYXJlc3QgbmVpZ2hib3JzIHRvIHVzZSB0byBjb25zdHJ1Y3QgdGhlIHRhcmdldCBzaW1wbGNpYWxcbiAgICogc2V0LiBEZWZhdWx0cyB0byB0aGUgYG5lYXJlc3ROZWlnaGJvcnNgIHBhcmFtZXRlci5cbiAgICovXG4gIHRhcmdldE5OZWlnaGJvcnM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogVU1BUCBwcm9qZWN0aW9uIHN5c3RlbSwgYmFzZWQgb24gdGhlIHB5dGhvbiBpbXBsZW1lbnRhdGlvbiBmcm9tIE1jSW5uZXMsIEwsXG4gKiBIZWFseSwgSiwgVU1BUDogVW5pZm9ybSBNYW5pZm9sZCBBcHByb3hpbWF0aW9uIGFuZCBQcm9qZWN0aW9uIGZvciBEaW1lbnNpb25cbiAqIFJlZHVjdGlvbiAoaHR0cHM6Ly9naXRodWIuY29tL2xtY2lubmVzL3VtYXApLlxuICpcbiAqIFRoaXMgaW1wbGVtZW50YXRpb24gZGlmZmVycyBpbiBhIGZldyByZWdhcmRzOlxuICogYSkgVGhlIGluaXRpYWxpemF0aW9uIG9mIHRoZSBlbWJlZGRpbmcgZm9yIG9wdGltaXphdGlvbiBpcyBub3QgY29tcHV0ZWQgdXNpbmdcbiAqICAgIGEgc3BlY3RyYWwgbWV0aG9kLCByYXRoZXIgaXQgaXMgaW5pdGlhbGl6ZWQgcmFuZG9tbHkuIFRoaXMgYXZvaWRzIHNvbWVcbiAqICAgIGNvbXB1dGF0aW9uYWxseSBpbnRlbnNpdmUgbWF0cml4IGVpZ2VuIGNvbXB1dGF0aW9ucyB0aGF0IGFyZW4ndCBlYXNpbHlcbiAqICAgIHBvcnRlZCB0byBKYXZhU2NyaXB0LlxuICogYikgQSBsb3Qgb2YgXCJleHRyYVwiIGZ1bmN0aW9uYWxpdHkgaGFzIGJlZW4gb21pdHRlZCBmcm9tIHRoaXMgaW1wbGVtZW50YXRpb24sXG4gKiAgICBtb3N0IG5vdGFibHkgYSBncmVhdCBkZWFsIG9mIGFsdGVybmF0ZSBkaXN0YW5jZSBmdW5jdGlvbnMuXG4gKlxuICogVGhpcyBpbXBsZW1lbnRhdGlvbiBwcm92aWRlcyB0aHJlZSBtZXRob2RzIG9mIHJlZHVjaW5nIGRpbWVuc2lvbmFsaXR5OlxuICogMSkgZml0OiBmaXQgdGhlIGRhdGEgc3luY2hyb25vdXNseVxuICogMikgZml0QXN5bmM6IGZpdCB0aGUgZGF0YSBhc3luY2hyb25vdXNseSwgd2l0aCBhIGNhbGxiYWNrIGZ1bmN0aW9uIHByb3ZpZGVkXG4gKiAgICAgIHRoYXQgaXMgaW52b2tlZCBvbiBlYWNoIG9wdGltaXphdGlvbiBzdGVwLlxuICogMykgaW5pdGlhbGl6ZUZpdCAvIHN0ZXA6IG1hbnVhbGx5IGluaXRpYWxpemUgdGhlIGFsZ29yaXRobSB0aGVuIGV4cGxpY3RseVxuICogICAgICBzdGVwIHRocm91Z2ggZWFjaCBlcG9jaCBvZiB0aGUgU0dEIG9wdGltaXphdGlvblxuICovXG5leHBvcnQgY2xhc3MgVU1BUCB7XG4gIHByaXZhdGUgbGVhcm5pbmdSYXRlID0gMS4wO1xuICBwcml2YXRlIGxvY2FsQ29ubmVjdGl2aXR5ID0gMS4wO1xuICBwcml2YXRlIG1pbkRpc3QgPSAwLjE7XG4gIHByaXZhdGUgbkNvbXBvbmVudHMgPSAyO1xuICBwcml2YXRlIG5FcG9jaHMgPSAwO1xuICBwcml2YXRlIG5OZWlnaGJvcnMgPSAxNTtcbiAgcHJpdmF0ZSBuZWdhdGl2ZVNhbXBsZVJhdGUgPSA1O1xuICBwcml2YXRlIHJhbmRvbSA9IE1hdGgucmFuZG9tO1xuICBwcml2YXRlIHJlcHVsc2lvblN0cmVuZ3RoID0gMS4wO1xuICBwcml2YXRlIHNldE9wTWl4UmF0aW8gPSAxLjA7XG4gIHByaXZhdGUgc3ByZWFkID0gMS4wO1xuICBwcml2YXRlIHRyYW5zZm9ybVF1ZXVlU2l6ZSA9IDQuMDtcblxuICAvLyBTdXBlcnZpc2VkIHByb2plY3Rpb24gcGFyYW1zXG4gIHByaXZhdGUgdGFyZ2V0TWV0cmljID0gVGFyZ2V0TWV0cmljLmNhdGVnb3JpY2FsO1xuICBwcml2YXRlIHRhcmdldFdlaWdodCA9IDAuNTtcbiAgcHJpdmF0ZSB0YXJnZXROTmVpZ2hib3JzID0gdGhpcy5uTmVpZ2hib3JzO1xuXG4gIHByaXZhdGUgZGlzdGFuY2VGbjogRGlzdGFuY2VGbiA9IG51bWVyaWM7XG5cbiAgLy8gS05OIHN0YXRlIChjYW4gYmUgcHJlY29tcHV0ZWQgYW5kIHN1cHBsaWVkIHZpYSBpbml0aWFsaXplRml0KVxuICBwcml2YXRlIGtubkluZGljZXM/OiBudW1iZXJbXVtdO1xuICBwcml2YXRlIGtubkRpc3RhbmNlcz86IG51bWJlcltdW107XG5cbiAgLy8gSW50ZXJuYWwgZ3JhcGggY29ubmVjdGl2aXR5IHJlcHJlc2VudGF0aW9uXG4gIHByaXZhdGUgZ3JhcGghOiBtYXRyaXguU3BhcnNlTWF0cml4O1xuICBwcml2YXRlIFghOiBWZWN0b3I7XG4gIHByaXZhdGUgaXNJbml0aWFsaXplZCA9IGZhbHNlO1xuICBwcml2YXRlIHJwRm9yZXN0OiB0cmVlLkZsYXRUcmVlW10gPSBbXTtcbiAgcHJpdmF0ZSBpbml0RnJvbVJhbmRvbSE6IG5uRGVzY2VudC5Jbml0RnJvbVJhbmRvbUZuO1xuICBwcml2YXRlIGluaXRGcm9tVHJlZSE6IG5uRGVzY2VudC5Jbml0RnJvbVRyZWVGbjtcbiAgcHJpdmF0ZSBzZWFyY2ghOiBubkRlc2NlbnQuU2VhcmNoRm47XG4gIHByaXZhdGUgc2VhcmNoR3JhcGghOiBtYXRyaXguU3BhcnNlTWF0cml4O1xuXG4gIC8vIFN1cGVydmlzZWQgcHJvamVjdGlvbiBsYWJlbHMgLyB0YXJnZXRzXG4gIHByaXZhdGUgWT86IG51bWJlcltdO1xuXG4gIC8vIFByb2plY3RlZCBlbWJlZGRpbmdcbiAgcHJpdmF0ZSBlbWJlZGRpbmc6IG51bWJlcltdW10gPSBbXTtcbiAgcHJpdmF0ZSBvcHRpbWl6YXRpb25TdGF0ZSA9IG5ldyBPcHRpbWl6YXRpb25TdGF0ZSgpO1xuXG5cbiAgZ2V0IG5laWdoYm9ycygpIHtcbiAgICByZXR1cm4gdGhpcy5uTmVpZ2hib3JzO1xuICB9XG4gIGNvbnN0cnVjdG9yKHBhcmFtczogVU1BUFBhcmFtZXRlcnMgPSB7fSkge1xuICAgIGNvbnN0IHNldFBhcmFtID0gKGtleToga2V5b2YgVU1BUFBhcmFtZXRlcnMpID0+IHtcbiAgICAgIC8vQHRzLWlnbm9yZVxuICAgICAgaWYgKHBhcmFtc1trZXldICE9PSB1bmRlZmluZWQpIHRoaXNba2V5XSA9IHBhcmFtc1trZXldO1xuICAgIH07XG5cbiAgICBzZXRQYXJhbSgnZGlzdGFuY2VGbicpO1xuICAgIHNldFBhcmFtKCdsZWFybmluZ1JhdGUnKTtcbiAgICBzZXRQYXJhbSgnbG9jYWxDb25uZWN0aXZpdHknKTtcbiAgICBzZXRQYXJhbSgnbWluRGlzdCcpO1xuICAgIHNldFBhcmFtKCduQ29tcG9uZW50cycpO1xuICAgIHNldFBhcmFtKCduRXBvY2hzJyk7XG4gICAgc2V0UGFyYW0oJ25OZWlnaGJvcnMnKTtcbiAgICBzZXRQYXJhbSgnbmVnYXRpdmVTYW1wbGVSYXRlJyk7XG4gICAgc2V0UGFyYW0oJ3JhbmRvbScpO1xuICAgIHNldFBhcmFtKCdyZXB1bHNpb25TdHJlbmd0aCcpO1xuICAgIHNldFBhcmFtKCdzZXRPcE1peFJhdGlvJyk7XG4gICAgc2V0UGFyYW0oJ3NwcmVhZCcpO1xuICAgIHNldFBhcmFtKCd0cmFuc2Zvcm1RdWV1ZVNpemUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXQgdGhlIGRhdGEgdG8gYSBwcm9qZWN0ZWQgZW1iZWRkaW5nIHNwYWNlIHN5bmNocm9ub3VzbHkuXG4gICAqL1xuICBmaXQoWDogVmVjdG9yKSB7XG4gICAgdGhpcy5pbml0aWFsaXplRml0KFgpO1xuICAgIHRoaXMub3B0aW1pemVMYXlvdXQoKTtcblxuICAgIHJldHVybiB0aGlzLmVtYmVkZGluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXQgdGhlIGRhdGEgdG8gYSBwcm9qZWN0ZWQgZW1iZWRkaW5nIHNwYWNlIGFzeW5jaHJvbm91c2x5LCB3aXRoIGEgY2FsbGJhY2tcbiAgICogZnVuY3Rpb24gaW52b2tlZCBvbiBldmVyeSBlcG9jaCBvZiBvcHRpbWl6YXRpb24uXG4gICAqL1xuICBhc3luYyBmaXRBc3luYyhcbiAgICBYOiBWZWN0b3IsXG4gICAgY2FsbGJhY2s6IChlcG9jaE51bWJlcjogbnVtYmVyKSA9PiB2b2lkIHwgYm9vbGVhbiA9ICgpID0+IHRydWVcbiAgKSB7XG4gICAgdGhpcy5pbml0aWFsaXplRml0KFgpO1xuXG4gICAgYXdhaXQgdGhpcy5vcHRpbWl6ZUxheW91dEFzeW5jKGNhbGxiYWNrKTtcbiAgICByZXR1cm4gdGhpcy5lbWJlZGRpbmc7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZXMgcGFyYW1ldGVycyBuZWVkZWQgZm9yIHN1cGVydmlzZWQgcHJvamVjdGlvbi5cbiAgICovXG4gIHNldFN1cGVydmlzZWRQcm9qZWN0aW9uKFk6IG51bWJlcltdLCBwYXJhbXM6IFVNQVBTdXBlcnZpc2VkUGFyYW1zID0ge30pIHtcbiAgICB0aGlzLlkgPSBZO1xuICAgIHRoaXMudGFyZ2V0TWV0cmljID0gcGFyYW1zLnRhcmdldE1ldHJpYyB8fCB0aGlzLnRhcmdldE1ldHJpYztcbiAgICB0aGlzLnRhcmdldFdlaWdodCA9IHBhcmFtcy50YXJnZXRXZWlnaHQgfHwgdGhpcy50YXJnZXRXZWlnaHQ7XG4gICAgdGhpcy50YXJnZXROTmVpZ2hib3JzID0gcGFyYW1zLnRhcmdldE5OZWlnaGJvcnMgfHwgdGhpcy50YXJnZXROTmVpZ2hib3JzO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIHVtYXAgd2l0aCBwcmVjb21wdXRlZCBLTk4gaW5kaWNlcyBhbmQgZGlzdGFuY2VzLlxuICAgKi9cbiAgc2V0UHJlY29tcHV0ZWRLTk4oa25uSW5kaWNlczogbnVtYmVyW11bXSwga25uRGlzdGFuY2VzOiBudW1iZXJbXVtdKSB7XG4gICAgdGhpcy5rbm5JbmRpY2VzID0ga25uSW5kaWNlcztcbiAgICB0aGlzLmtubkRpc3RhbmNlcyA9IGtubkRpc3RhbmNlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplcyBmaXQgYnkgY29tcHV0aW5nIEtOTiBhbmQgYSBmdXp6eSBzaW1wbGljaWFsIHNldCwgYXMgd2VsbCBhc1xuICAgKiBpbml0aWFsaXppbmcgdGhlIHByb2plY3RlZCBlbWJlZGRpbmdzLiBTZXRzIHRoZSBvcHRpbWl6YXRpb24gc3RhdGUgYWhlYWRcbiAgICogb2Ygb3B0aW1pemF0aW9uIHN0ZXBzLiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgZXBvY2hzIHRvIGJlIHVzZWQgZm9yIHRoZVxuICAgKiBTR0Qgb3B0aW1pemF0aW9uLlxuICAgKi9cbiAgaW5pdGlhbGl6ZUZpdChYOiBWZWN0b3IpOiBudW1iZXIge1xuICAgIGlmIChYLmxlbmd0aCA8PSB0aGlzLm5OZWlnaGJvcnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTm90IGVub3VnaCBkYXRhIHBvaW50cyAoJHtYLmxlbmd0aH0pIHRvIGNyZWF0ZSBuTmVpZ2hib3JzOiAke3RoaXMubk5laWdoYm9yc30uICBBZGQgbW9yZSBkYXRhIHBvaW50cyBvciBhZGp1c3QgdGhlIGNvbmZpZ3VyYXRpb24uYCk7XG4gICAgfVxuXG4gICAgLy8gV2UgZG9uJ3QgbmVlZCB0byByZWluaXRpYWxpemUgaWYgd2UndmUgYWxyZWFkeSBpbml0aWFsaXplZCBmb3IgdGhpcyBkYXRhLlxuICAgIGlmICh0aGlzLlggPT09IFggJiYgdGhpcy5pc0luaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRORXBvY2hzKCk7XG4gICAgfVxuXG4gICAgdGhpcy5YID0gWDtcblxuICAgIGlmICghdGhpcy5rbm5JbmRpY2VzICYmICF0aGlzLmtubkRpc3RhbmNlcykge1xuICAgICAgY29uc3Qga25uUmVzdWx0cyA9IHRoaXMubmVhcmVzdE5laWdoYm9ycyhYKTtcbiAgICAgIHRoaXMua25uSW5kaWNlcyA9IGtublJlc3VsdHMua25uSW5kaWNlcztcbiAgICAgIHRoaXMua25uRGlzdGFuY2VzID0ga25uUmVzdWx0cy5rbm5EaXN0YW5jZXM7XG4gICAgfVxuXG4gICAgdGhpcy5ncmFwaCA9IHRoaXMuZnV6enlTaW1wbGljaWFsU2V0KFxuICAgICAgWCxcbiAgICAgIHRoaXMubk5laWdoYm9ycyxcbiAgICAgIHRoaXMuc2V0T3BNaXhSYXRpb1xuICAgICk7XG5cbiAgICAvLyBTZXQgdXAgdGhlIHNlYXJjaCBncmFwaCBmb3Igc3Vic2VxdWVudCB0cmFuc2Zvcm1hdGlvbi5cbiAgICB0aGlzLm1ha2VTZWFyY2hGbnMoKTtcbiAgICB0aGlzLnNlYXJjaEdyYXBoID0gdGhpcy5tYWtlU2VhcmNoR3JhcGgoWCk7XG5cbiAgICAvLyBDaGVjayBpZiBzdXBlcnZpc2VkIHByb2plY3Rpb24sIHRoZW4gYWRqdXN0IHRoZSBncmFwaC5cbiAgICB0aGlzLnByb2Nlc3NHcmFwaEZvclN1cGVydmlzZWRQcm9qZWN0aW9uKCk7XG5cbiAgICBjb25zdCB7XG4gICAgICBoZWFkLFxuICAgICAgdGFpbCxcbiAgICAgIGVwb2Noc1BlclNhbXBsZSxcbiAgICB9ID0gdGhpcy5pbml0aWFsaXplU2ltcGxpY2lhbFNldEVtYmVkZGluZygpO1xuXG4gICAgLy8gU2V0IHRoZSBvcHRpbWl6YXRpb24gcm91dGluZSBzdGF0ZVxuICAgIHRoaXMub3B0aW1pemF0aW9uU3RhdGUuaGVhZCA9IGhlYWQ7XG4gICAgdGhpcy5vcHRpbWl6YXRpb25TdGF0ZS50YWlsID0gdGFpbDtcbiAgICB0aGlzLm9wdGltaXphdGlvblN0YXRlLmVwb2Noc1BlclNhbXBsZSA9IGVwb2Noc1BlclNhbXBsZTtcblxuICAgIC8vIE5vdywgaW5pdGlhbGl6ZSB0aGUgb3B0aW1pemF0aW9uIHN0ZXBzXG4gICAgdGhpcy5pbml0aWFsaXplT3B0aW1pemF0aW9uKCk7XG4gICAgdGhpcy5wcmVwYXJlRm9yT3B0aW1pemF0aW9uTG9vcCgpO1xuICAgIHRoaXMuaXNJbml0aWFsaXplZCA9IHRydWU7XG5cbiAgICByZXR1cm4gdGhpcy5nZXRORXBvY2hzKCk7XG4gIH1cblxuICBwcml2YXRlIG1ha2VTZWFyY2hGbnMoKSB7XG4gICAgY29uc3QgeyBpbml0RnJvbVRyZWUsIGluaXRGcm9tUmFuZG9tIH0gPSBubkRlc2NlbnQubWFrZUluaXRpYWxpemF0aW9ucyhcbiAgICAgIHRoaXMuZGlzdGFuY2VGblxuICAgICk7XG4gICAgdGhpcy5pbml0RnJvbVRyZWUgPSBpbml0RnJvbVRyZWU7XG4gICAgdGhpcy5pbml0RnJvbVJhbmRvbSA9IGluaXRGcm9tUmFuZG9tO1xuICAgIHRoaXMuc2VhcmNoID0gbm5EZXNjZW50Lm1ha2VJbml0aWFsaXplZE5OU2VhcmNoKHRoaXMuZGlzdGFuY2VGbik7XG4gIH1cblxuICBwcml2YXRlIG1ha2VTZWFyY2hHcmFwaChYOiBWZWN0b3IpIHtcbiAgICBjb25zdCBrbm5JbmRpY2VzID0gdGhpcy5rbm5JbmRpY2VzITtcbiAgICBjb25zdCBrbm5EaXN0YW5jZXMgPSB0aGlzLmtubkRpc3RhbmNlcyE7XG4gICAgY29uc3QgZGltcyA9IFtYLmxlbmd0aCwgWC5sZW5ndGhdO1xuICAgIGNvbnN0IHNlYXJjaEdyYXBoID0gbmV3IG1hdHJpeC5TcGFyc2VNYXRyaXgoW10sIFtdLCBbXSwgZGltcyk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrbm5JbmRpY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBrbm4gPSBrbm5JbmRpY2VzW2ldO1xuICAgICAgY29uc3QgZGlzdGFuY2VzID0ga25uRGlzdGFuY2VzW2ldO1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBrbm4ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgY29uc3QgbmVpZ2hib3IgPSBrbm5bal07XG4gICAgICAgIGNvbnN0IGRpc3RhbmNlID0gZGlzdGFuY2VzW2pdO1xuICAgICAgICBpZiAoZGlzdGFuY2UgPiAwKSB7XG4gICAgICAgICAgc2VhcmNoR3JhcGguc2V0KGksIG5laWdoYm9yLCBkaXN0YW5jZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB0cmFuc3Bvc2UgPSBtYXRyaXgudHJhbnNwb3NlKHNlYXJjaEdyYXBoKTtcbiAgICByZXR1cm4gbWF0cml4Lm1heGltdW0oc2VhcmNoR3JhcGgsIHRyYW5zcG9zZSk7XG4gIH1cblxuICAvKipcbiAgICogVHJhbnNmb3JtcyBkYXRhIHRvIHRoZSBleGlzdGluZyBlbWJlZGRpbmcgc3BhY2UuXG4gICAqL1xuICB0cmFuc2Zvcm0odG9UcmFuc2Zvcm06IFZlY3Rvcikge1xuICAgIC8vIFVzZSB0aGUgcHJldmlvdXMgcmF3RGF0YVxuICAgIGNvbnN0IHJhd0RhdGEgPSB0aGlzLlg7XG4gICAgaWYgKHJhd0RhdGEgPT09IHVuZGVmaW5lZCB8fCByYXdEYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBkYXRhIGhhcyBiZWVuIGZpdC4nKTtcbiAgICB9XG5cbiAgICBsZXQgbk5laWdoYm9ycyA9IE1hdGguZmxvb3IodGhpcy5uTmVpZ2hib3JzICogdGhpcy50cmFuc2Zvcm1RdWV1ZVNpemUpO1xuICAgIG5OZWlnaGJvcnMgPSBNYXRoLm1pbihyYXdEYXRhLmxlbmd0aCwgbk5laWdoYm9ycyk7XG4gICAgY29uc3QgaW5pdCA9IG5uRGVzY2VudC5pbml0aWFsaXplU2VhcmNoKFxuICAgICAgdGhpcy5ycEZvcmVzdCxcbiAgICAgIHJhd0RhdGEsXG4gICAgICB0b1RyYW5zZm9ybSxcbiAgICAgIG5OZWlnaGJvcnMsXG4gICAgICB0aGlzLmluaXRGcm9tUmFuZG9tLFxuICAgICAgdGhpcy5pbml0RnJvbVRyZWUsXG4gICAgICB0aGlzLnJhbmRvbVxuICAgICk7XG5cbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLnNlYXJjaChyYXdEYXRhLCB0aGlzLnNlYXJjaEdyYXBoLCBpbml0LCB0b1RyYW5zZm9ybSk7XG5cbiAgICBsZXQgeyBpbmRpY2VzLCB3ZWlnaHRzOiBkaXN0YW5jZXMgfSA9IGhlYXAuZGVoZWFwU29ydChyZXN1bHQpO1xuXG4gICAgaW5kaWNlcyA9IGluZGljZXMubWFwKHggPT4geC5zbGljZSgwLCB0aGlzLm5OZWlnaGJvcnMpKTtcbiAgICBkaXN0YW5jZXMgPSBkaXN0YW5jZXMubWFwKHggPT4geC5zbGljZSgwLCB0aGlzLm5OZWlnaGJvcnMpKTtcblxuICAgIGNvbnN0IGFkanVzdGVkTG9jYWxDb25uZWN0aXZpdHkgPSBNYXRoLm1heCgwLCB0aGlzLmxvY2FsQ29ubmVjdGl2aXR5IC0gMSk7XG4gICAgY29uc3QgeyBzaWdtYXMsIHJob3MgfSA9IHRoaXMuc21vb3RoS05ORGlzdGFuY2UoXG4gICAgICBkaXN0YW5jZXMsXG4gICAgICB0aGlzLm5OZWlnaGJvcnMsXG4gICAgICBhZGp1c3RlZExvY2FsQ29ubmVjdGl2aXR5XG4gICAgKTtcblxuICAgIGNvbnN0IHsgcm93cywgY29scywgdmFscyB9ID0gdGhpcy5jb21wdXRlTWVtYmVyc2hpcFN0cmVuZ3RocyhcbiAgICAgIGluZGljZXMsXG4gICAgICBkaXN0YW5jZXMsXG4gICAgICBzaWdtYXMsXG4gICAgICByaG9zXG4gICAgKTtcblxuICAgIGNvbnN0IHNpemUgPSBbdG9UcmFuc2Zvcm0ubGVuZ3RoLCByYXdEYXRhLmxlbmd0aF07XG4gICAgbGV0IGdyYXBoID0gbmV3IG1hdHJpeC5TcGFyc2VNYXRyaXgocm93cywgY29scywgdmFscywgc2l6ZSk7XG5cbiAgICAvLyBUaGlzIHdhcyBhIHZlcnkgc3BlY2lhbGx5IGNvbnN0cnVjdGVkIGdyYXBoIHdpdGggY29uc3RhbnQgZGVncmVlLlxuICAgIC8vIFRoYXQgbGV0cyB1cyBkbyBmYW5jeSB1bnBhY2tpbmcgYnkgcmVzaGFwaW5nIHRoZSBjc3IgbWF0cml4IGluZGljZXNcbiAgICAvLyBhbmQgZGF0YS4gRG9pbmcgc28gcmVsaWVzIG9uIHRoZSBjb25zdGFudCBkZWdyZWUgYXNzdW1wdGlvbiFcblxuICAgIGNvbnN0IG5vcm1lZCA9IG1hdHJpeC5ub3JtYWxpemUoZ3JhcGgsIG1hdHJpeC5Ob3JtVHlwZS5sMSk7XG5cbiAgICBjb25zdCBjc3JNYXRyaXggPSBtYXRyaXguZ2V0Q1NSKG5vcm1lZCk7XG4gICAgY29uc3QgblBvaW50cyA9IHRvVHJhbnNmb3JtLmxlbmd0aDtcblxuICAgIGNvbnN0IGVJbmRpY2VzID0gdXRpbHMucmVzaGFwZTJkKFxuICAgICAgY3NyTWF0cml4LmluZGljZXMsXG4gICAgICBuUG9pbnRzLFxuICAgICAgdGhpcy5uTmVpZ2hib3JzXG4gICAgKTtcblxuICAgIGNvbnN0IGVXZWlnaHRzID0gdXRpbHMucmVzaGFwZTJkKFxuICAgICAgY3NyTWF0cml4LnZhbHVlcyxcbiAgICAgIG5Qb2ludHMsXG4gICAgICB0aGlzLm5OZWlnaGJvcnNcbiAgICApO1xuXG4gICAgY29uc3QgZW1iZWRkaW5nID0gaW5pdFRyYW5zZm9ybShlSW5kaWNlcywgZVdlaWdodHMsIHRoaXMuZW1iZWRkaW5nKTtcblxuICAgIGNvbnN0IG5FcG9jaHMgPSB0aGlzLm5FcG9jaHNcbiAgICAgID8gdGhpcy5uRXBvY2hzIC8gM1xuICAgICAgOiBncmFwaC5uUm93cyA8PSAxMDAwMFxuICAgICAgPyAxMDBcbiAgICAgIDogMzA7XG5cbiAgICBjb25zdCBncmFwaE1heCA9IGdyYXBoXG4gICAgICAuZ2V0VmFsdWVzKClcbiAgICAgIC5yZWR1Y2UoKG1heCwgdmFsKSA9PiAodmFsID4gbWF4ID8gdmFsIDogbWF4KSwgMCk7XG4gICAgZ3JhcGggPSBncmFwaC5tYXAodmFsdWUgPT4gKHZhbHVlIDwgZ3JhcGhNYXggLyBuRXBvY2hzID8gMCA6IHZhbHVlKSk7XG4gICAgZ3JhcGggPSBtYXRyaXguZWxpbWluYXRlWmVyb3MoZ3JhcGgpO1xuXG4gICAgY29uc3QgZXBvY2hzUGVyU2FtcGxlID0gdGhpcy5tYWtlRXBvY2hzUGVyU2FtcGxlKFxuICAgICAgZ3JhcGguZ2V0VmFsdWVzKCksXG4gICAgICBuRXBvY2hzXG4gICAgKTtcbiAgICBjb25zdCBoZWFkID0gZ3JhcGguZ2V0Um93cygpO1xuICAgIGNvbnN0IHRhaWwgPSBncmFwaC5nZXRDb2xzKCk7XG5cbiAgICAvLyBJbml0aWFsaXplIG9wdGltaXphdGlvbiBzbGlnaHRseSBkaWZmZXJlbnRseSB0aGFuIHRoZSBmaXQgbWV0aG9kLlxuICAgIHRoaXMuYXNzaWduT3B0aW1pemF0aW9uU3RhdGVQYXJhbWV0ZXJzKHtcbiAgICAgIGhlYWRFbWJlZGRpbmc6IGVtYmVkZGluZyxcbiAgICAgIHRhaWxFbWJlZGRpbmc6IHRoaXMuZW1iZWRkaW5nLFxuICAgICAgaGVhZCxcbiAgICAgIHRhaWwsXG4gICAgICBjdXJyZW50RXBvY2g6IDAsXG4gICAgICBuRXBvY2hzLFxuICAgICAgblZlcnRpY2VzOiBncmFwaC5nZXREaW1zKClbMV0sXG4gICAgICBlcG9jaHNQZXJTYW1wbGUsXG4gICAgfSk7XG4gICAgdGhpcy5wcmVwYXJlRm9yT3B0aW1pemF0aW9uTG9vcCgpO1xuXG4gICAgcmV0dXJuIHRoaXMub3B0aW1pemVMYXlvdXQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgd2UncmUgdXNpbmcgc3VwZXJ2aXNlZCBwcm9qZWN0aW9uLCB0aGVuIHByb2Nlc3MgdGhlIGdyYXBoXG4gICAqIGFjY29yZGluZ2x5LlxuICAgKi9cbiAgcHJpdmF0ZSBwcm9jZXNzR3JhcGhGb3JTdXBlcnZpc2VkUHJvamVjdGlvbigpIHtcbiAgICBjb25zdCB7IFksIFggfSA9IHRoaXM7XG4gICAgaWYgKFkpIHtcbiAgICAgIGlmIChZLmxlbmd0aCAhPT0gWC5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMZW5ndGggb2YgWCBhbmQgeSBtdXN0IGJlIGVxdWFsJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnRhcmdldE1ldHJpYyA9PT0gVGFyZ2V0TWV0cmljLmNhdGVnb3JpY2FsKSB7XG4gICAgICAgIGNvbnN0IGx0ID0gdGhpcy50YXJnZXRXZWlnaHQgPCAxLjA7XG4gICAgICAgIGNvbnN0IGZhckRpc3QgPSBsdCA/IDIuNSAqICgxLjAgLyAoMS4wIC0gdGhpcy50YXJnZXRXZWlnaHQpKSA6IDEuMGUxMjtcbiAgICAgICAgdGhpcy5ncmFwaCA9IHRoaXMuY2F0ZWdvcmljYWxTaW1wbGljaWFsU2V0SW50ZXJzZWN0aW9uKFxuICAgICAgICAgIHRoaXMuZ3JhcGgsXG4gICAgICAgICAgWSxcbiAgICAgICAgICBmYXJEaXN0XG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICAvLyBUT0RPIChhbmR5Y29lbmVuQCk6IGFkZCBub24tY2F0ZWdvcmljYWwgc3VwZXJ2aXNlZCBlbWJlZGRpbmdzLlxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNYW51YWxseSBzdGVwIHRocm91Z2ggdGhlIG9wdGltaXphdGlvbiBwcm9jZXNzIG9uZSBlcG9jaCBhdCBhIHRpbWUuXG4gICAqL1xuICBzdGVwKCkge1xuICAgIGNvbnN0IHsgY3VycmVudEVwb2NoIH0gPSB0aGlzLm9wdGltaXphdGlvblN0YXRlO1xuXG4gICAgaWYgKGN1cnJlbnRFcG9jaCA8IHRoaXMuZ2V0TkVwb2NocygpKSB7XG4gICAgICB0aGlzLm9wdGltaXplTGF5b3V0U3RlcChjdXJyZW50RXBvY2gpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5vcHRpbWl6YXRpb25TdGF0ZS5jdXJyZW50RXBvY2g7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY29tcHV0ZWQgcHJvamVjdGVkIGVtYmVkZGluZy5cbiAgICovXG4gIGdldEVtYmVkZGluZygpIHtcbiAgICByZXR1cm4gdGhpcy5lbWJlZGRpbmc7XG4gIH1cblxuICAvKipcbiAgICogQ29tcHV0ZSB0aGUgYGBuTmVpZ2hib3JzYGAgbmVhcmVzdCBwb2ludHMgZm9yIGVhY2ggZGF0YSBwb2ludCBpbiBgYFhgYFxuICAgKiBUaGlzIG1heSBiZSBleGFjdCwgYnV0IG1vcmUgbGlrZWx5IGlzIGFwcHJveGltYXRlZCB2aWEgbmVhcmVzdCBuZWlnaGJvclxuICAgKiBkZXNjZW50LlxuICAgKi9cbiAgcHJpdmF0ZSBuZWFyZXN0TmVpZ2hib3JzKFg6IFZlY3Rvcikge1xuICAgIGNvbnN0IHsgZGlzdGFuY2VGbiwgbk5laWdoYm9ycyB9ID0gdGhpcztcbiAgICBjb25zdCBsb2cyID0gKG46IG51bWJlcikgPT4gTWF0aC5sb2cobikgLyBNYXRoLmxvZygyKTtcbiAgICBjb25zdCBtZXRyaWNOTkRlc2NlbnQgPSBubkRlc2NlbnQubWFrZU5ORGVzY2VudChkaXN0YW5jZUZuLCB0aGlzLnJhbmRvbSk7XG5cbiAgICAvLyBIYW5kbGUgcHl0aG9uMyByb3VuZGluZyBkb3duIGZyb20gMC41IGRpc2NycGFuY3lcbiAgICBjb25zdCByb3VuZCA9IChuOiBudW1iZXIpID0+IHtcbiAgICAgIHJldHVybiBuID09PSAwLjUgPyAwIDogTWF0aC5yb3VuZChuKTtcbiAgICB9O1xuXG4gICAgY29uc3QgblRyZWVzID0gNSArIE1hdGguZmxvb3Iocm91bmQoWC5sZW5ndGggKiogMC41IC8gMjAuMCkpO1xuICAgIGNvbnN0IG5JdGVycyA9IE1hdGgubWF4KDUsIE1hdGguZmxvb3IoTWF0aC5yb3VuZChsb2cyKFgubGVuZ3RoKSkpKTtcblxuICAgIHRoaXMucnBGb3Jlc3QgPSB0cmVlLm1ha2VGb3Jlc3QoWCwgbk5laWdoYm9ycywgblRyZWVzLCB0aGlzLnJhbmRvbSk7XG5cbiAgICBjb25zdCBsZWFmQXJyYXkgPSB0cmVlLm1ha2VMZWFmQXJyYXkodGhpcy5ycEZvcmVzdCk7XG4gICAgY29uc3QgeyBpbmRpY2VzLCB3ZWlnaHRzIH0gPSBtZXRyaWNOTkRlc2NlbnQoXG4gICAgICBYLFxuICAgICAgbGVhZkFycmF5LFxuICAgICAgbk5laWdoYm9ycyxcbiAgICAgIG5JdGVyc1xuICAgICk7XG4gICAgcmV0dXJuIHsga25uSW5kaWNlczogaW5kaWNlcywga25uRGlzdGFuY2VzOiB3ZWlnaHRzIH07XG4gIH1cblxuICAvKipcbiAgICogR2l2ZW4gYSBzZXQgb2YgZGF0YSBYLCBhIG5laWdoYm9yaG9vZCBzaXplLCBhbmQgYSBtZWFzdXJlIG9mIGRpc3RhbmNlXG4gICAqIGNvbXB1dGUgdGhlIGZ1enp5IHNpbXBsaWNpYWwgc2V0IChoZXJlIHJlcHJlc2VudGVkIGFzIGEgZnV6enkgZ3JhcGggaW5cbiAgICogdGhlIGZvcm0gb2YgYSBzcGFyc2UgbWF0cml4KSBhc3NvY2lhdGVkIHRvIHRoZSBkYXRhLiBUaGlzIGlzIGRvbmUgYnlcbiAgICogbG9jYWxseSBhcHByb3hpbWF0aW5nIGdlb2Rlc2ljIGRpc3RhbmNlIGF0IGVhY2ggcG9pbnQsIGNyZWF0aW5nIGEgZnV6enlcbiAgICogc2ltcGxpY2lhbCBzZXQgZm9yIGVhY2ggc3VjaCBwb2ludCwgYW5kIHRoZW4gY29tYmluaW5nIGFsbCB0aGUgbG9jYWxcbiAgICogZnV6enkgc2ltcGxpY2lhbCBzZXRzIGludG8gYSBnbG9iYWwgb25lIHZpYSBhIGZ1enp5IHVuaW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBmdXp6eVNpbXBsaWNpYWxTZXQoXG4gICAgWDogVmVjdG9yLFxuICAgIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgICBzZXRPcE1peFJhdGlvID0gMS4wXG4gICkge1xuICAgIGNvbnN0IHsga25uSW5kaWNlcyA9IFtdLCBrbm5EaXN0YW5jZXMgPSBbXSwgbG9jYWxDb25uZWN0aXZpdHkgfSA9IHRoaXM7XG5cbiAgICBjb25zdCB7IHNpZ21hcywgcmhvcyB9ID0gdGhpcy5zbW9vdGhLTk5EaXN0YW5jZShcbiAgICAgIGtubkRpc3RhbmNlcyxcbiAgICAgIG5OZWlnaGJvcnMsXG4gICAgICBsb2NhbENvbm5lY3Rpdml0eVxuICAgICk7XG5cbiAgICBjb25zdCB7IHJvd3MsIGNvbHMsIHZhbHMgfSA9IHRoaXMuY29tcHV0ZU1lbWJlcnNoaXBTdHJlbmd0aHMoXG4gICAgICBrbm5JbmRpY2VzLFxuICAgICAga25uRGlzdGFuY2VzLFxuICAgICAgc2lnbWFzLFxuICAgICAgcmhvc1xuICAgICk7XG5cbiAgICBjb25zdCBzaXplID0gW1gubGVuZ3RoLCBYLmxlbmd0aF07XG4gICAgY29uc3Qgc3BhcnNlTWF0cml4ID0gbmV3IG1hdHJpeC5TcGFyc2VNYXRyaXgocm93cywgY29scywgdmFscywgc2l6ZSk7XG5cbiAgICBjb25zdCB0cmFuc3Bvc2UgPSBtYXRyaXgudHJhbnNwb3NlKHNwYXJzZU1hdHJpeCk7XG4gICAgY29uc3QgcHJvZE1hdHJpeCA9IG1hdHJpeC5wYWlyd2lzZU11bHRpcGx5KHNwYXJzZU1hdHJpeCwgdHJhbnNwb3NlKTtcblxuICAgIGNvbnN0IGEgPSBtYXRyaXguc3VidHJhY3QobWF0cml4LmFkZChzcGFyc2VNYXRyaXgsIHRyYW5zcG9zZSksIHByb2RNYXRyaXgpO1xuICAgIGNvbnN0IGIgPSBtYXRyaXgubXVsdGlwbHlTY2FsYXIoYSwgc2V0T3BNaXhSYXRpbyk7XG4gICAgY29uc3QgYyA9IG1hdHJpeC5tdWx0aXBseVNjYWxhcihwcm9kTWF0cml4LCAxLjAgLSBzZXRPcE1peFJhdGlvKTtcbiAgICBjb25zdCByZXN1bHQgPSBtYXRyaXguYWRkKGIsIGMpO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21iaW5lIGEgZnV6enkgc2ltcGxpY2lhbCBzZXQgd2l0aCBhbm90aGVyIGZ1enp5IHNpbXBsaWNpYWwgc2V0XG4gICAqIGdlbmVyYXRlZCBmcm9tIGNhdGVnb3JpY2FsIGRhdGEgdXNpbmcgY2F0ZWdvcmljYWwgZGlzdGFuY2VzLiBUaGUgdGFyZ2V0XG4gICAqIGRhdGEgaXMgYXNzdW1lZCB0byBiZSBjYXRlZ29yaWNhbCBsYWJlbCBkYXRhIChhIHZlY3RvciBvZiBsYWJlbHMpLFxuICAgKiBhbmQgdGhpcyB3aWxsIHVwZGF0ZSB0aGUgZnV6enkgc2ltcGxpY2lhbCBzZXQgdG8gcmVzcGVjdCB0aGF0IGxhYmVsIGRhdGEuXG4gICAqL1xuICBwcml2YXRlIGNhdGVnb3JpY2FsU2ltcGxpY2lhbFNldEludGVyc2VjdGlvbihcbiAgICBzaW1wbGljaWFsU2V0OiBtYXRyaXguU3BhcnNlTWF0cml4LFxuICAgIHRhcmdldDogbnVtYmVyW10sXG4gICAgZmFyRGlzdDogbnVtYmVyLFxuICAgIHVua25vd25EaXN0ID0gMS4wXG4gICkge1xuICAgIGxldCBpbnRlcnNlY3Rpb24gPSBmYXN0SW50ZXJzZWN0aW9uKFxuICAgICAgc2ltcGxpY2lhbFNldCxcbiAgICAgIHRhcmdldCxcbiAgICAgIHVua25vd25EaXN0LFxuICAgICAgZmFyRGlzdFxuICAgICk7XG4gICAgaW50ZXJzZWN0aW9uID0gbWF0cml4LmVsaW1pbmF0ZVplcm9zKGludGVyc2VjdGlvbik7XG4gICAgcmV0dXJuIHJlc2V0TG9jYWxDb25uZWN0aXZpdHkoaW50ZXJzZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlIGEgY29udGludW91cyB2ZXJzaW9uIG9mIHRoZSBkaXN0YW5jZSB0byB0aGUga3RoIG5lYXJlc3RcbiAgICogbmVpZ2hib3IuIFRoYXQgaXMsIHRoaXMgaXMgc2ltaWxhciB0byBrbm4tZGlzdGFuY2UgYnV0IGFsbG93cyBjb250aW51b3VzXG4gICAqIGsgdmFsdWVzIHJhdGhlciB0aGFuIHJlcXVpcmluZyBhbiBpbnRlZ3JhbCBrLiBJbiBlc3NjZW5jZSB3ZSBhcmUgc2ltcGx5XG4gICAqIGNvbXB1dGluZyB0aGUgZGlzdGFuY2Ugc3VjaCB0aGF0IHRoZSBjYXJkaW5hbGl0eSBvZiBmdXp6eSBzZXQgd2UgZ2VuZXJhdGVcbiAgICogaXMgay5cbiAgICovXG4gIHByaXZhdGUgc21vb3RoS05ORGlzdGFuY2UoXG4gICAgZGlzdGFuY2VzOiBWZWN0b3JzLFxuICAgIGs6IG51bWJlcixcbiAgICBsb2NhbENvbm5lY3Rpdml0eSA9IDEuMCxcbiAgICBuSXRlciA9IDY0LFxuICAgIGJhbmR3aWR0aCA9IDEuMFxuICApIHtcbiAgICBjb25zdCB0YXJnZXQgPSAoTWF0aC5sb2coaykgLyBNYXRoLmxvZygyKSkgKiBiYW5kd2lkdGg7XG4gICAgY29uc3QgcmhvID0gdXRpbHMuemVyb3MoZGlzdGFuY2VzLmxlbmd0aCk7XG4gICAgY29uc3QgcmVzdWx0ID0gdXRpbHMuemVyb3MoZGlzdGFuY2VzLmxlbmd0aCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpc3RhbmNlcy5sZW5ndGg7IGkrKykge1xuICAgICAgbGV0IGxvID0gMC4wO1xuICAgICAgbGV0IGhpID0gSW5maW5pdHk7XG4gICAgICBsZXQgbWlkID0gMS4wO1xuXG4gICAgICAvLyBUT0RPOiBUaGlzIGlzIHZlcnkgaW5lZmZpY2llbnQsIGJ1dCB3aWxsIGRvIGZvciBub3cuIEZJWE1FXG4gICAgICBjb25zdCBpdGhEaXN0YW5jZXMgPSBkaXN0YW5jZXNbaV07XG4gICAgICBjb25zdCBub25aZXJvRGlzdHMgPSBpdGhEaXN0YW5jZXMuZmlsdGVyKGQgPT4gZCA+IDAuMCk7XG5cbiAgICAgIGlmIChub25aZXJvRGlzdHMubGVuZ3RoID49IGxvY2FsQ29ubmVjdGl2aXR5KSB7XG4gICAgICAgIGxldCBpbmRleCA9IE1hdGguZmxvb3IobG9jYWxDb25uZWN0aXZpdHkpO1xuICAgICAgICBsZXQgaW50ZXJwb2xhdGlvbiA9IGxvY2FsQ29ubmVjdGl2aXR5IC0gaW5kZXg7XG4gICAgICAgIGlmIChpbmRleCA+IDApIHtcbiAgICAgICAgICByaG9baV0gPSBub25aZXJvRGlzdHNbaW5kZXggLSAxXTtcbiAgICAgICAgICBpZiAoaW50ZXJwb2xhdGlvbiA+IFNNT09USF9LX1RPTEVSQU5DRSkge1xuICAgICAgICAgICAgcmhvW2ldICs9XG4gICAgICAgICAgICAgIGludGVycG9sYXRpb24gKiAobm9uWmVyb0Rpc3RzW2luZGV4XSAtIG5vblplcm9EaXN0c1tpbmRleCAtIDFdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmhvW2ldID0gaW50ZXJwb2xhdGlvbiAqIG5vblplcm9EaXN0c1swXTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChub25aZXJvRGlzdHMubGVuZ3RoID4gMCkge1xuICAgICAgICByaG9baV0gPSB1dGlscy5tYXgobm9uWmVyb0Rpc3RzKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgbiA9IDA7IG4gPCBuSXRlcjsgbisrKSB7XG4gICAgICAgIGxldCBwc3VtID0gMC4wO1xuICAgICAgICBmb3IgKGxldCBqID0gMTsgaiA8IGRpc3RhbmNlc1tpXS5sZW5ndGg7IGorKykge1xuICAgICAgICAgIGNvbnN0IGQgPSBkaXN0YW5jZXNbaV1bal0gLSByaG9baV07XG4gICAgICAgICAgaWYgKGQgPiAwKSB7XG4gICAgICAgICAgICBwc3VtICs9IE1hdGguZXhwKC0oZCAvIG1pZCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwc3VtICs9IDEuMDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoTWF0aC5hYnMocHN1bSAtIHRhcmdldCkgPCBTTU9PVEhfS19UT0xFUkFOQ0UpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwc3VtID4gdGFyZ2V0KSB7XG4gICAgICAgICAgaGkgPSBtaWQ7XG4gICAgICAgICAgbWlkID0gKGxvICsgaGkpIC8gMi4wO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxvID0gbWlkO1xuICAgICAgICAgIGlmIChoaSA9PT0gSW5maW5pdHkpIHtcbiAgICAgICAgICAgIG1pZCAqPSAyO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtaWQgPSAobG8gKyBoaSkgLyAyLjA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJlc3VsdFtpXSA9IG1pZDtcblxuICAgICAgLy8gVE9ETzogVGhpcyBpcyB2ZXJ5IGluZWZmaWNpZW50LCBidXQgd2lsbCBkbyBmb3Igbm93LiBGSVhNRVxuICAgICAgaWYgKHJob1tpXSA+IDAuMCkge1xuICAgICAgICBjb25zdCBtZWFuSXRoRGlzdGFuY2VzID0gdXRpbHMubWVhbihpdGhEaXN0YW5jZXMpO1xuICAgICAgICBpZiAocmVzdWx0W2ldIDwgTUlOX0tfRElTVF9TQ0FMRSAqIG1lYW5JdGhEaXN0YW5jZXMpIHtcbiAgICAgICAgICByZXN1bHRbaV0gPSBNSU5fS19ESVNUX1NDQUxFICogbWVhbkl0aERpc3RhbmNlcztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgbWVhbkRpc3RhbmNlcyA9IHV0aWxzLm1lYW4oZGlzdGFuY2VzLm1hcCh1dGlscy5tZWFuKSk7XG4gICAgICAgIGlmIChyZXN1bHRbaV0gPCBNSU5fS19ESVNUX1NDQUxFICogbWVhbkRpc3RhbmNlcykge1xuICAgICAgICAgIHJlc3VsdFtpXSA9IE1JTl9LX0RJU1RfU0NBTEUgKiBtZWFuRGlzdGFuY2VzO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgc2lnbWFzOiByZXN1bHQsIHJob3M6IHJobyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCB0aGUgbWVtYmVyc2hpcCBzdHJlbmd0aCBkYXRhIGZvciB0aGUgMS1za2VsZXRvbiBvZiBlYWNoIGxvY2FsXG4gICAqIGZ1enp5IHNpbXBsaWNpYWwgc2V0IC0tIHRoaXMgaXMgZm9ybWVkIGFzIGEgc3BhcnNlIG1hdHJpeCB3aGVyZSBlYWNoIHJvdyBpc1xuICAgKiBhIGxvY2FsIGZ1enp5IHNpbXBsaWNpYWwgc2V0LCB3aXRoIGEgbWVtYmVyc2hpcCBzdHJlbmd0aCBmb3IgdGhlXG4gICAqIDEtc2ltcGxleCB0byBlYWNoIG90aGVyIGRhdGEgcG9pbnQuXG4gICAqL1xuICBwcml2YXRlIGNvbXB1dGVNZW1iZXJzaGlwU3RyZW5ndGhzKFxuICAgIGtubkluZGljZXM6IFZlY3RvcnMsXG4gICAga25uRGlzdGFuY2VzOiBWZWN0b3JzLFxuICAgIHNpZ21hczogbnVtYmVyW10sXG4gICAgcmhvczogbnVtYmVyW11cbiAgKTogeyByb3dzOiBudW1iZXJbXTsgY29sczogbnVtYmVyW107IHZhbHM6IG51bWJlcltdIH0ge1xuICAgIGNvbnN0IG5TYW1wbGVzID0ga25uSW5kaWNlcy5sZW5ndGg7XG4gICAgY29uc3Qgbk5laWdoYm9ycyA9IGtubkluZGljZXNbMF0ubGVuZ3RoO1xuXG4gICAgY29uc3Qgcm93cyA9IHV0aWxzLnplcm9zKG5TYW1wbGVzICogbk5laWdoYm9ycyk7XG4gICAgY29uc3QgY29scyA9IHV0aWxzLnplcm9zKG5TYW1wbGVzICogbk5laWdoYm9ycyk7XG4gICAgY29uc3QgdmFscyA9IHV0aWxzLnplcm9zKG5TYW1wbGVzICogbk5laWdoYm9ycyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5TYW1wbGVzOyBpKyspIHtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbk5laWdoYm9yczsgaisrKSB7XG4gICAgICAgIGxldCB2YWwgPSAwO1xuICAgICAgICBpZiAoa25uSW5kaWNlc1tpXVtqXSA9PT0gLTEpIHtcbiAgICAgICAgICBjb250aW51ZTsgLy8gV2UgZGlkbid0IGdldCB0aGUgZnVsbCBrbm4gZm9yIGlcbiAgICAgICAgfVxuICAgICAgICBpZiAoa25uSW5kaWNlc1tpXVtqXSA9PT0gaSkge1xuICAgICAgICAgIHZhbCA9IDAuMDtcbiAgICAgICAgfSBlbHNlIGlmIChrbm5EaXN0YW5jZXNbaV1bal0gLSByaG9zW2ldIDw9IDAuMCkge1xuICAgICAgICAgIHZhbCA9IDEuMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWwgPSBNYXRoLmV4cCgtKChrbm5EaXN0YW5jZXNbaV1bal0gLSByaG9zW2ldKSAvIHNpZ21hc1tpXSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcm93c1tpICogbk5laWdoYm9ycyArIGpdID0gaTtcbiAgICAgICAgY29sc1tpICogbk5laWdoYm9ycyArIGpdID0ga25uSW5kaWNlc1tpXVtqXTtcbiAgICAgICAgdmFsc1tpICogbk5laWdoYm9ycyArIGpdID0gdmFsO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7IHJvd3MsIGNvbHMsIHZhbHMgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGEgZnV6enkgc2ltcGxpY2lhbCBzZXQgZW1iZWRkaW5nLCB1c2luZyBhIHNwZWNpZmllZFxuICAgKiBpbml0aWFsaXNhdGlvbiBtZXRob2QgYW5kIHRoZW4gbWluaW1pemluZyB0aGUgZnV6enkgc2V0IGNyb3NzIGVudHJvcHlcbiAgICogYmV0d2VlbiB0aGUgMS1za2VsZXRvbnMgb2YgdGhlIGhpZ2ggYW5kIGxvdyBkaW1lbnNpb25hbCBmdXp6eSBzaW1wbGljaWFsXG4gICAqIHNldHMuXG4gICAqL1xuICBwcml2YXRlIGluaXRpYWxpemVTaW1wbGljaWFsU2V0RW1iZWRkaW5nKCkge1xuICAgIGNvbnN0IG5FcG9jaHMgPSB0aGlzLmdldE5FcG9jaHMoKTtcblxuICAgIGNvbnN0IHsgbkNvbXBvbmVudHMgfSA9IHRoaXM7XG4gICAgY29uc3QgZ3JhcGhWYWx1ZXMgPSB0aGlzLmdyYXBoLmdldFZhbHVlcygpO1xuICAgIGxldCBncmFwaE1heCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncmFwaFZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgdmFsdWUgPSBncmFwaFZhbHVlc1tpXTtcbiAgICAgIGlmIChncmFwaE1heCA8IGdyYXBoVmFsdWVzW2ldKSB7XG4gICAgICAgIGdyYXBoTWF4ID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZ3JhcGggPSB0aGlzLmdyYXBoLm1hcCh2YWx1ZSA9PiB7XG4gICAgICBpZiAodmFsdWUgPCBncmFwaE1heCAvIG5FcG9jaHMpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBXZSdyZSBub3QgY29tcHV0aW5nIHRoZSBzcGVjdHJhbCBpbml0aWFsaXphdGlvbiBpbiB0aGlzIGltcGxlbWVudGF0aW9uXG4gICAgLy8gdW50aWwgd2UgZGV0ZXJtaW5lIGEgYmV0dGVyIGVpZ2VudmFsdWUvZWlnZW52ZWN0b3IgY29tcHV0YXRpb25cbiAgICAvLyBhcHByb2FjaFxuICAgIHRoaXMuZW1iZWRkaW5nID0gdXRpbHMuemVyb3MoZ3JhcGgublJvd3MpLm1hcCgoKSA9PiB7XG4gICAgICByZXR1cm4gdXRpbHMuemVyb3MobkNvbXBvbmVudHMpLm1hcCgoKSA9PiB7XG4gICAgICAgIHJldHVybiB1dGlscy50YXVSYW5kKHRoaXMucmFuZG9tKSAqIDIwICsgLTEwOyAvLyBSYW5kb20gZnJvbSAtMTAgdG8gMTBcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gR2V0IGdyYXBoIGRhdGEgaW4gb3JkZXJlZCB3YXkuLi5cbiAgICBjb25zdCB3ZWlnaHRzOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IGhlYWQ6IG51bWJlcltdID0gW107XG4gICAgY29uc3QgdGFpbDogbnVtYmVyW10gPSBbXTtcbiAgICBjb25zdCByb3dDb2xWYWx1ZXMgPSBncmFwaC5nZXRBbGwoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvd0NvbFZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZW50cnkgPSByb3dDb2xWYWx1ZXNbaV07XG4gICAgICBpZiAoZW50cnkudmFsdWUpIHtcbiAgICAgICAgd2VpZ2h0cy5wdXNoKGVudHJ5LnZhbHVlKTtcbiAgICAgICAgdGFpbC5wdXNoKGVudHJ5LnJvdyk7XG4gICAgICAgIGhlYWQucHVzaChlbnRyeS5jb2wpO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBlcG9jaHNQZXJTYW1wbGUgPSB0aGlzLm1ha2VFcG9jaHNQZXJTYW1wbGUod2VpZ2h0cywgbkVwb2Nocyk7XG5cbiAgICByZXR1cm4geyBoZWFkLCB0YWlsLCBlcG9jaHNQZXJTYW1wbGUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhIHNldCBvZiB3ZWlnaHRzIGFuZCBudW1iZXIgb2YgZXBvY2hzIGdlbmVyYXRlIHRoZSBudW1iZXIgb2ZcbiAgICogZXBvY2hzIHBlciBzYW1wbGUgZm9yIGVhY2ggd2VpZ2h0LlxuICAgKi9cbiAgcHJpdmF0ZSBtYWtlRXBvY2hzUGVyU2FtcGxlKHdlaWdodHM6IG51bWJlcltdLCBuRXBvY2hzOiBudW1iZXIpIHtcbiAgICBjb25zdCByZXN1bHQgPSB1dGlscy5maWxsZWQod2VpZ2h0cy5sZW5ndGgsIC0xLjApO1xuICAgIGNvbnN0IG1heCA9IHV0aWxzLm1heCh3ZWlnaHRzKTtcbiAgICBjb25zdCBuU2FtcGxlcyA9IHdlaWdodHMubWFwKHcgPT4gKHcgLyBtYXgpICogbkVwb2Nocyk7XG4gICAgblNhbXBsZXMuZm9yRWFjaCgobiwgaSkgPT4ge1xuICAgICAgaWYgKG4gPiAwKSByZXN1bHRbaV0gPSBuRXBvY2hzIC8gblNhbXBsZXNbaV07XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBc3NpZ25zIG9wdGltaXphdGlvbiBzdGF0ZSBwYXJhbWV0ZXJzIGZyb20gYSBwYXJ0aWFsIG9wdGltaXphdGlvbiBzdGF0ZS5cbiAgICovXG4gIHByaXZhdGUgYXNzaWduT3B0aW1pemF0aW9uU3RhdGVQYXJhbWV0ZXJzKHN0YXRlOiBQYXJ0aWFsPE9wdGltaXphdGlvblN0YXRlPikge1xuICAgIE9iamVjdC5hc3NpZ24odGhpcy5vcHRpbWl6YXRpb25TdGF0ZSwgc3RhdGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgYSBmZXcgb3B0aW1pemF0aW9uIHN0YXRlIHBhcmFtZXRlcnMgdGhhdCBhcmUgbmVjZXNzYXJ5IGJlZm9yZSBlbnRlcmluZ1xuICAgKiB0aGUgb3B0aW1pemF0aW9uIHN0ZXAgbG9vcC5cbiAgICovXG4gIHByaXZhdGUgcHJlcGFyZUZvck9wdGltaXphdGlvbkxvb3AoKSB7XG4gICAgLy8gSHlwZXJwYXJhbWV0ZXJzXG4gICAgY29uc3QgeyByZXB1bHNpb25TdHJlbmd0aCwgbGVhcm5pbmdSYXRlLCBuZWdhdGl2ZVNhbXBsZVJhdGUgfSA9IHRoaXM7XG5cbiAgICBjb25zdCB7XG4gICAgICBlcG9jaHNQZXJTYW1wbGUsXG4gICAgICBoZWFkRW1iZWRkaW5nLFxuICAgICAgdGFpbEVtYmVkZGluZyxcbiAgICB9ID0gdGhpcy5vcHRpbWl6YXRpb25TdGF0ZTtcblxuICAgIGNvbnN0IGRpbSA9IGhlYWRFbWJlZGRpbmdbMF0ubGVuZ3RoO1xuICAgIGNvbnN0IG1vdmVPdGhlciA9IGhlYWRFbWJlZGRpbmcubGVuZ3RoID09PSB0YWlsRW1iZWRkaW5nLmxlbmd0aDtcblxuICAgIGNvbnN0IGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlID0gZXBvY2hzUGVyU2FtcGxlLm1hcChcbiAgICAgIGUgPT4gZSAvIG5lZ2F0aXZlU2FtcGxlUmF0ZVxuICAgICk7XG4gICAgY29uc3QgZXBvY2hPZk5leHROZWdhdGl2ZVNhbXBsZSA9IFsuLi5lcG9jaHNQZXJOZWdhdGl2ZVNhbXBsZV07XG4gICAgY29uc3QgZXBvY2hPZk5leHRTYW1wbGUgPSBbLi4uZXBvY2hzUGVyU2FtcGxlXTtcblxuICAgIHRoaXMuYXNzaWduT3B0aW1pemF0aW9uU3RhdGVQYXJhbWV0ZXJzKHtcbiAgICAgIGVwb2NoT2ZOZXh0U2FtcGxlLFxuICAgICAgZXBvY2hPZk5leHROZWdhdGl2ZVNhbXBsZSxcbiAgICAgIGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlLFxuICAgICAgbW92ZU90aGVyLFxuICAgICAgaW5pdGlhbEFscGhhOiBsZWFybmluZ1JhdGUsXG4gICAgICBhbHBoYTogbGVhcm5pbmdSYXRlLFxuICAgICAgZ2FtbWE6IHJlcHVsc2lvblN0cmVuZ3RoLFxuICAgICAgZGltLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIG9wdGltaXphdGlvbiBzdGF0ZSBmb3Igc3RlcHdpc2Ugb3B0aW1pemF0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBpbml0aWFsaXplT3B0aW1pemF0aW9uKCkge1xuICAgIC8vIEFsZ29yaXRobSBzdGF0ZVxuICAgIGNvbnN0IGhlYWRFbWJlZGRpbmcgPSB0aGlzLmVtYmVkZGluZztcbiAgICBjb25zdCB0YWlsRW1iZWRkaW5nID0gdGhpcy5lbWJlZGRpbmc7XG5cbiAgICAvLyBJbml0aWFsaXplZCBpbiBpbml0aWFsaXplU2ltcGxpY2lhbFNldEVtYmVkZGluZygpXG4gICAgY29uc3QgeyBoZWFkLCB0YWlsLCBlcG9jaHNQZXJTYW1wbGUgfSA9IHRoaXMub3B0aW1pemF0aW9uU3RhdGU7XG5cbiAgICBjb25zdCBuRXBvY2hzID0gdGhpcy5nZXRORXBvY2hzKCk7XG4gICAgY29uc3QgblZlcnRpY2VzID0gdGhpcy5ncmFwaC5uQ29scztcblxuICAgIGNvbnN0IHsgYSwgYiB9ID0gZmluZEFCUGFyYW1zKHRoaXMuc3ByZWFkLCB0aGlzLm1pbkRpc3QpO1xuXG4gICAgdGhpcy5hc3NpZ25PcHRpbWl6YXRpb25TdGF0ZVBhcmFtZXRlcnMoe1xuICAgICAgaGVhZEVtYmVkZGluZyxcbiAgICAgIHRhaWxFbWJlZGRpbmcsXG4gICAgICBoZWFkLFxuICAgICAgdGFpbCxcbiAgICAgIGVwb2Noc1BlclNhbXBsZSxcbiAgICAgIGEsXG4gICAgICBiLFxuICAgICAgbkVwb2NocyxcbiAgICAgIG5WZXJ0aWNlcyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbXByb3ZlIGFuIGVtYmVkZGluZyB1c2luZyBzdG9jaGFzdGljIGdyYWRpZW50IGRlc2NlbnQgdG8gbWluaW1pemUgdGhlXG4gICAqIGZ1enp5IHNldCBjcm9zcyBlbnRyb3B5IGJldHdlZW4gdGhlIDEtc2tlbGV0b25zIG9mIHRoZSBoaWdoIGRpbWVuc2lvbmFsXG4gICAqIGFuZCBsb3cgZGltZW5zaW9uYWwgZnV6enkgc2ltcGxpY2lhbCBzZXRzLiBJbiBwcmFjdGljZSB0aGlzIGlzIGRvbmUgYnlcbiAgICogc2FtcGxpbmcgZWRnZXMgYmFzZWQgb24gdGhlaXIgbWVtYmVyc2hpcCBzdHJlbmd0aCAod2l0aCB0aGUgKDEtcCkgdGVybXNcbiAgICogY29taW5nIGZyb20gbmVnYXRpdmUgc2FtcGxpbmcgc2ltaWxhciB0byB3b3JkMnZlYykuXG4gICAqL1xuICBwcml2YXRlIG9wdGltaXplTGF5b3V0U3RlcChuOiBudW1iZXIpIHtcbiAgICBjb25zdCB7IG9wdGltaXphdGlvblN0YXRlIH0gPSB0aGlzO1xuICAgIGNvbnN0IHtcbiAgICAgIGhlYWQsXG4gICAgICB0YWlsLFxuICAgICAgaGVhZEVtYmVkZGluZyxcbiAgICAgIHRhaWxFbWJlZGRpbmcsXG4gICAgICBlcG9jaHNQZXJTYW1wbGUsXG4gICAgICBlcG9jaE9mTmV4dFNhbXBsZSxcbiAgICAgIGVwb2NoT2ZOZXh0TmVnYXRpdmVTYW1wbGUsXG4gICAgICBlcG9jaHNQZXJOZWdhdGl2ZVNhbXBsZSxcbiAgICAgIG1vdmVPdGhlcixcbiAgICAgIGluaXRpYWxBbHBoYSxcbiAgICAgIGFscGhhLFxuICAgICAgZ2FtbWEsXG4gICAgICBhLFxuICAgICAgYixcbiAgICAgIGRpbSxcbiAgICAgIG5FcG9jaHMsXG4gICAgICBuVmVydGljZXMsXG4gICAgfSA9IG9wdGltaXphdGlvblN0YXRlO1xuXG4gICAgY29uc3QgY2xpcFZhbHVlID0gNC4wO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlcG9jaHNQZXJTYW1wbGUubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChlcG9jaE9mTmV4dFNhbXBsZVtpXSA+IG4pIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGogPSBoZWFkW2ldO1xuICAgICAgY29uc3QgayA9IHRhaWxbaV07XG5cbiAgICAgIGNvbnN0IGN1cnJlbnQgPSBoZWFkRW1iZWRkaW5nW2pdO1xuICAgICAgY29uc3Qgb3RoZXIgPSB0YWlsRW1iZWRkaW5nW2tdO1xuXG4gICAgICBjb25zdCBkaXN0U3F1YXJlZCA9IHJEaXN0KGN1cnJlbnQsIG90aGVyKTtcblxuICAgICAgbGV0IGdyYWRDb2VmZiA9IDA7XG4gICAgICBpZiAoZGlzdFNxdWFyZWQgPiAwKSB7XG4gICAgICAgIGdyYWRDb2VmZiA9IC0yLjAgKiBhICogYiAqIE1hdGgucG93KGRpc3RTcXVhcmVkLCBiIC0gMS4wKTtcbiAgICAgICAgZ3JhZENvZWZmIC89IGEgKiBNYXRoLnBvdyhkaXN0U3F1YXJlZCwgYikgKyAxLjA7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGQgPSAwOyBkIDwgZGltOyBkKyspIHtcbiAgICAgICAgY29uc3QgZ3JhZEQgPSBjbGlwKGdyYWRDb2VmZiAqIChjdXJyZW50W2RdIC0gb3RoZXJbZF0pLCBjbGlwVmFsdWUpO1xuICAgICAgICBjdXJyZW50W2RdICs9IGdyYWREICogYWxwaGE7XG4gICAgICAgIGlmIChtb3ZlT3RoZXIpIHtcbiAgICAgICAgICBvdGhlcltkXSArPSAtZ3JhZEQgKiBhbHBoYTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBlcG9jaE9mTmV4dFNhbXBsZVtpXSArPSBlcG9jaHNQZXJTYW1wbGVbaV07XG5cbiAgICAgIGNvbnN0IG5OZWdTYW1wbGVzID0gTWF0aC5mbG9vcihcbiAgICAgICAgKG4gLSBlcG9jaE9mTmV4dE5lZ2F0aXZlU2FtcGxlW2ldKSAvIGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlW2ldXG4gICAgICApO1xuXG4gICAgICBmb3IgKGxldCBwID0gMDsgcCA8IG5OZWdTYW1wbGVzOyBwKyspIHtcbiAgICAgICAgY29uc3QgayA9IHV0aWxzLnRhdVJhbmRJbnQoblZlcnRpY2VzLCB0aGlzLnJhbmRvbSk7XG4gICAgICAgIGNvbnN0IG90aGVyID0gdGFpbEVtYmVkZGluZ1trXTtcblxuICAgICAgICBjb25zdCBkaXN0U3F1YXJlZCA9IHJEaXN0KGN1cnJlbnQsIG90aGVyKTtcblxuICAgICAgICBsZXQgZ3JhZENvZWZmID0gMC4wO1xuICAgICAgICBpZiAoZGlzdFNxdWFyZWQgPiAwLjApIHtcbiAgICAgICAgICBncmFkQ29lZmYgPSAyLjAgKiBnYW1tYSAqIGI7XG4gICAgICAgICAgZ3JhZENvZWZmIC89XG4gICAgICAgICAgICAoMC4wMDEgKyBkaXN0U3F1YXJlZCkgKiAoYSAqIE1hdGgucG93KGRpc3RTcXVhcmVkLCBiKSArIDEpO1xuICAgICAgICB9IGVsc2UgaWYgKGogPT09IGspIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAobGV0IGQgPSAwOyBkIDwgZGltOyBkKyspIHtcbiAgICAgICAgICBsZXQgZ3JhZEQgPSA0LjA7XG4gICAgICAgICAgaWYgKGdyYWRDb2VmZiA+IDAuMCkge1xuICAgICAgICAgICAgZ3JhZEQgPSBjbGlwKGdyYWRDb2VmZiAqIChjdXJyZW50W2RdIC0gb3RoZXJbZF0pLCBjbGlwVmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjdXJyZW50W2RdICs9IGdyYWREICogYWxwaGE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVwb2NoT2ZOZXh0TmVnYXRpdmVTYW1wbGVbaV0gKz0gbk5lZ1NhbXBsZXMgKiBlcG9jaHNQZXJOZWdhdGl2ZVNhbXBsZVtpXTtcbiAgICB9XG4gICAgb3B0aW1pemF0aW9uU3RhdGUuYWxwaGEgPSBpbml0aWFsQWxwaGEgKiAoMS4wIC0gbiAvIG5FcG9jaHMpO1xuXG4gICAgb3B0aW1pemF0aW9uU3RhdGUuY3VycmVudEVwb2NoICs9IDE7XG4gICAgcmV0dXJuIGhlYWRFbWJlZGRpbmc7XG4gIH1cblxuICAvKipcbiAgICogSW1wcm92ZSBhbiBlbWJlZGRpbmcgdXNpbmcgc3RvY2hhc3RpYyBncmFkaWVudCBkZXNjZW50IHRvIG1pbmltaXplIHRoZVxuICAgKiBmdXp6eSBzZXQgY3Jvc3MgZW50cm9weSBiZXR3ZWVuIHRoZSAxLXNrZWxldG9ucyBvZiB0aGUgaGlnaCBkaW1lbnNpb25hbFxuICAgKiBhbmQgbG93IGRpbWVuc2lvbmFsIGZ1enp5IHNpbXBsaWNpYWwgc2V0cy4gSW4gcHJhY3RpY2UgdGhpcyBpcyBkb25lIGJ5XG4gICAqIHNhbXBsaW5nIGVkZ2VzIGJhc2VkIG9uIHRoZWlyIG1lbWJlcnNoaXAgc3RyZW5ndGggKHdpdGggdGhlICgxLXApIHRlcm1zXG4gICAqIGNvbWluZyBmcm9tIG5lZ2F0aXZlIHNhbXBsaW5nIHNpbWlsYXIgdG8gd29yZDJ2ZWMpLlxuICAgKi9cbiAgcHJpdmF0ZSBvcHRpbWl6ZUxheW91dEFzeW5jKFxuICAgIGVwb2NoQ2FsbGJhY2s6IChlcG9jaE51bWJlcjogbnVtYmVyKSA9PiB2b2lkIHwgYm9vbGVhbiA9ICgpID0+IHRydWVcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHN0ZXAgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgeyBuRXBvY2hzLCBjdXJyZW50RXBvY2ggfSA9IHRoaXMub3B0aW1pemF0aW9uU3RhdGU7XG4gICAgICAgICAgdGhpcy5lbWJlZGRpbmcgPSB0aGlzLm9wdGltaXplTGF5b3V0U3RlcChjdXJyZW50RXBvY2gpO1xuICAgICAgICAgIGNvbnN0IGVwb2NoQ29tcGxldGVkID0gdGhpcy5vcHRpbWl6YXRpb25TdGF0ZS5jdXJyZW50RXBvY2g7XG4gICAgICAgICAgY29uc3Qgc2hvdWxkU3RvcCA9IGVwb2NoQ2FsbGJhY2soZXBvY2hDb21wbGV0ZWQpID09PSBmYWxzZTtcbiAgICAgICAgICBjb25zdCBpc0ZpbmlzaGVkID0gZXBvY2hDb21wbGV0ZWQgPT09IG5FcG9jaHM7XG4gICAgICAgICAgaWYgKCFzaG91bGRTdG9wICYmICFpc0ZpbmlzaGVkKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHN0ZXAoKSwgMCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGlzRmluaXNoZWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHN0ZXAoKSwgMCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW1wcm92ZSBhbiBlbWJlZGRpbmcgdXNpbmcgc3RvY2hhc3RpYyBncmFkaWVudCBkZXNjZW50IHRvIG1pbmltaXplIHRoZVxuICAgKiBmdXp6eSBzZXQgY3Jvc3MgZW50cm9weSBiZXR3ZWVuIHRoZSAxLXNrZWxldG9ucyBvZiB0aGUgaGlnaCBkaW1lbnNpb25hbFxuICAgKiBhbmQgbG93IGRpbWVuc2lvbmFsIGZ1enp5IHNpbXBsaWNpYWwgc2V0cy4gSW4gcHJhY3RpY2UgdGhpcyBpcyBkb25lIGJ5XG4gICAqIHNhbXBsaW5nIGVkZ2VzIGJhc2VkIG9uIHRoZWlyIG1lbWJlcnNoaXAgc3RyZW5ndGggKHdpdGggdGhlICgxLXApIHRlcm1zXG4gICAqIGNvbWluZyBmcm9tIG5lZ2F0aXZlIHNhbXBsaW5nIHNpbWlsYXIgdG8gd29yZDJ2ZWMpLlxuICAgKi9cbiAgcHJpdmF0ZSBvcHRpbWl6ZUxheW91dChcbiAgICBlcG9jaENhbGxiYWNrOiAoZXBvY2hOdW1iZXI6IG51bWJlcikgPT4gdm9pZCB8IGJvb2xlYW4gPSAoKSA9PiB0cnVlXG4gICk6IFZlY3RvcnMge1xuICAgIGxldCBpc0ZpbmlzaGVkID0gZmFsc2U7XG4gICAgbGV0IGVtYmVkZGluZzogVmVjdG9ycyA9IFtdO1xuICAgIHdoaWxlICghaXNGaW5pc2hlZCkge1xuICAgICAgY29uc3QgeyBuRXBvY2hzLCBjdXJyZW50RXBvY2ggfSA9IHRoaXMub3B0aW1pemF0aW9uU3RhdGU7XG4gICAgICBlbWJlZGRpbmcgPSB0aGlzLm9wdGltaXplTGF5b3V0U3RlcChjdXJyZW50RXBvY2gpO1xuICAgICAgY29uc3QgZXBvY2hDb21wbGV0ZWQgPSB0aGlzLm9wdGltaXphdGlvblN0YXRlLmN1cnJlbnRFcG9jaDtcbiAgICAgIGNvbnN0IHNob3VsZFN0b3AgPSBlcG9jaENhbGxiYWNrKGVwb2NoQ29tcGxldGVkKSA9PT0gZmFsc2U7XG4gICAgICBpc0ZpbmlzaGVkID0gZXBvY2hDb21wbGV0ZWQgPT09IG5FcG9jaHMgfHwgc2hvdWxkU3RvcDtcbiAgICB9XG4gICAgcmV0dXJuIGVtYmVkZGluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgZXBvY2hzIGZvciBvcHRpbWl6aW5nIHRoZSBwcm9qZWN0aW9uLlxuICAgKiBOT1RFOiBUaGlzIGhldXJpc3RpYyBkaWZmZXJzIGZyb20gdGhlIHB5dGhvbiB2ZXJzaW9uXG4gICAqL1xuICBwdWJsaWMgZ2V0TkVwb2NocygpIHtcbiAgICBjb25zdCBncmFwaCA9IHRoaXMuZ3JhcGg7XG5cbiAgICBpZiAodGhpcy5uRXBvY2hzID4gMCkge1xuICAgICAgcmV0dXJuIHRoaXMubkVwb2NocztcbiAgICB9XG5cbiAgICBpZiAoIWdyYXBoKSB7XG4gICAgICByZXR1cm4gMjAwO1xuICAgIH1cblxuICAgIGNvbnN0IGxlbmd0aCA9IGdyYXBoLm5Sb3dzO1xuICAgIGlmIChsZW5ndGggPD0gMjUwMCkge1xuICAgICAgcmV0dXJuIDUwMDtcbiAgICB9IGVsc2UgaWYgKGxlbmd0aCA8PSA1MDAwKSB7XG4gICAgICByZXR1cm4gNDAwO1xuICAgIH0gZWxzZSBpZiAobGVuZ3RoIDw9IDc1MDApIHtcbiAgICAgIHJldHVybiAzMDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAyMDA7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBldWNsaWRlYW4oeDogVmVjdG9yLCB5OiBWZWN0b3IpIHtcbiAgbGV0IHJlc3VsdCA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkrKykge1xuICAgIHJlc3VsdCArPSAoeFtpXSAtIHlbaV0pICoqIDI7XG4gIH1cbiAgcmV0dXJuIE1hdGguc3FydChyZXN1bHQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbnVtZXJpYyh4OiBudW1iZXIsIHk6IG51bWJlcikge1xuICBjb25zdCByZXN1bHQgPSBNYXRoLmFicyh4IC0geSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb3NpbmUoeDogVmVjdG9yLCB5OiBWZWN0b3IpIHtcbiAgbGV0IHJlc3VsdCA9IDAuMDtcbiAgbGV0IG5vcm1YID0gMC4wO1xuICBsZXQgbm9ybVkgPSAwLjA7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSsrKSB7XG4gICAgcmVzdWx0ICs9IHhbaV0gKiB5W2ldO1xuICAgIG5vcm1YICs9IHhbaV0gKiogMjtcbiAgICBub3JtWSArPSB5W2ldICoqIDI7XG4gIH1cblxuICBpZiAobm9ybVggPT09IDAgJiYgbm9ybVkgPT09IDApIHtcbiAgICByZXR1cm4gMDtcbiAgfSBlbHNlIGlmIChub3JtWCA9PT0gMCB8fCBub3JtWSA9PT0gMCkge1xuICAgIHJldHVybiAxLjA7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIDEuMCAtIHJlc3VsdCAvIE1hdGguc3FydChub3JtWCAqIG5vcm1ZKTtcbiAgfVxufVxuXG4vKipcbiAqIEFuIGludGVyZmFjZSByZXByZXNlbnRpbmcgdGhlIG9wdGltaXphdGlvbiBzdGF0ZSB0cmFja2VkIGJldHdlZW4gc3RlcHMgb2ZcbiAqIHRoZSBTR0Qgb3B0aW1pemF0aW9uXG4gKi9cbmNsYXNzIE9wdGltaXphdGlvblN0YXRlIHtcbiAgY3VycmVudEVwb2NoID0gMDtcblxuICAvLyBEYXRhIHRyYWNrZWQgZHVyaW5nIG9wdGltaXphdGlvbiBzdGVwcy5cbiAgaGVhZEVtYmVkZGluZzogbnVtYmVyW11bXSA9IFtdO1xuICB0YWlsRW1iZWRkaW5nOiBudW1iZXJbXVtdID0gW107XG4gIGhlYWQ6IG51bWJlcltdID0gW107XG4gIHRhaWw6IG51bWJlcltdID0gW107XG4gIGVwb2Noc1BlclNhbXBsZTogbnVtYmVyW10gPSBbXTtcbiAgZXBvY2hPZk5leHRTYW1wbGU6IG51bWJlcltdID0gW107XG4gIGVwb2NoT2ZOZXh0TmVnYXRpdmVTYW1wbGU6IG51bWJlcltdID0gW107XG4gIGVwb2Noc1Blck5lZ2F0aXZlU2FtcGxlOiBudW1iZXJbXSA9IFtdO1xuICBtb3ZlT3RoZXIgPSB0cnVlO1xuICBpbml0aWFsQWxwaGEgPSAxLjA7XG4gIGFscGhhID0gMS4wO1xuICBnYW1tYSA9IDEuMDtcbiAgYSA9IDEuNTc2OTQzNDYwMzExMzA3NztcbiAgYiA9IDAuODk1MDYwODc3OTEwOTczMztcbiAgZGltID0gMjtcbiAgbkVwb2NocyA9IDUwMDtcbiAgblZlcnRpY2VzID0gMDtcbn1cblxuLyoqXG4gKiBTdGFuZGFyZCBjbGFtcGluZyBvZiBhIHZhbHVlIGludG8gYSBmaXhlZCByYW5nZVxuICovXG5mdW5jdGlvbiBjbGlwKHg6IG51bWJlciwgY2xpcFZhbHVlOiBudW1iZXIpIHtcbiAgaWYgKHggPiBjbGlwVmFsdWUpIHJldHVybiBjbGlwVmFsdWU7XG4gIGVsc2UgaWYgKHggPCAtY2xpcFZhbHVlKSByZXR1cm4gLWNsaXBWYWx1ZTtcbiAgZWxzZSByZXR1cm4geDtcbn1cblxuLyoqXG4gKiBSZWR1Y2VkIEV1Y2xpZGVhbiBkaXN0YW5jZS5cbiAqL1xuZnVuY3Rpb24gckRpc3QoeDogbnVtYmVyW10sIHk6IG51bWJlcltdKSB7XG4gIGxldCByZXN1bHQgPSAwLjA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkrKykge1xuICAgIHJlc3VsdCArPSBNYXRoLnBvdyh4W2ldIC0geVtpXSwgMik7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBGaXQgYSwgYiBwYXJhbXMgZm9yIHRoZSBkaWZmZXJlbnRpYWJsZSBjdXJ2ZSB1c2VkIGluIGxvd2VyXG4gKiBkaW1lbnNpb25hbCBmdXp6eSBzaW1wbGljaWFsIGNvbXBsZXggY29uc3RydWN0aW9uLiBXZSB3YW50IHRoZVxuICogc21vb3RoIGN1cnZlIChmcm9tIGEgcHJlLWRlZmluZWQgZmFtaWx5IHdpdGggc2ltcGxlIGdyYWRpZW50KSB0aGF0XG4gKiBiZXN0IG1hdGNoZXMgYW4gb2Zmc2V0IGV4cG9uZW50aWFsIGRlY2F5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZEFCUGFyYW1zKHNwcmVhZDogbnVtYmVyLCBtaW5EaXN0OiBudW1iZXIpIHtcbiAgY29uc3QgY3VydmUgPSAoW2EsIGJdOiBudW1iZXJbXSkgPT4gKHg6IG51bWJlcikgPT4ge1xuICAgIHJldHVybiAxLjAgLyAoMS4wICsgYSAqIHggKiogKDIgKiBiKSk7XG4gIH07XG5cbiAgY29uc3QgeHYgPSB1dGlsc1xuICAgIC5saW5lYXIoMCwgc3ByZWFkICogMywgMzAwKVxuICAgIC5tYXAodmFsID0+ICh2YWwgPCBtaW5EaXN0ID8gMS4wIDogdmFsKSk7XG5cbiAgY29uc3QgeXYgPSB1dGlscy56ZXJvcyh4di5sZW5ndGgpLm1hcCgodmFsLCBpbmRleCkgPT4ge1xuICAgIGNvbnN0IGd0ZSA9IHh2W2luZGV4XSA+PSBtaW5EaXN0O1xuICAgIHJldHVybiBndGUgPyBNYXRoLmV4cCgtKHh2W2luZGV4XSAtIG1pbkRpc3QpIC8gc3ByZWFkKSA6IHZhbDtcbiAgfSk7XG5cbiAgY29uc3QgaW5pdGlhbFZhbHVlcyA9IFswLjUsIDAuNV07XG4gIGNvbnN0IGRhdGEgPSB7IHg6IHh2LCB5OiB5diB9O1xuXG4gIC8vIERlZmF1bHQgb3B0aW9ucyBmb3IgdGhlIGFsZ29yaXRobSAoZnJvbSBnaXRodWIgZXhhbXBsZSlcbiAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICBkYW1waW5nOiAxLjUsXG4gICAgaW5pdGlhbFZhbHVlcyxcbiAgICBncmFkaWVudERpZmZlcmVuY2U6IDEwZS0yLFxuICAgIG1heEl0ZXJhdGlvbnM6IDEwMCxcbiAgICBlcnJvclRvbGVyYW5jZTogMTBlLTMsXG4gIH07XG5cbiAgY29uc3QgeyBwYXJhbWV0ZXJWYWx1ZXMgfSA9IExNKGRhdGEsIGN1cnZlLCBvcHRpb25zKTtcbiAgY29uc3QgW2EsIGJdID0gcGFyYW1ldGVyVmFsdWVzIGFzIG51bWJlcltdO1xuICByZXR1cm4geyBhLCBiIH07XG59XG5cbi8qKlxuICogVW5kZXIgdGhlIGFzc3VtcHRpb24gb2YgY2F0ZWdvcmljYWwgZGlzdGFuY2UgZm9yIHRoZSBpbnRlcnNlY3RpbmdcbiAqIHNpbXBsaWNpYWwgc2V0IHBlcmZvcm0gYSBmYXN0IGludGVyc2VjdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZhc3RJbnRlcnNlY3Rpb24oXG4gIGdyYXBoOiBtYXRyaXguU3BhcnNlTWF0cml4LFxuICB0YXJnZXQ6IG51bWJlcltdLFxuICB1bmtub3duRGlzdCA9IDEuMCxcbiAgZmFyRGlzdCA9IDUuMFxuKSB7XG4gIHJldHVybiBncmFwaC5tYXAoKHZhbHVlLCByb3csIGNvbCkgPT4ge1xuICAgIGlmICh0YXJnZXRbcm93XSA9PT0gLTEgfHwgdGFyZ2V0W2NvbF0gPT09IC0xKSB7XG4gICAgICByZXR1cm4gdmFsdWUgKiBNYXRoLmV4cCgtdW5rbm93bkRpc3QpO1xuICAgIH0gZWxzZSBpZiAodGFyZ2V0W3Jvd10gIT09IHRhcmdldFtjb2xdKSB7XG4gICAgICByZXR1cm4gdmFsdWUgKiBNYXRoLmV4cCgtZmFyRGlzdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gIH0pO1xufVxuXG4vKipcbiAqIFJlc2V0IHRoZSBsb2NhbCBjb25uZWN0aXZpdHkgcmVxdWlyZW1lbnQgLS0gZWFjaCBkYXRhIHNhbXBsZSBzaG91bGRcbiAqIGhhdmUgY29tcGxldGUgY29uZmlkZW5jZSBpbiBhdCBsZWFzdCBvbmUgMS1zaW1wbGV4IGluIHRoZSBzaW1wbGljaWFsIHNldC5cbiAqIFdlIGNhbiBlbmZvcmNlIHRoaXMgYnkgbG9jYWxseSByZXNjYWxpbmcgY29uZmlkZW5jZXMsIGFuZCB0aGVuIHJlbWVyZ2luZyB0aGVcbiAqIGRpZmZlcmVudCBsb2NhbCBzaW1wbGljaWFsIHNldHMgdG9nZXRoZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNldExvY2FsQ29ubmVjdGl2aXR5KHNpbXBsaWNpYWxTZXQ6IG1hdHJpeC5TcGFyc2VNYXRyaXgpIHtcbiAgc2ltcGxpY2lhbFNldCA9IG1hdHJpeC5ub3JtYWxpemUoc2ltcGxpY2lhbFNldCwgbWF0cml4Lk5vcm1UeXBlLm1heCk7XG4gIGNvbnN0IHRyYW5zcG9zZSA9IG1hdHJpeC50cmFuc3Bvc2Uoc2ltcGxpY2lhbFNldCk7XG4gIGNvbnN0IHByb2RNYXRyaXggPSBtYXRyaXgucGFpcndpc2VNdWx0aXBseSh0cmFuc3Bvc2UsIHNpbXBsaWNpYWxTZXQpO1xuICBzaW1wbGljaWFsU2V0ID0gbWF0cml4LmFkZChcbiAgICBzaW1wbGljaWFsU2V0LFxuICAgIG1hdHJpeC5zdWJ0cmFjdCh0cmFuc3Bvc2UsIHByb2RNYXRyaXgpXG4gICk7XG4gIHJldHVybiBtYXRyaXguZWxpbWluYXRlWmVyb3Moc2ltcGxpY2lhbFNldCk7XG59XG5cbi8qKlxuICogR2l2ZW4gaW5kaWNlcyBhbmQgd2VpZ2h0cyBhbmQgYW4gb3JpZ2luYWwgZW1iZWRkaW5nc1xuICogaW5pdGlhbGl6ZSB0aGUgcG9zaXRpb25zIG9mIG5ldyBwb2ludHMgcmVsYXRpdmUgdG8gdGhlXG4gKiBpbmRpY2VzIGFuZCB3ZWlnaHRzIChvZiB0aGVpciBuZWlnaGJvcnMgaW4gdGhlIHNvdXJjZSBkYXRhKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluaXRUcmFuc2Zvcm0oXG4gIGluZGljZXM6IG51bWJlcltdW10sXG4gIHdlaWdodHM6IG51bWJlcltdW10sXG4gIGVtYmVkZGluZzogVmVjdG9yc1xuKSB7XG4gIGNvbnN0IHJlc3VsdCA9IHV0aWxzXG4gICAgLnplcm9zKGluZGljZXMubGVuZ3RoKVxuICAgIC5tYXAoeiA9PiB1dGlscy56ZXJvcyhlbWJlZGRpbmdbMF0ubGVuZ3RoKSk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbmRpY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbmRpY2VzWzBdLmxlbmd0aDsgaisrKSB7XG4gICAgICBmb3IgKGxldCBkID0gMDsgZCA8IGVtYmVkZGluZ1swXS5sZW5ndGg7IGQrKykge1xuICAgICAgICBjb25zdCBhID0gaW5kaWNlc1tpXVtqXTtcbiAgICAgICAgcmVzdWx0W2ldW2RdICs9IHdlaWdodHNbaV1bal0gKiBlbWJlZGRpbmdbYV1bZF07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG4iXX0=","/**\n * @license\n *\n * Copyright 2019 Google LLC. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ==============================================================================\n */\n/**\n * This is a JavaScript reimplementation of UMAP (original license below), from\n * the python implementation found at https://github.com/lmcinnes/umap.\n *\n * @author andycoenen@google.com (Andy Coenen)\n */\n/**\n * @license\n * BSD 3-Clause License\n *\n * Copyright (c) 2017, Leland McInnes\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * * Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n *\n * * Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * * Neither the name of the copyright holder nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport * as heap from './heap';\nimport * as matrix from './matrix';\nimport * as tree from './tree';\nimport * as utils from './utils';\n/**\n * Create a version of nearest neighbor descent.\n */\nexport function makeNNDescent(distanceFn, random) {\n return function nNDescent(data, leafArray, nNeighbors, nIters = 10, maxCandidates = 50, delta = 0.001, rho = 0.5, rpTreeInit = true) {\n const nVertices = data.length;\n const currentGraph = heap.makeHeap(data.length, nNeighbors);\n for (let i = 0; i < data.length; i++) {\n const indices = heap.rejectionSample(nNeighbors, data.length, random);\n for (let j = 0; j < indices.length; j++) {\n const d = distanceFn(data[i], data[indices[j]]);\n heap.heapPush(currentGraph, i, d, indices[j], 1);\n heap.heapPush(currentGraph, indices[j], d, i, 1);\n }\n }\n if (rpTreeInit) {\n for (let n = 0; n < leafArray.length; n++) {\n for (let i = 0; i < leafArray[n].length; i++) {\n if (leafArray[n][i] < 0) {\n break;\n }\n for (let j = i + 1; j < leafArray[n].length; j++) {\n if (leafArray[n][j] < 0) {\n break;\n }\n const d = distanceFn(data[leafArray[n][i]], data[leafArray[n][j]]);\n heap.heapPush(currentGraph, leafArray[n][i], d, leafArray[n][j], 1);\n heap.heapPush(currentGraph, leafArray[n][j], d, leafArray[n][i], 1);\n }\n }\n }\n }\n for (let n = 0; n < nIters; n++) {\n const candidateNeighbors = heap.buildCandidates(currentGraph, nVertices, nNeighbors, maxCandidates, random);\n let c = 0;\n for (let i = 0; i < nVertices; i++) {\n for (let j = 0; j < maxCandidates; j++) {\n let p = Math.floor(candidateNeighbors[0][i][j]);\n if (p < 0 || utils.tauRand(random) < rho) {\n continue;\n }\n for (let k = 0; k < maxCandidates; k++) {\n const q = Math.floor(candidateNeighbors[0][i][k]);\n const cj = candidateNeighbors[2][i][j];\n const ck = candidateNeighbors[2][i][k];\n if (q < 0 || (!cj && !ck)) {\n continue;\n }\n const d = distanceFn(data[p], data[q]);\n c += heap.heapPush(currentGraph, p, d, q, 1);\n c += heap.heapPush(currentGraph, q, d, p, 1);\n }\n }\n }\n if (c <= delta * nNeighbors * data.length) {\n break;\n }\n }\n const sorted = heap.deheapSort(currentGraph);\n return sorted;\n };\n}\nexport function makeInitializations(distanceFn) {\n function initFromRandom(nNeighbors, data, queryPoints, _heap, random) {\n for (let i = 0; i < queryPoints.length; i++) {\n const indices = utils.rejectionSample(nNeighbors, data.length, random);\n for (let j = 0; j < indices.length; j++) {\n if (indices[j] < 0) {\n continue;\n }\n const d = distanceFn(data[indices[j]], queryPoints[i]);\n heap.heapPush(_heap, i, d, indices[j], 1);\n }\n }\n }\n function initFromTree(_tree, data, queryPoints, _heap, random) {\n for (let i = 0; i < queryPoints.length; i++) {\n const indices = tree.searchFlatTree(queryPoints[i], _tree, random);\n for (let j = 0; j < indices.length; j++) {\n if (indices[j] < 0) {\n return;\n }\n const d = distanceFn(data[indices[j]], queryPoints[i]);\n heap.heapPush(_heap, i, d, indices[j], 1);\n }\n }\n return;\n }\n return { initFromRandom, initFromTree };\n}\nexport function makeInitializedNNSearch(distanceFn) {\n return function nnSearchFn(data, graph, initialization, queryPoints) {\n const { indices, indptr } = matrix.getCSR(graph);\n for (let i = 0; i < queryPoints.length; i++) {\n const tried = new Set(initialization[0][i]);\n while (true) {\n // Find smallest flagged vertex\n const vertex = heap.smallestFlagged(initialization, i);\n if (vertex === -1) {\n break;\n }\n const candidates = indices.slice(indptr[vertex], indptr[vertex + 1]);\n for (const candidate of candidates) {\n if (candidate === vertex ||\n candidate === -1 ||\n tried.has(candidate)) {\n continue;\n }\n const d = distanceFn(data[candidate], queryPoints[i]);\n heap.uncheckedHeapPush(initialization, i, d, candidate, 1);\n tried.add(candidate);\n }\n }\n }\n return initialization;\n };\n}\nexport function initializeSearch(forest, data, queryPoints, nNeighbors, initFromRandom, initFromTree, random) {\n const results = heap.makeHeap(queryPoints.length, nNeighbors);\n initFromRandom(nNeighbors, data, queryPoints, results, random);\n if (forest) {\n for (let tree of forest) {\n initFromTree(tree, data, queryPoints, results, random);\n }\n }\n return results;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm5fZGVzY2VudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm5uX2Rlc2NlbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBRUg7Ozs7O0dBS0c7QUFFSDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStCRztBQUVILE9BQU8sS0FBSyxJQUFJLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxNQUFNLE1BQU0sVUFBVSxDQUFDO0FBQ25DLE9BQU8sS0FBSyxJQUFJLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sS0FBSyxLQUFLLE1BQU0sU0FBUyxDQUFDO0FBR2pDOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxVQUFzQixFQUFFLE1BQWdCO0lBQ3BFLE9BQU8sU0FBUyxTQUFTLENBQ3ZCLElBQVksRUFDWixTQUFrQixFQUNsQixVQUFrQixFQUNsQixNQUFNLEdBQUcsRUFBRSxFQUNYLGFBQWEsR0FBRyxFQUFFLEVBQ2xCLEtBQUssR0FBRyxLQUFLLEVBQ2IsR0FBRyxHQUFHLEdBQUcsRUFDVCxVQUFVLEdBQUcsSUFBSTtRQUVqQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzlCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztRQUU1RCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNwQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3RFLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO2dCQUN2QyxNQUFNLENBQUMsR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUVoRCxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDakQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7YUFDbEQ7U0FDRjtRQUNELElBQUksVUFBVSxFQUFFO1lBQ2QsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQ3pDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO29CQUM1QyxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUU7d0JBQ3ZCLE1BQU07cUJBQ1A7b0JBQ0QsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO3dCQUNoRCxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUU7NEJBQ3ZCLE1BQU07eUJBQ1A7d0JBQ0QsTUFBTSxDQUFDLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFDbkUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7d0JBQ3BFLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO3FCQUNyRTtpQkFDRjthQUNGO1NBQ0Y7UUFFRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQy9CLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FDN0MsWUFBWSxFQUNaLFNBQVMsRUFDVCxVQUFVLEVBQ1YsYUFBYSxFQUNiLE1BQU0sQ0FDUCxDQUFDO1lBRUYsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ1YsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDbEMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGFBQWEsRUFBRSxDQUFDLEVBQUUsRUFBRTtvQkFDdEMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNoRCxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxHQUFHLEVBQUU7d0JBQ3hDLFNBQVM7cUJBQ1Y7b0JBQ0QsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGFBQWEsRUFBRSxDQUFDLEVBQUUsRUFBRTt3QkFDdEMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUNsRCxNQUFNLEVBQUUsR0FBRyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFDdkMsTUFBTSxFQUFFLEdBQUcsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQ3ZDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUU7NEJBQ3pCLFNBQVM7eUJBQ1Y7d0JBRUQsTUFBTSxDQUFDLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFDdkMsQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO3dCQUM3QyxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7cUJBQzlDO2lCQUNGO2FBQ0Y7WUFDRCxJQUFJLENBQUMsSUFBSSxLQUFLLEdBQUcsVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUU7Z0JBQ3pDLE1BQU07YUFDUDtTQUNGO1FBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM3QyxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDLENBQUM7QUFDSixDQUFDO0FBa0JELE1BQU0sVUFBVSxtQkFBbUIsQ0FBQyxVQUFzQjtJQUN4RCxTQUFTLGNBQWMsQ0FDckIsVUFBa0IsRUFDbEIsSUFBWSxFQUNaLFdBQW1CLEVBQ25CLEtBQWdCLEVBQ2hCLE1BQWdCO1FBRWhCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQzNDLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDdkUsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQ3ZDLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRTtvQkFDbEIsU0FBUztpQkFDVjtnQkFDRCxNQUFNLENBQUMsR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN2RCxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzthQUMzQztTQUNGO0lBQ0gsQ0FBQztJQUVELFNBQVMsWUFBWSxDQUNuQixLQUFvQixFQUNwQixJQUFZLEVBQ1osV0FBbUIsRUFDbkIsS0FBZ0IsRUFDaEIsTUFBZ0I7UUFFaEIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDM0MsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBRW5FLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO2dCQUN2QyxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUU7b0JBQ2xCLE9BQU87aUJBQ1I7Z0JBQ0QsTUFBTSxDQUFDLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdkQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7YUFDM0M7U0FDRjtRQUNELE9BQU87SUFDVCxDQUFDO0lBRUQsT0FBTyxFQUFFLGNBQWMsRUFBRSxZQUFZLEVBQUUsQ0FBQztBQUMxQyxDQUFDO0FBU0QsTUFBTSxVQUFVLHVCQUF1QixDQUFDLFVBQXNCO0lBQzVELE9BQU8sU0FBUyxVQUFVLENBQ3hCLElBQVksRUFDWixLQUEwQixFQUMxQixjQUF5QixFQUN6QixXQUFtQjtRQUVuQixNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFakQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDM0MsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUMsT0FBTyxJQUFJLEVBQUU7Z0JBQ1gsK0JBQStCO2dCQUMvQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFFdkQsSUFBSSxNQUFNLEtBQUssQ0FBQyxDQUFDLEVBQUU7b0JBQ2pCLE1BQU07aUJBQ1A7Z0JBQ0QsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNyRSxLQUFLLE1BQU0sU0FBUyxJQUFJLFVBQVUsRUFBRTtvQkFDbEMsSUFDRSxTQUFTLEtBQUssTUFBTTt3QkFDcEIsU0FBUyxLQUFLLENBQUMsQ0FBQzt3QkFDaEIsS0FBSyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFDcEI7d0JBQ0EsU0FBUztxQkFDVjtvQkFDRCxNQUFNLENBQUMsR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUN0RCxJQUFJLENBQUMsaUJBQWlCLENBQUMsY0FBYyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUMzRCxLQUFLLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO2lCQUN0QjthQUNGO1NBQ0Y7UUFDRCxPQUFPLGNBQWMsQ0FBQztJQUN4QixDQUFDLENBQUM7QUFDSixDQUFDO0FBRUQsTUFBTSxVQUFVLGdCQUFnQixDQUM5QixNQUF1QixFQUN2QixJQUFZLEVBQ1osV0FBbUIsRUFDbkIsVUFBa0IsRUFDbEIsY0FBZ0MsRUFDaEMsWUFBNEIsRUFDNUIsTUFBZ0I7SUFFaEIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQzlELGNBQWMsQ0FBQyxVQUFVLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDL0QsSUFBSSxNQUFNLEVBQUU7UUFDVixLQUFLLElBQUksSUFBSSxJQUFJLE1BQU0sRUFBRTtZQUN2QixZQUFZLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1NBQ3hEO0tBQ0Y7SUFDRCxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICpcbiAqIENvcHlyaWdodCAyMDE5IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuLyoqXG4gKiBUaGlzIGlzIGEgSmF2YVNjcmlwdCByZWltcGxlbWVudGF0aW9uIG9mIFVNQVAgKG9yaWdpbmFsIGxpY2Vuc2UgYmVsb3cpLCBmcm9tXG4gKiB0aGUgcHl0aG9uIGltcGxlbWVudGF0aW9uIGZvdW5kIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9sbWNpbm5lcy91bWFwLlxuICpcbiAqIEBhdXRob3IgYW5keWNvZW5lbkBnb29nbGUuY29tIChBbmR5IENvZW5lbilcbiAqL1xuXG4vKipcbiAqIEBsaWNlbnNlXG4gKiBCU0QgMy1DbGF1c2UgTGljZW5zZVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxNywgTGVsYW5kIE1jSW5uZXNcbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpc1xuICogICBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAqXG4gKiAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxuICogICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAqXG4gKiAqIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIGNvcHlyaWdodCBob2xkZXIgbm9yIHRoZSBuYW1lcyBvZiBpdHNcbiAqICAgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb21cbiAqICAgdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbiAqXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFXG4gKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTFxuICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1JcbiAqIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSXG4gKiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLFxuICogT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0VcbiAqIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKi9cblxuaW1wb3J0ICogYXMgaGVhcCBmcm9tICcuL2hlYXAnO1xuaW1wb3J0ICogYXMgbWF0cml4IGZyb20gJy4vbWF0cml4JztcbmltcG9ydCAqIGFzIHRyZWUgZnJvbSAnLi90cmVlJztcbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgUmFuZG9tRm4sIFZlY3RvcnMsIERpc3RhbmNlRm4sIFZlY3RvciB9IGZyb20gJy4vdW1hcCc7XG5cbi8qKlxuICogQ3JlYXRlIGEgdmVyc2lvbiBvZiBuZWFyZXN0IG5laWdoYm9yIGRlc2NlbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYWtlTk5EZXNjZW50KGRpc3RhbmNlRm46IERpc3RhbmNlRm4sIHJhbmRvbTogUmFuZG9tRm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIG5ORGVzY2VudChcbiAgICBkYXRhOiBWZWN0b3IsXG4gICAgbGVhZkFycmF5OiBWZWN0b3JzLFxuICAgIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgICBuSXRlcnMgPSAxMCxcbiAgICBtYXhDYW5kaWRhdGVzID0gNTAsXG4gICAgZGVsdGEgPSAwLjAwMSxcbiAgICByaG8gPSAwLjUsXG4gICAgcnBUcmVlSW5pdCA9IHRydWVcbiAgKSB7XG4gICAgY29uc3QgblZlcnRpY2VzID0gZGF0YS5sZW5ndGg7XG4gICAgY29uc3QgY3VycmVudEdyYXBoID0gaGVhcC5tYWtlSGVhcChkYXRhLmxlbmd0aCwgbk5laWdoYm9ycyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGluZGljZXMgPSBoZWFwLnJlamVjdGlvblNhbXBsZShuTmVpZ2hib3JzLCBkYXRhLmxlbmd0aCwgcmFuZG9tKTtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kaWNlcy5sZW5ndGg7IGorKykge1xuICAgICAgICBjb25zdCBkID0gZGlzdGFuY2VGbihkYXRhW2ldLCBkYXRhW2luZGljZXNbal1dKTtcblxuICAgICAgICBoZWFwLmhlYXBQdXNoKGN1cnJlbnRHcmFwaCwgaSwgZCwgaW5kaWNlc1tqXSwgMSk7XG4gICAgICAgIGhlYXAuaGVhcFB1c2goY3VycmVudEdyYXBoLCBpbmRpY2VzW2pdLCBkLCBpLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHJwVHJlZUluaXQpIHtcbiAgICAgIGZvciAobGV0IG4gPSAwOyBuIDwgbGVhZkFycmF5Lmxlbmd0aDsgbisrKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVhZkFycmF5W25dLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYgKGxlYWZBcnJheVtuXVtpXSA8IDApIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCBsZWFmQXJyYXlbbl0ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmIChsZWFmQXJyYXlbbl1bal0gPCAwKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlRm4oZGF0YVtsZWFmQXJyYXlbbl1baV1dLCBkYXRhW2xlYWZBcnJheVtuXVtqXV0pO1xuICAgICAgICAgICAgaGVhcC5oZWFwUHVzaChjdXJyZW50R3JhcGgsIGxlYWZBcnJheVtuXVtpXSwgZCwgbGVhZkFycmF5W25dW2pdLCAxKTtcbiAgICAgICAgICAgIGhlYXAuaGVhcFB1c2goY3VycmVudEdyYXBoLCBsZWFmQXJyYXlbbl1bal0sIGQsIGxlYWZBcnJheVtuXVtpXSwgMSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgbiA9IDA7IG4gPCBuSXRlcnM7IG4rKykge1xuICAgICAgY29uc3QgY2FuZGlkYXRlTmVpZ2hib3JzID0gaGVhcC5idWlsZENhbmRpZGF0ZXMoXG4gICAgICAgIGN1cnJlbnRHcmFwaCxcbiAgICAgICAgblZlcnRpY2VzLFxuICAgICAgICBuTmVpZ2hib3JzLFxuICAgICAgICBtYXhDYW5kaWRhdGVzLFxuICAgICAgICByYW5kb21cbiAgICAgICk7XG5cbiAgICAgIGxldCBjID0gMDtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgblZlcnRpY2VzOyBpKyspIHtcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBtYXhDYW5kaWRhdGVzOyBqKyspIHtcbiAgICAgICAgICBsZXQgcCA9IE1hdGguZmxvb3IoY2FuZGlkYXRlTmVpZ2hib3JzWzBdW2ldW2pdKTtcbiAgICAgICAgICBpZiAocCA8IDAgfHwgdXRpbHMudGF1UmFuZChyYW5kb20pIDwgcmhvKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBtYXhDYW5kaWRhdGVzOyBrKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHEgPSBNYXRoLmZsb29yKGNhbmRpZGF0ZU5laWdoYm9yc1swXVtpXVtrXSk7XG4gICAgICAgICAgICBjb25zdCBjaiA9IGNhbmRpZGF0ZU5laWdoYm9yc1syXVtpXVtqXTtcbiAgICAgICAgICAgIGNvbnN0IGNrID0gY2FuZGlkYXRlTmVpZ2hib3JzWzJdW2ldW2tdO1xuICAgICAgICAgICAgaWYgKHEgPCAwIHx8ICghY2ogJiYgIWNrKSkge1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlRm4oZGF0YVtwXSwgZGF0YVtxXSk7XG4gICAgICAgICAgICBjICs9IGhlYXAuaGVhcFB1c2goY3VycmVudEdyYXBoLCBwLCBkLCBxLCAxKTtcbiAgICAgICAgICAgIGMgKz0gaGVhcC5oZWFwUHVzaChjdXJyZW50R3JhcGgsIHEsIGQsIHAsIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGMgPD0gZGVsdGEgKiBuTmVpZ2hib3JzICogZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHNvcnRlZCA9IGhlYXAuZGVoZWFwU29ydChjdXJyZW50R3JhcGgpO1xuICAgIHJldHVybiBzb3J0ZWQ7XG4gIH07XG59XG5cbmV4cG9ydCB0eXBlIEluaXRGcm9tUmFuZG9tRm4gPSAoXG4gIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgZGF0YTogVmVjdG9yLFxuICBxdWVyeVBvaW50czogVmVjdG9yLFxuICBfaGVhcDogaGVhcC5IZWFwLFxuICByYW5kb206IFJhbmRvbUZuXG4pID0+IHZvaWQ7XG5cbmV4cG9ydCB0eXBlIEluaXRGcm9tVHJlZUZuID0gKFxuICBfdHJlZTogdHJlZS5GbGF0VHJlZSxcbiAgZGF0YTogVmVjdG9yLFxuICBxdWVyeVBvaW50czogVmVjdG9yLFxuICBfaGVhcDogaGVhcC5IZWFwLFxuICByYW5kb206IFJhbmRvbUZuXG4pID0+IHZvaWQ7XG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlSW5pdGlhbGl6YXRpb25zKGRpc3RhbmNlRm46IERpc3RhbmNlRm4pIHtcbiAgZnVuY3Rpb24gaW5pdEZyb21SYW5kb20oXG4gICAgbk5laWdoYm9yczogbnVtYmVyLFxuICAgIGRhdGE6IFZlY3RvcixcbiAgICBxdWVyeVBvaW50czogVmVjdG9yLFxuICAgIF9oZWFwOiBoZWFwLkhlYXAsXG4gICAgcmFuZG9tOiBSYW5kb21GblxuICApIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHF1ZXJ5UG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpbmRpY2VzID0gdXRpbHMucmVqZWN0aW9uU2FtcGxlKG5OZWlnaGJvcnMsIGRhdGEubGVuZ3RoLCByYW5kb20pO1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbmRpY2VzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChpbmRpY2VzW2pdIDwgMCkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGQgPSBkaXN0YW5jZUZuKGRhdGFbaW5kaWNlc1tqXV0sIHF1ZXJ5UG9pbnRzW2ldKTtcbiAgICAgICAgaGVhcC5oZWFwUHVzaChfaGVhcCwgaSwgZCwgaW5kaWNlc1tqXSwgMSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW5pdEZyb21UcmVlKFxuICAgIF90cmVlOiB0cmVlLkZsYXRUcmVlLFxuICAgIGRhdGE6IFZlY3RvcixcbiAgICBxdWVyeVBvaW50czogVmVjdG9yLFxuICAgIF9oZWFwOiBoZWFwLkhlYXAsXG4gICAgcmFuZG9tOiBSYW5kb21GblxuICApIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHF1ZXJ5UG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpbmRpY2VzID0gdHJlZS5zZWFyY2hGbGF0VHJlZShxdWVyeVBvaW50c1tpXSwgX3RyZWUsIHJhbmRvbSk7XG5cbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5kaWNlcy5sZW5ndGg7IGorKykge1xuICAgICAgICBpZiAoaW5kaWNlc1tqXSA8IDApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZCA9IGRpc3RhbmNlRm4oZGF0YVtpbmRpY2VzW2pdXSwgcXVlcnlQb2ludHNbaV0pO1xuICAgICAgICBoZWFwLmhlYXBQdXNoKF9oZWFwLCBpLCBkLCBpbmRpY2VzW2pdLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcmV0dXJuIHsgaW5pdEZyb21SYW5kb20sIGluaXRGcm9tVHJlZSB9O1xufVxuXG5leHBvcnQgdHlwZSBTZWFyY2hGbiA9IChcbiAgZGF0YTogVmVjdG9yLFxuICBncmFwaDogbWF0cml4LlNwYXJzZU1hdHJpeCxcbiAgaW5pdGlhbGl6YXRpb246IGhlYXAuSGVhcCxcbiAgcXVlcnlQb2ludHM6IFZlY3RvclxuKSA9PiBoZWFwLkhlYXA7XG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlSW5pdGlhbGl6ZWROTlNlYXJjaChkaXN0YW5jZUZuOiBEaXN0YW5jZUZuKSB7XG4gIHJldHVybiBmdW5jdGlvbiBublNlYXJjaEZuKFxuICAgIGRhdGE6IFZlY3RvcixcbiAgICBncmFwaDogbWF0cml4LlNwYXJzZU1hdHJpeCxcbiAgICBpbml0aWFsaXphdGlvbjogaGVhcC5IZWFwLFxuICAgIHF1ZXJ5UG9pbnRzOiBWZWN0b3JcbiAgKSB7XG4gICAgY29uc3QgeyBpbmRpY2VzLCBpbmRwdHIgfSA9IG1hdHJpeC5nZXRDU1IoZ3JhcGgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBxdWVyeVBvaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgdHJpZWQgPSBuZXcgU2V0KGluaXRpYWxpemF0aW9uWzBdW2ldKTtcbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIC8vIEZpbmQgc21hbGxlc3QgZmxhZ2dlZCB2ZXJ0ZXhcbiAgICAgICAgY29uc3QgdmVydGV4ID0gaGVhcC5zbWFsbGVzdEZsYWdnZWQoaW5pdGlhbGl6YXRpb24sIGkpO1xuXG4gICAgICAgIGlmICh2ZXJ0ZXggPT09IC0xKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2FuZGlkYXRlcyA9IGluZGljZXMuc2xpY2UoaW5kcHRyW3ZlcnRleF0sIGluZHB0clt2ZXJ0ZXggKyAxXSk7XG4gICAgICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBjYW5kaWRhdGUgPT09IHZlcnRleCB8fFxuICAgICAgICAgICAgY2FuZGlkYXRlID09PSAtMSB8fFxuICAgICAgICAgICAgdHJpZWQuaGFzKGNhbmRpZGF0ZSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBkID0gZGlzdGFuY2VGbihkYXRhW2NhbmRpZGF0ZV0sIHF1ZXJ5UG9pbnRzW2ldKTtcbiAgICAgICAgICBoZWFwLnVuY2hlY2tlZEhlYXBQdXNoKGluaXRpYWxpemF0aW9uLCBpLCBkLCBjYW5kaWRhdGUsIDEpO1xuICAgICAgICAgIHRyaWVkLmFkZChjYW5kaWRhdGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBpbml0aWFsaXphdGlvbjtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRpYWxpemVTZWFyY2goXG4gIGZvcmVzdDogdHJlZS5GbGF0VHJlZVtdLFxuICBkYXRhOiBWZWN0b3IsXG4gIHF1ZXJ5UG9pbnRzOiBWZWN0b3IsXG4gIG5OZWlnaGJvcnM6IG51bWJlcixcbiAgaW5pdEZyb21SYW5kb206IEluaXRGcm9tUmFuZG9tRm4sXG4gIGluaXRGcm9tVHJlZTogSW5pdEZyb21UcmVlRm4sXG4gIHJhbmRvbTogUmFuZG9tRm5cbikge1xuICBjb25zdCByZXN1bHRzID0gaGVhcC5tYWtlSGVhcChxdWVyeVBvaW50cy5sZW5ndGgsIG5OZWlnaGJvcnMpO1xuICBpbml0RnJvbVJhbmRvbShuTmVpZ2hib3JzLCBkYXRhLCBxdWVyeVBvaW50cywgcmVzdWx0cywgcmFuZG9tKTtcbiAgaWYgKGZvcmVzdCkge1xuICAgIGZvciAobGV0IHRyZWUgb2YgZm9yZXN0KSB7XG4gICAgICBpbml0RnJvbVRyZWUodHJlZSwgZGF0YSwgcXVlcnlQb2ludHMsIHJlc3VsdHMsIHJhbmRvbSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHRzO1xufVxuIl19","import isArray from 'is-any-array';\n\nimport errorCalculation from './errorCalculation';\nimport step from './step';\n\n/**\n * Curve fitting algorithm\n * @param {{x:Array<number>, y:Array<number>}} data - Array of points to fit in the format [x1, x2, ... ], [y1, y2, ... ]\n * @param {function} parameterizedFunction - The parameters and returns a function with the independent variable as a parameter\n * @param {object} [options] - Options object\n * @param {number} [options.damping] - Levenberg-Marquardt parameter\n * @param {number} [options.gradientDifference = 10e-2] - Adjustment for decrease the damping parameter\n * @param {Array<number>} [options.minValues] - Minimum allowed values for parameters\n * @param {Array<number>} [options.maxValues] - Maximum allowed values for parameters\n * @param {Array<number>} [options.initialValues] - Array of initial parameter values\n * @param {number} [options.maxIterations = 100] - Maximum of allowed iterations\n * @param {number} [options.errorTolerance = 10e-3] - Minimum uncertainty allowed for each point\n * @return {{parameterValues: Array<number>, parameterError: number, iterations: number}}\n */\nexport default function levenbergMarquardt(\n data,\n parameterizedFunction,\n options = {},\n) {\n let {\n maxIterations = 100,\n gradientDifference = 10e-2,\n damping = 0,\n errorTolerance = 10e-3,\n minValues,\n maxValues,\n initialValues,\n } = options;\n\n if (damping <= 0) {\n throw new Error('The damping option must be a positive number');\n } else if (!data.x || !data.y) {\n throw new Error('The data parameter must have x and y elements');\n } else if (\n !isArray(data.x) ||\n data.x.length < 2 ||\n !isArray(data.y) ||\n data.y.length < 2\n ) {\n throw new Error(\n 'The data parameter elements must be an array with more than 2 points',\n );\n } else if (data.x.length !== data.y.length) {\n throw new Error('The data parameter elements must have the same size');\n }\n\n let parameters =\n initialValues || new Array(parameterizedFunction.length).fill(1);\n let parLen = parameters.length;\n maxValues = maxValues || new Array(parLen).fill(Number.MAX_SAFE_INTEGER);\n minValues = minValues || new Array(parLen).fill(Number.MIN_SAFE_INTEGER);\n\n if (maxValues.length !== minValues.length) {\n throw new Error('minValues and maxValues must be the same size');\n }\n\n if (!isArray(parameters)) {\n throw new Error('initialValues must be an array');\n }\n\n let error = errorCalculation(data, parameters, parameterizedFunction);\n\n let converged = error <= errorTolerance;\n\n let iteration;\n for (iteration = 0; iteration < maxIterations && !converged; iteration++) {\n parameters = step(\n data,\n parameters,\n damping,\n gradientDifference,\n parameterizedFunction,\n );\n\n for (let k = 0; k < parLen; k++) {\n parameters[k] = Math.min(\n Math.max(minValues[k], parameters[k]),\n maxValues[k],\n );\n }\n\n error = errorCalculation(data, parameters, parameterizedFunction);\n if (isNaN(error)) break;\n converged = error <= errorTolerance;\n }\n\n return {\n parameterValues: parameters,\n parameterError: error,\n iterations: iteration,\n };\n}\n","export const isNil = (x) => x === null || x === undefined;\nexport function insertSmaller(distancesAr, indexes, num, index) {\n if (num > distancesAr[distancesAr.length - 1]) {\n return;\n }\n const newPosition = distancesAr.findIndex((v) => num > v) + 1;\n distancesAr.pop();\n distancesAr.splice(newPosition, 0, num);\n indexes.pop();\n indexes.splice(newPosition, 0, index);\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ1dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQUMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLFNBQVMsQ0FBQztBQUUvRCxNQUFNLFVBQVUsYUFBYSxDQUFDLFdBQXFCLEVBQUUsT0FBaUIsRUFBRSxHQUFXLEVBQUUsS0FBYTtJQUM5RixJQUFJLEdBQUcsR0FBRyxXQUFXLENBQUMsV0FBVyxDQUFDLE1BQU0sR0FBQyxDQUFDLENBQUMsRUFBRTtRQUN6QyxPQUFPO0tBQ1Y7SUFDRCxNQUFNLFdBQVcsR0FBRyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzlELFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUNsQixXQUFXLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDeEMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ2QsT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgaXNOaWwgPSAoeDogYW55KSA9PiB4ID09PSBudWxsIHx8IHggPT09IHVuZGVmaW5lZDtcblxuZXhwb3J0IGZ1bmN0aW9uIGluc2VydFNtYWxsZXIoZGlzdGFuY2VzQXI6IG51bWJlcltdLCBpbmRleGVzOiBudW1iZXJbXSwgbnVtOiBudW1iZXIsIGluZGV4OiBudW1iZXIpIHtcbiAgICBpZiAobnVtID4gZGlzdGFuY2VzQXJbZGlzdGFuY2VzQXIubGVuZ3RoLTFdKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbmV3UG9zaXRpb24gPSBkaXN0YW5jZXNBci5maW5kSW5kZXgoKHYpID0+IG51bSA+IHYpICsgMTtcbiAgICBkaXN0YW5jZXNBci5wb3AoKTtcbiAgICBkaXN0YW5jZXNBci5zcGxpY2UobmV3UG9zaXRpb24sIDAsIG51bSk7XG4gICAgaW5kZXhlcy5wb3AoKTtcbiAgICBpbmRleGVzLnNwbGljZShuZXdQb3NpdGlvbiwgMCwgaW5kZXgpO1xufVxuIl19","import { isNil } from './utils';\n/** Distance matrix class compatible with data structure of scipy.spatial.distance.pdist */\nexport class DistanceMatrix {\n get data() { return this._data; }\n get size() { return this._size; }\n /**\n * @param {Float32Array} data Distance data\n * @param {number} size Number of original observations\n */\n constructor(data, size) {\n if (size == undefined) {\n if (data == undefined)\n throw new Error('Arguments error: data or size is required.');\n this._data = data;\n this._size = (1 + Math.sqrt(1 + 4 * 2 * this._data.length)) / 2;\n if (this._size != Math.floor(this._size))\n throw new Error(`Invalid data length ${this._data.length} leads to non integer size ${this._size}`);\n }\n else {\n this._size = size;\n const dataLength = size * (size - 1) / 2;\n if (data) {\n if (data.length != dataLength)\n throw new Error(`Invalid data length. Observations size ${size} requires data length ${dataLength}.`);\n this._data = data;\n }\n else {\n this._data = new Float32Array(dataLength);\n }\n }\n }\n _linearizeIJ(i, j) {\n if (!(i < j))\n throw new Error('i must be less than j');\n return this._size * i + j - Math.floor(((i + 2) * (i + 1)) / 2);\n }\n get(i, j) {\n if (i == j)\n return 0;\n else if (i < j)\n return this._data[this._linearizeIJ(i, j)];\n else\n return this._data[this._linearizeIJ(j, i)];\n }\n set(i, j, value) {\n this._data[this._linearizeIJ(i, j)] = value;\n }\n static calc(list, method) {\n const size = list.length;\n const res = new DistanceMatrix(undefined, size);\n for (let i = 0; i < size; i++) {\n for (let j = i + 1; j < size; j++) {\n // if any of the values is null, set distance to 1\n res.set(i, j, !isNil(list[i]) && !isNil(list[j]) ? method(list[i], list[j]) : 1);\n }\n }\n return res;\n }\n // squares each value in matrix in place\n square() {\n for (let i = 0; i < this._data.length; i++)\n this._data[i] = this._data[i] ** 2;\n }\n // adds another matrix to this one in place\n add(other) {\n if (this._size !== other._size)\n throw new Error(`Matrices must have the same size. This size: ${this._size}, other size: ${other._size}`);\n for (let i = 0; i < this._data.length; i++)\n this._data[i] += other._data[i];\n }\n // square root each value in matrix in place\n sqrt() {\n for (let i = 0; i < this._data.length; i++)\n this._data[i] = Math.sqrt(this._data[i]);\n }\n //normilze distance matrix in place\n normalize() {\n let min = 0;\n let max = this._data[0];\n for (let i = 0; i < this._data.length; i++) {\n if (this._data[i] < min)\n min = this._data[i];\n if (this._data[i] > max)\n max = this._data[i];\n }\n const range = max - min;\n for (let i = 0; i < this._data.length; i++)\n this._data[i] = range === 0 ? this._data[i] - min : (this._data[i] - min) / (max - min);\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzdGFuY2UtbWF0cml4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGlzdGFuY2UtbWF0cml4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLE9BQU8sRUFBQyxLQUFLLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFFOUIsMkZBQTJGO0FBQzNGLE1BQU0sT0FBTyxjQUFjO0lBSXpCLElBQUksSUFBSSxLQUFtQixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBRS9DLElBQUksSUFBSSxLQUFhLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFFekM7OztPQUdHO0lBQ0gsWUFBWSxJQUFtQixFQUFFLElBQWE7UUFDNUMsSUFBSSxJQUFJLElBQUksU0FBUyxFQUFFO1lBQ3JCLElBQUksSUFBSSxJQUFJLFNBQVM7Z0JBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO1lBRXJGLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSyxDQUFDO1lBQ25CLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2hFLElBQUksSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7Z0JBQ3RDLE1BQU0sSUFBSSxLQUFLLENBQUMsdUJBQXVCLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSw4QkFBOEIsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7U0FDdkc7YUFBTTtZQUNMLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1lBQ2xCLE1BQU0sVUFBVSxHQUFXLElBQUksR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7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QjtRQUNELE1BQU0sS0FBSyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUM7UUFDeEIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRTtZQUN4QyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUM7SUFDNUYsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZ3JvayBmcm9tICdkYXRhZ3Jvay1hcGkvZ3Jvayc7XG5pbXBvcnQgKiBhcyB1aSBmcm9tICdkYXRhZ3Jvay1hcGkvdWknO1xuaW1wb3J0ICogYXMgREcgZnJvbSAnZGF0YWdyb2stYXBpL2RnJztcbmltcG9ydCB7aXNOaWx9IGZyb20gJy4vdXRpbHMnO1xuXG4vKiogRGlzdGFuY2UgbWF0cml4IGNsYXNzIGNvbXBhdGlibGUgd2l0aCBkYXRhIHN0cnVjdHVyZSBvZiBzY2lweS5zcGF0aWFsLmRpc3RhbmNlLnBkaXN0ICovXG5leHBvcnQgY2xhc3MgRGlzdGFuY2VNYXRyaXgge1xuICBfZGF0YTogRmxvYXQzMkFycmF5O1xuICBfc2l6ZTogbnVtYmVyO1xuXG4gIGdldCBkYXRhKCk6IEZsb2F0MzJBcnJheSB7IHJldHVybiB0aGlzLl9kYXRhOyB9XG5cbiAgZ2V0IHNpemUoKTogbnVtYmVyIHsgcmV0dXJuIHRoaXMuX3NpemU7IH1cblxuICAvKipcbiAgICogQHBhcmFtIHtGbG9hdDMyQXJyYXl9IGRhdGEgRGlzdGFuY2UgZGF0YVxuICAgKiBAcGFyYW0ge251bWJlcn0gc2l6ZSBOdW1iZXIgb2Ygb3JpZ2luYWwgb2JzZXJ2YXRpb25zXG4gICAqL1xuICBjb25zdHJ1Y3RvcihkYXRhPzogRmxvYXQzMkFycmF5LCBzaXplPzogbnVtYmVyKSB7XG4gICAgaWYgKHNpemUgPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoZGF0YSA9PSB1bmRlZmluZWQpIHRocm93IG5ldyBFcnJvcignQXJndW1lbnRzIGVycm9yOiBkYXRhIG9yIHNpemUgaXMgcmVxdWlyZWQuJyk7XG5cbiAgICAgIHRoaXMuX2RhdGEgPSBkYXRhITtcbiAgICAgIHRoaXMuX3NpemUgPSAoMSArIE1hdGguc3FydCgxICsgNCAqIDIgKiB0aGlzLl9kYXRhLmxlbmd0aCkpIC8gMjtcbiAgICAgIGlmICh0aGlzLl9zaXplICE9IE1hdGguZmxvb3IodGhpcy5fc2l6ZSkpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBkYXRhIGxlbmd0aCAke3RoaXMuX2RhdGEubGVuZ3RofSBsZWFkcyB0byBub24gaW50ZWdlciBzaXplICR7dGhpcy5fc2l6ZX1gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fc2l6ZSA9IHNpemU7XG4gICAgICBjb25zdCBkYXRhTGVuZ3RoOiBudW1iZXIgPSBzaXplICogKHNpemUgLSAxKSAvIDI7XG4gICAgICBpZiAoZGF0YSkge1xuICAgICAgICBpZiAoZGF0YS5sZW5ndGggIT0gZGF0YUxlbmd0aClcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZGF0YSBsZW5ndGguIE9ic2VydmF0aW9ucyBzaXplICR7c2l6ZX0gcmVxdWlyZXMgZGF0YSBsZW5ndGggJHtkYXRhTGVuZ3RofS5gKTtcbiAgICAgICAgdGhpcy5fZGF0YSA9IGRhdGE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9kYXRhID0gbmV3IEZsb2F0MzJBcnJheShkYXRhTGVuZ3RoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9saW5lYXJpemVJSihpOiBudW1iZXIsIGo6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKCEoaSA8IGopKSB0aHJvdyBuZXcgRXJyb3IoJ2kgbXVzdCBiZSBsZXNzIHRoYW4gaicpO1xuICAgIHJldHVybiB0aGlzLl9zaXplICogaSArIGogLSBNYXRoLmZsb29yKCgoaSArIDIpICogKGkgKyAxKSkgLyAyKTtcbiAgfVxuXG4gIGdldChpOiBudW1iZXIsIGo6IG51bWJlcikge1xuICAgIGlmIChpID09IGopXG4gICAgICByZXR1cm4gMDtcbiAgICBlbHNlIGlmIChpIDwgailcbiAgICAgIHJldHVybiB0aGlzLl9kYXRhW3RoaXMuX2xpbmVhcml6ZUlKKGksIGopXTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gdGhpcy5fZGF0YVt0aGlzLl9saW5lYXJpemVJSihqLCBpKV07XG4gIH1cblxuICBzZXQoaTogbnVtYmVyLCBqOiBudW1iZXIsIHZhbHVlOiBudW1iZXIpIHtcbiAgICB0aGlzLl9kYXRhW3RoaXMuX2xpbmVhcml6ZUlKKGksIGopXSA9IHZhbHVlO1xuICB9XG5cbiAgc3RhdGljIGNhbGM8VE9iaj4obGlzdDogSW5kZXhhYmxlPFRPYmo+LCBtZXRob2Q6IChhOiBUT2JqLCBiOiBUT2JqKSA9PiBudW1iZXIpOiBEaXN0YW5jZU1hdHJpeCB7XG4gICAgY29uc3Qgc2l6ZTogbnVtYmVyID0gbGlzdC5sZW5ndGg7XG4gICAgY29uc3QgcmVzID0gbmV3IERpc3RhbmNlTWF0cml4KHVuZGVmaW5lZCwgc2l6ZSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgIGZvciAobGV0IGogPSBpICsgMTsgaiA8IHNpemU7IGorKykge1xuICAgICAgICAvLyBpZiBhbnkgb2YgdGhlIHZhbHVlcyBpcyBudWxsLCBzZXQgZGlzdGFuY2UgdG8gMVxuICAgICAgICByZXMuc2V0KGksIGosICFpc05pbChsaXN0W2ldKSAmJiAhaXNOaWwobGlzdFtqXSkgPyBtZXRob2QobGlzdFtpXSwgbGlzdFtqXSkgOiAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIC8vIHNxdWFyZXMgZWFjaCB2YWx1ZSBpbiBtYXRyaXggaW4gcGxhY2VcbiAgcHVibGljIHNxdWFyZSgpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2RhdGEubGVuZ3RoOyBpKyspXG4gICAgICB0aGlzLl9kYXRhW2ldID0gdGhpcy5fZGF0YVtpXSAqKiAyO1xuICB9XG5cbiAgLy8gYWRkcyBhbm90aGVyIG1hdHJpeCB0byB0aGlzIG9uZSBpbiBwbGFjZVxuICBwdWJsaWMgYWRkKG90aGVyOiBEaXN0YW5jZU1hdHJpeCkge1xuICAgIGlmICh0aGlzLl9zaXplICE9PSBvdGhlci5fc2l6ZSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTWF0cmljZXMgbXVzdCBoYXZlIHRoZSBzYW1lIHNpemUuIFRoaXMgc2l6ZTogJHt0aGlzLl9zaXplfSwgb3RoZXIgc2l6ZTogJHtvdGhlci5fc2l6ZX1gKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2RhdGEubGVuZ3RoOyBpKyspXG4gICAgICB0aGlzLl9kYXRhW2ldICs9IG90aGVyLl9kYXRhW2ldO1xuICB9XG5cbiAgLy8gc3F1YXJlIHJvb3QgZWFjaCB2YWx1ZSBpbiBtYXRyaXggaW4gcGxhY2VcbiAgcHVibGljIHNxcnQoKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9kYXRhLmxlbmd0aDsgaSsrKVxuICAgICAgdGhpcy5fZGF0YVtpXSA9IE1hdGguc3FydCh0aGlzLl9kYXRhW2ldKTtcbiAgfVxuXG4gIC8vbm9ybWlsemUgZGlzdGFuY2UgbWF0cml4IGluIHBsYWNlXG4gIHB1YmxpYyBub3JtYWxpemUoKSB7XG4gICAgbGV0IG1pbiA9IDA7XG4gICAgbGV0IG1heCA9IHRoaXMuX2RhdGFbMF07XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9kYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodGhpcy5fZGF0YVtpXSA8IG1pbilcbiAgICAgICAgbWluID0gdGhpcy5fZGF0YVtpXTtcbiAgICAgIGlmICh0aGlzLl9kYXRhW2ldID4gbWF4KVxuICAgICAgICBtYXggPSB0aGlzLl9kYXRhW2ldO1xuICAgIH1cbiAgICBjb25zdCByYW5nZSA9IG1heCAtIG1pbjtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2RhdGEubGVuZ3RoOyBpKyspXG4gICAgICB0aGlzLl9kYXRhW2ldID0gcmFuZ2UgPT09IDAgPyB0aGlzLl9kYXRhW2ldIC0gbWluIDogKHRoaXMuX2RhdGFbaV0gLSBtaW4pIC8gKG1heCAtIG1pbik7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbmRleGFibGU8VE9iaj4ge1xuICBbaW5kZXg6IG51bWJlcl06IFRPYmo7XG4gIGdldCBsZW5ndGgoKTogbnVtYmVyO1xufVxuIl19","import { getSimilarityFromDistance } from \"../distance-metrics-methods\";\nimport { BitArrayMetricsNames } from \"../typed-metrics\";\nimport { insertSmaller, isNil } from \"./utils\";\nexport class SparseMatrixService {\n constructor() {\n this._workerCount = Math.max(navigator.hardwareConcurrency - 2, 1);\n }\n async calc(values, fnName, threshold, opts = {}) {\n //size of full matrix\n const matSize = values.length * (values.length - 1) / 2;\n const chunkSize = Math.floor(matSize / this._workerCount);\n const minThreshold = values.length > 20000 ? await this.getMinimalThreshold(values, fnName, opts) : 0;\n if (threshold < minThreshold) {\n console.log(`using threshold ${minThreshold}`);\n threshold = minThreshold;\n }\n opts['threshold'] = threshold;\n const promises = new Array(this._workerCount);\n const workers = new Array(this._workerCount).fill(null).map(() => new Worker(new URL('./sparse-matrix-worker', import.meta.url)));\n for (let idx = 0; idx < this._workerCount; idx++) {\n promises[idx] = new Promise((resolveWorker, rejectWorker) => {\n const startIdx = idx * chunkSize;\n const endIdx = idx === this._workerCount - 1 ? matSize : (idx + 1) * chunkSize;\n if (endIdx <= startIdx)\n resolveWorker({ i: new Int32Array(0), j: new Int32Array(0), distance: new Float32Array(0), idx });\n workers[idx].postMessage({ values, startIdx, endIdx, threshold, fnName, opts });\n workers[idx].onmessage = ({ data: { error, i, j, distance } }) => {\n if (error) {\n workers[idx].terminate();\n rejectWorker(error);\n }\n else {\n workers[idx].terminate();\n resolveWorker({ i, j, distance, idx });\n }\n };\n });\n }\n const results = await Promise.all(promises);\n const fullSize = results.reduce((acc, val) => acc + val.i.length, 0);\n const i = new Int32Array(fullSize);\n const j = new Int32Array(fullSize);\n const distance = new Float32Array(fullSize);\n let offset = 0;\n // setting the results\n for (const res of results) {\n i.set(res.i, offset);\n j.set(res.j, offset);\n distance.set(res.distance, offset);\n offset += res.i.length;\n }\n return { i, j, distance };\n }\n async getKNN(values, fnName, nNeighbours = 15, opts = {}) {\n const matSize = values.length * (values.length - 1) / 2;\n const chunkSize = Math.floor(matSize / this._workerCount);\n const promises = new Array(this._workerCount);\n const workers = new Array(this._workerCount).fill(null).map(() => new Worker(new URL('./knn-worker', import.meta.url)));\n for (let idx = 0; idx < this._workerCount; idx++) {\n promises[idx] = new Promise((resolveWorker, rejectWorker) => {\n const startIdx = idx * chunkSize;\n const endIdx = idx === this._workerCount - 1 ? matSize : (idx + 1) * chunkSize;\n if (endIdx <= startIdx)\n resolveWorker({ knnDistances: new Array(0), knnIndexes: new Array(0) });\n workers[idx].postMessage({ values, startIdx, endIdx, fnName, opts, nNeighbours });\n workers[idx].onmessage = ({ data: { error, knnDistances, knnIndexes } }) => {\n if (error) {\n workers[idx].terminate();\n rejectWorker(error);\n }\n else {\n workers[idx].terminate();\n resolveWorker({ knnDistances, knnIndexes });\n }\n };\n });\n }\n const results = await Promise.all(promises);\n const knnRes = { knnDistances: new Array(values.length).fill(null).map(() => new Array(nNeighbours).fill(99999)),\n knnIndexes: new Array(values.length).fill(null).map(() => new Array(nNeighbours).fill(-1)) };\n for (const res of results) {\n for (let i = 0; i < values.length; ++i) {\n for (let j = 0; j < res.knnDistances[i]?.length ?? 0; ++j) {\n insertSmaller(knnRes.knnDistances[i], knnRes.knnIndexes[i], res.knnDistances[i][j], res.knnIndexes[i][j]);\n }\n }\n }\n return knnRes;\n }\n async getSampleDistances(values, fnName, opts = {}) {\n const thresholdWorkers = new Array(this._workerCount).fill(null)\n .map(() => new Worker(new URL('./sparse-matrix-threshold-worker', import.meta.url)));\n // data may be sorted by clusters, which will hinder the random sampling\n // so we shuffle it first\n const shuffledValues = values.slice();\n for (let i = shuffledValues.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [shuffledValues[i], shuffledValues[j]] = [shuffledValues[j], shuffledValues[i]];\n }\n try {\n const matSize = values.length * (values.length - 1) / 2;\n const chunkSize = Math.floor(matSize / this._workerCount);\n const maxSampleSize = 1000000;\n const sampleSise = Math.max(Math.min(matSize / 1000, maxSampleSize), Math.min(matSize, maxSampleSize));\n const testSetSizePerWorker = Math.floor(sampleSise / this._workerCount);\n const tPromises = new Array(this._workerCount);\n for (let idx = 0; idx < this._workerCount; idx++) {\n tPromises[idx] = new Promise((resolveWorker, rejectWorker) => {\n const startIdx = idx * chunkSize;\n const endIdx = idx === this._workerCount - 1 ? matSize : (idx + 1) * chunkSize;\n thresholdWorkers[idx].postMessage({ values: shuffledValues, startIdx, endIdx, sampleLength: testSetSizePerWorker, fnName, opts });\n thresholdWorkers[idx].onmessage = ({ data: { error, distance } }) => {\n thresholdWorkers[idx].terminate();\n if (error) {\n rejectWorker(error);\n }\n else {\n resolveWorker({ distance });\n }\n };\n });\n }\n const results = await Promise.all(tPromises);\n const fullSize = results.reduce((acc, val) => acc + val.distance.length, 0);\n const distance = new Float32Array(fullSize);\n let offset = 0;\n for (const res of results) {\n distance.set(res.distance, offset);\n offset += res.distance.length;\n }\n distance.sort();\n return distance;\n }\n catch (e) {\n thresholdWorkers?.forEach((w) => w?.terminate());\n console.error(e);\n return new Float32Array(1).fill(0.5);\n }\n }\n async getMinimalThreshold(values, fnName, opts = {}) {\n //We need to calculate the minimal threshold first,\n //in order to get matrix such that it does not exceed the maximum size of 1GB\n //we have 3 return arrays, each 4 bites per element, so if the maximum size of the matrix is 1GB,\n const max_Sparse_matrix_size = 70000000;\n try {\n const matSize = values.length * (values.length - 1) / 2;\n const distance = await this.getSampleDistances(values, fnName, opts);\n const fractionIndex = Math.floor(max_Sparse_matrix_size / matSize * distance.length);\n let threshold = 1 - distance[fractionIndex];\n // threshold = Math.max(threshold, 0.3);\n return threshold;\n }\n catch (e) {\n console.error(e);\n return 0.5;\n }\n }\n static calcSync(values, fnName, distanceFn, threshold) {\n const i = [];\n const j = [];\n const distances = [];\n let cnt = 0;\n let mi = 0;\n let mj = 0;\n const fullSize = values.length * (values.length - 1) / 2;\n while (cnt < fullSize) {\n //const value = seq1List[mi] && seq1List[mj] ? hamming(seq1List[mi], seq1List[mj]) : 0;\n const value = !isNil(values[mi]) && !isNil(values[mj]) ?\n distanceFn(values[mi], values[mj]) : 1;\n const similarity = Object.values(BitArrayMetricsNames).some((a) => a === fnName) ? getSimilarityFromDistance(value) : 1 - value;\n if (similarity >= threshold) {\n i.push(mi);\n j.push(mj);\n distances.push(value);\n }\n cnt++;\n mj++;\n if (mj === values.length) {\n mi++;\n mj = mi + 1;\n }\n }\n const iArray = new Int32Array(i);\n const jArray = new Int32Array(j);\n const distanceArray = new Float32Array(distances);\n return { i: iArray, j: jArray, distance: distanceArray };\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhcnNlLW1hdHJpeC1zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3BhcnNlLW1hdHJpeC1zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxvQkFBb0IsRUFBeUIsTUFBTSxrQkFBa0IsQ0FBQztBQUMvRSxPQUFPLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQztBQWEvQyxNQUFNLE9BQU8sbUJBQW1CO0lBRTVCO1FBQ0UsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxtQkFBbUIsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVNLEtBQUssQ0FBQyxJQUFJLENBQUksTUFBZ0IsRUFBRSxNQUFvQixFQUFFLFNBQWlCLEVBQUUsT0FBMkIsRUFBRTtRQUczRyxxQkFBcUI7UUFDckIsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3hELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUUxRCxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsTUFBTSxHQUFHLEtBQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZHLElBQUksU0FBUyxHQUFHLFlBQVksRUFBRTtZQUM1QixPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQy9DLFNBQVMsR0FBRyxZQUFZLENBQUM7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b3J0IHsgZ2V0U2ltaWxhcml0eUZyb21EaXN0YW5jZSB9IGZyb20gXCIuLi9kaXN0YW5jZS1tZXRyaWNzLW1ldGhvZHNcIjtcbmltcG9ydCB7IEJpdEFycmF5TWV0cmljc05hbWVzLCBLbm93bk1ldHJpY3MsIE1lYXN1cmUgfSBmcm9tIFwiLi4vdHlwZWQtbWV0cmljc1wiO1xuaW1wb3J0IHsgaW5zZXJ0U21hbGxlciwgaXNOaWwgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5leHBvcnQgdHlwZSBTcGFyc2VNYXRyaXhSZXN1bHQgPSB7XG4gIGk6IEludDMyQXJyYXksXG4gIGo6IEludDMyQXJyYXksXG4gIGRpc3RhbmNlOiBGbG9hdDMyQXJyYXksXG4gIGlkeD86IG51bWJlclxufTtcblxuZXhwb3J0IHR5cGUgS25uUmVzdWx0ID0ge1xuICBrbm5EaXN0YW5jZXM6IG51bWJlcltdW10sXG4gIGtubkluZGV4ZXM6IG51bWJlcltdW11cbn1cbmV4cG9ydCBjbGFzcyBTcGFyc2VNYXRyaXhTZXJ2aWNlIHtcbiAgICBwcml2YXRlIF93b3JrZXJDb3VudDogbnVtYmVyO1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgdGhpcy5fd29ya2VyQ291bnQgPSBNYXRoLm1heChuYXZpZ2F0b3IuaGFyZHdhcmVDb25jdXJyZW5jeSAtIDIsIDEpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBjYWxjPFQ+KHZhbHVlczogQXJyYXk8VD4sIGZuTmFtZTogS25vd25NZXRyaWNzLCB0aHJlc2hvbGQ6IG51bWJlciwgb3B0czoge1tfOiBzdHJpbmddOiBhbnl9ID0ge30pIHtcblxuXG4gICAgICAvL3NpemUgb2YgZnVsbCBtYXRyaXhcbiAgICAgIGNvbnN0IG1hdFNpemUgPSB2YWx1ZXMubGVuZ3RoICogKHZhbHVlcy5sZW5ndGggLSAxKSAvIDI7XG4gICAgICBjb25zdCBjaHVua1NpemUgPSBNYXRoLmZsb29yKG1hdFNpemUgLyB0aGlzLl93b3JrZXJDb3VudCk7XG5cbiAgICAgIGNvbnN0IG1pblRocmVzaG9sZCA9IHZhbHVlcy5sZW5ndGggPiAyMF8wMDAgPyBhd2FpdCB0aGlzLmdldE1pbmltYWxUaHJlc2hvbGQodmFsdWVzLCBmbk5hbWUsIG9wdHMpIDogMDtcbiAgICAgIGlmICh0aHJlc2hvbGQgPCBtaW5UaHJlc2hvbGQpIHtcbiAgICAgICAgY29uc29sZS5sb2coYHVzaW5nIHRocmVzaG9sZCAke21pblRocmVzaG9sZH1gKTtcbiAgICAgICAgdGhyZXNob2xkID0gbWluVGhyZXNob2xkO1xuICAgICAgfVxuICAgICAgb3B0c1sndGhyZXNob2xkJ10gPSB0aHJlc2hvbGQ7XG4gICAgICBjb25zdCBwcm9taXNlcyA9XG4gICAgICAgIG5ldyBBcnJheTxQcm9taXNlPFNwYXJzZU1hdHJpeFJlc3VsdD4+KHRoaXMuX3dvcmtlckNvdW50KTtcblxuICAgICAgY29uc3Qgd29ya2VycyA9IG5ldyBBcnJheSh0aGlzLl93b3JrZXJDb3VudCkuZmlsbChudWxsKS5tYXAoKCkgPT4gbmV3IFdvcmtlcihuZXcgVVJMKCcuL3NwYXJzZS1tYXRyaXgtd29ya2VyJywgaW1wb3J0Lm1ldGEudXJsKSkpO1xuICAgICAgZm9yIChsZXQgaWR4ID0gMDsgaWR4IDwgdGhpcy5fd29ya2VyQ291bnQ7IGlkeCsrKSB7XG4gICAgICAgIHByb21pc2VzW2lkeF0gPSBuZXcgUHJvbWlzZSgocmVzb2x2ZVdvcmtlciwgcmVqZWN0V29ya2VyKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc3RhcnRJZHggPSBpZHggKiBjaHVua1NpemU7XG4gICAgICAgICAgY29uc3QgZW5kSWR4ID0gaWR4ID09PSB0aGlzLl93b3JrZXJDb3VudCAtIDEgPyBtYXRTaXplIDogKGlkeCArIDEpICogY2h1bmtTaXplO1xuICAgICAgICAgIGlmIChlbmRJZHggPD0gc3RhcnRJZHgpIFxuICAgICAgICAgICAgcmVzb2x2ZVdvcmtlcih7aTogbmV3IEludDMyQXJyYXkoMCksIGo6IG5ldyBJbnQzMkFycmF5KDApLCBkaXN0YW5jZTogbmV3IEZsb2F0MzJBcnJheSgwKSwgaWR4fSk7XG4gICAgICAgICAgd29ya2Vyc1tpZHhdLnBvc3RNZXNzYWdlKHt2YWx1ZXMsIHN0YXJ0SWR4LCBlbmRJZHgsIHRocmVzaG9sZCwgZm5OYW1lLCBvcHRzfSk7XG4gICAgICAgICAgd29ya2Vyc1tpZHhdLm9ubWVzc2FnZSA9ICh7ZGF0YToge2Vycm9yLCBpLCBqLCBkaXN0YW5jZX19KTogdm9pZCA9PiB7XG4gICAgICAgICAgICBpZiAoZXJyb3IpIHsgXG4gICAgICAgICAgICAgIHdvcmtlcnNbaWR4XS50ZXJtaW5hdGUoKTtcbiAgICAgICAgICAgICAgcmVqZWN0V29ya2VyKGVycm9yKTsgXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB3b3JrZXJzW2lkeF0udGVybWluYXRlKCk7XG4gICAgICAgICAgICAgIHJlc29sdmVXb3JrZXIoe2ksIGosIGRpc3RhbmNlLCBpZHh9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICAgIGNvbnN0IGZ1bGxTaXplID0gcmVzdWx0cy5yZWR1Y2UoKGFjYywgdmFsKSA9PiBhY2MgKyB2YWwuaS5sZW5ndGgsIDApO1xuICAgICAgY29uc3QgaSA9IG5ldyBJbnQzMkFycmF5KGZ1bGxTaXplKTtcbiAgICAgIGNvbnN0IGogPSBuZXcgSW50MzJBcnJheShmdWxsU2l6ZSk7XG4gICAgICBjb25zdCBkaXN0YW5jZSA9IG5ldyBGbG9hdDMyQXJyYXkoZnVsbFNpemUpO1xuICAgICAgbGV0IG9mZnNldCA9IDA7XG4gICAgICAvLyBzZXR0aW5nIHRoZSByZXN1bHRzXG4gICAgICBmb3IgKGNvbnN0IHJlcyBvZiByZXN1bHRzKSB7XG4gICAgICAgIGkuc2V0KHJlcy5pLCBvZmZzZXQpO1xuICAgICAgICBqLnNldChyZXMuaiwgb2Zmc2V0KTtcbiAgICAgICAgZGlzdGFuY2Uuc2V0KHJlcy5kaXN0YW5jZSwgb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0ICs9IHJlcy5pLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7aSwgaiwgZGlzdGFuY2V9O1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXRLTk48VD4odmFsdWVzOiBBcnJheTxUPiwgZm5OYW1lOiBLbm93bk1ldHJpY3MsIG5OZWlnaGJvdXJzOiBudW1iZXIgPSAxNSwgb3B0czoge1tfOiBzdHJpbmddOiBhbnl9ID0ge30pIHtcbiAgICAgIGNvbnN0IG1hdFNpemUgPSB2YWx1ZXMubGVuZ3RoICogKHZhbHVlcy5sZW5ndGggLSAxKSAvIDI7XG4gICAgICBjb25zdCBjaHVua1NpemUgPSBNYXRoLmZsb29yKG1hdFNpemUgLyB0aGlzLl93b3JrZXJDb3VudCk7XG4gICAgICBjb25zdCBwcm9taXNlcyA9XG4gICAgICAgIG5ldyBBcnJheTxQcm9taXNlPEtublJlc3VsdD4+KHRoaXMuX3dvcmtlckNvdW50KTtcbiAgICAgIGNvbnN0IHdvcmtlcnMgPSBuZXcgQXJyYXkodGhpcy5fd29ya2VyQ291bnQpLmZpbGwobnVsbCkubWFwKCgpID0+IG5ldyBXb3JrZXIobmV3IFVSTCgnLi9rbm4td29ya2VyJywgaW1wb3J0Lm1ldGEudXJsKSkpO1xuICAgICAgZm9yIChsZXQgaWR4ID0gMDsgaWR4IDwgdGhpcy5fd29ya2VyQ291bnQ7IGlkeCsrKSB7XG4gICAgICAgIHByb21pc2VzW2lkeF0gPSBuZXcgUHJvbWlzZSgocmVzb2x2ZVdvcmtlciwgcmVqZWN0V29ya2VyKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc3RhcnRJZHggPSBpZHggKiBjaHVua1NpemU7XG4gICAgICAgICAgY29uc3QgZW5kSWR4ID0gaWR4ID09PSB0aGlzLl93b3JrZXJDb3VudCAtIDEgPyBtYXRTaXplIDogKGlkeCArIDEpICogY2h1bmtTaXplO1xuICAgICAgICAgIGlmIChlbmRJZHggPD0gc3RhcnRJZHgpIFxuICAgICAgICAgICAgcmVzb2x2ZVdvcmtlcih7a25uRGlzdGFuY2VzOiBuZXcgQXJyYXkoMCksIGtubkluZGV4ZXM6IG5ldyBBcnJheSgwKX0pO1xuICAgICAgICAgIHdvcmtlcnNbaWR4XS5wb3N0TWVzc2FnZSh7dmFsdWVzLCBzdGFydElkeCwgZW5kSWR4LCBmbk5hbWUsIG9wdHMsIG5OZWlnaGJvdXJzfSk7XG4gICAgICAgICAgd29ya2Vyc1tpZHhdLm9ubWVzc2FnZSA9ICh7ZGF0YToge2Vycm9yLCBrbm5EaXN0YW5jZXMsIGtubkluZGV4ZXN9fSk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7IFxuICAgICAgICAgICAgICB3b3JrZXJzW2lkeF0udGVybWluYXRlKCk7XG4gICAgICAgICAgICAgIHJlamVjdFdvcmtlcihlcnJvcik7IFxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgd29ya2Vyc1tpZHhdLnRlcm1pbmF0ZSgpO1xuICAgICAgICAgICAgICByZXNvbHZlV29ya2VyKHtrbm5EaXN0YW5jZXMsIGtubkluZGV4ZXN9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgXG4gICAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICAgICAgY29uc3Qga25uUmVzOiBLbm5SZXN1bHQgPSB7a25uRGlzdGFuY2VzOiBuZXcgQXJyYXkodmFsdWVzLmxlbmd0aCkuZmlsbChudWxsKS5tYXAoKCkgPT4gbmV3IEFycmF5PG51bWJlcj4obk5laWdoYm91cnMpLmZpbGwoOTk5OTkpKSxcbiAgICAgICAga25uSW5kZXhlczogbmV3IEFycmF5KHZhbHVlcy5sZW5ndGgpLmZpbGwobnVsbCkubWFwKCgpID0+IG5ldyBBcnJheTxudW1iZXI+KG5OZWlnaGJvdXJzKS5maWxsKC0xKSl9O1xuICAgICAgZm9yIChjb25zdCByZXMgb2YgcmVzdWx0cykge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgcmVzLmtubkRpc3RhbmNlc1tpXT8ubGVuZ3RoID8/IDA7ICsraikge1xuICAgICAgICAgICAgaW5zZXJ0U21hbGxlcihrbm5SZXMua25uRGlzdGFuY2VzW2ldLCBrbm5SZXMua25uSW5kZXhlc1tpXSwgcmVzLmtubkRpc3RhbmNlc1tpXVtqXSwgcmVzLmtubkluZGV4ZXNbaV1bal0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGtublJlcztcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0U2FtcGxlRGlzdGFuY2VzPFQ+KHZhbHVlczogQXJyYXk8VD4sIGZuTmFtZTogS25vd25NZXRyaWNzLCBvcHRzOiB7W186IHN0cmluZ106IGFueX0gPSB7fSk6IFByb21pc2U8RmxvYXQzMkFycmF5PiB7XG4gICAgICBjb25zdCB0aHJlc2hvbGRXb3JrZXJzID0gbmV3IEFycmF5KHRoaXMuX3dvcmtlckNvdW50KS5maWxsKG51bGwpXG4gICAgICAgIC5tYXAoKCkgPT4gbmV3IFdvcmtlcihuZXcgVVJMKCcuL3NwYXJzZS1tYXRyaXgtdGhyZXNob2xkLXdvcmtlcicsIGltcG9ydC5tZXRhLnVybCkpKTtcbiAgICAgIC8vIGRhdGEgbWF5IGJlIHNvcnRlZCBieSBjbHVzdGVycywgd2hpY2ggd2lsbCBoaW5kZXIgdGhlIHJhbmRvbSBzYW1wbGluZ1xuICAgICAgLy8gc28gd2Ugc2h1ZmZsZSBpdCBmaXJzdFxuICAgICAgY29uc3Qgc2h1ZmZsZWRWYWx1ZXMgPSB2YWx1ZXMuc2xpY2UoKTtcbiAgICAgIGZvciAobGV0IGkgPSBzaHVmZmxlZFZhbHVlcy5sZW5ndGggLSAxOyBpID4gMDsgaS0tKSB7XG4gICAgICAgIGNvbnN0IGogPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAoaSArIDEpKTtcbiAgICAgICAgW3NodWZmbGVkVmFsdWVzW2ldLCBzaHVmZmxlZFZhbHVlc1tqXV0gPSBbc2h1ZmZsZWRWYWx1ZXNbal0sIHNodWZmbGVkVmFsdWVzW2ldXTtcbiAgICAgIH1cbiAgXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBtYXRTaXplID0gdmFsdWVzLmxlbmd0aCAqICh2YWx1ZXMubGVuZ3RoIC0gMSkgLyAyO1xuICAgICAgICBjb25zdCBjaHVua1NpemUgPSBNYXRoLmZsb29yKG1hdFNpemUgLyB0aGlzLl93b3JrZXJDb3VudCk7XG4gICAgICAgIGNvbnN0IG1heFNhbXBsZVNpemUgPSAxXzAwMF8wMDA7XG4gICAgICAgIGNvbnN0IHNhbXBsZVNpc2UgPSBNYXRoLm1heChNYXRoLm1pbihtYXRTaXplIC8gMTAwMCwgbWF4U2FtcGxlU2l6ZSksIE1hdGgubWluKG1hdFNpemUsIG1heFNhbXBsZVNpemUpKTtcbiAgICAgICAgY29uc3QgdGVzdFNldFNpemVQZXJXb3JrZXIgPSBNYXRoLmZsb29yKHNhbXBsZVNpc2UgLyB0aGlzLl93b3JrZXJDb3VudCk7XG4gICAgICAgIGNvbnN0IHRQcm9taXNlcyA9IG5ldyBBcnJheTxQcm9taXNlPHtkaXN0YW5jZTogRmxvYXQzMkFycmF5fT4+KHRoaXMuX3dvcmtlckNvdW50KTtcblxuICAgICAgICBmb3IgKGxldCBpZHggPSAwOyBpZHggPCB0aGlzLl93b3JrZXJDb3VudDsgaWR4KyspIHtcbiAgICAgICAgICB0UHJvbWlzZXNbaWR4XSA9IG5ldyBQcm9taXNlKChyZXNvbHZlV29ya2VyLCByZWplY3RXb3JrZXIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0SWR4ID0gaWR4ICogY2h1bmtTaXplO1xuICAgICAgICAgICAgY29uc3QgZW5kSWR4ID0gaWR4ID09PSB0aGlzLl93b3JrZXJDb3VudCAtIDEgPyBtYXRTaXplIDogKGlkeCArIDEpICogY2h1bmtTaXplO1xuICAgICAgICAgICAgdGhyZXNob2xkV29ya2Vyc1tpZHhdLnBvc3RNZXNzYWdlKHt2YWx1ZXM6IHNodWZmbGVkVmFsdWVzLCBzdGFydElkeCwgZW5kSWR4LCBzYW1wbGVMZW5ndGg6IHRlc3RTZXRTaXplUGVyV29ya2VyLCBmbk5hbWUsIG9wdHN9KTtcbiAgICAgICAgICAgIHRocmVzaG9sZFdvcmtlcnNbaWR4XS5vbm1lc3NhZ2UgPSAoe2RhdGE6IHtlcnJvciwgZGlzdGFuY2V9fSk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgICB0aHJlc2hvbGRXb3JrZXJzW2lkeF0udGVybWluYXRlKCk7XG4gICAgICAgICAgICAgIGlmIChlcnJvcikgeyByZWplY3RXb3JrZXIoZXJyb3IpOyB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc29sdmVXb3JrZXIoe2Rpc3RhbmNlfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwodFByb21pc2VzKTtcbiAgICAgICAgY29uc3QgZnVsbFNpemUgPSByZXN1bHRzLnJlZHVjZSgoYWNjLCB2YWwpID0+IGFjYyArIHZhbC5kaXN0YW5jZS5sZW5ndGgsIDApO1xuICAgICAgICBjb25zdCBkaXN0YW5jZSA9IG5ldyBGbG9hdDMyQXJyYXkoZnVsbFNpemUpO1xuICAgICAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICAgICAgZm9yIChjb25zdCByZXMgb2YgcmVzdWx0cykge1xuICAgICAgICAgIGRpc3RhbmNlLnNldChyZXMuZGlzdGFuY2UsIG9mZnNldCk7XG4gICAgICAgICAgb2Zmc2V0ICs9IHJlcy5kaXN0YW5jZS5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgZGlzdGFuY2Uuc29ydCgpO1xuXG4gICAgICAgIHJldHVybiBkaXN0YW5jZTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyZXNob2xkV29ya2Vycz8uZm9yRWFjaCgodykgPT4gdz8udGVybWluYXRlKCkpO1xuICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheSgxKS5maWxsKDAuNSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBnZXRNaW5pbWFsVGhyZXNob2xkPFQ+KHZhbHVlczogQXJyYXk8VD4sIGZuTmFtZTogS25vd25NZXRyaWNzLCBvcHRzOiB7W186IHN0cmluZ106IGFueX0gPSB7fSkge1xuXG4gICAgICAvL1dlIG5lZWQgdG8gY2FsY3VsYXRlIHRoZSBtaW5pbWFsIHRocmVzaG9sZCBmaXJzdCxcbiAgICAgIC8vaW4gb3JkZXIgdG8gZ2V0IG1hdHJpeCBzdWNoIHRoYXQgaXQgZG9lcyBub3QgZXhjZWVkIHRoZSBtYXhpbXVtIHNpemUgb2YgMUdCXG4gICAgICAvL3dlIGhhdmUgMyByZXR1cm4gYXJyYXlzLCBlYWNoIDQgYml0ZXMgcGVyIGVsZW1lbnQsIHNvIGlmIHRoZSBtYXhpbXVtIHNpemUgb2YgdGhlIG1hdHJpeCBpcyAxR0IsXG4gICAgICBjb25zdCBtYXhfU3BhcnNlX21hdHJpeF9zaXplID0gNzBfMDAwXzAwMDtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IG1hdFNpemUgPSB2YWx1ZXMubGVuZ3RoICogKHZhbHVlcy5sZW5ndGggLSAxKSAvIDI7XG4gICAgICAgIGNvbnN0IGRpc3RhbmNlID0gYXdhaXQgdGhpcy5nZXRTYW1wbGVEaXN0YW5jZXModmFsdWVzLCBmbk5hbWUsIG9wdHMpO1xuICAgICAgICBjb25zdCBmcmFjdGlvbkluZGV4ID0gTWF0aC5mbG9vcihtYXhfU3BhcnNlX21hdHJpeF9zaXplIC8gbWF0U2l6ZSAqIGRpc3RhbmNlLmxlbmd0aCk7XG4gICAgICAgIGxldCB0aHJlc2hvbGQgPSAxIC0gZGlzdGFuY2VbZnJhY3Rpb25JbmRleF07XG4gICAgICAgIC8vIHRocmVzaG9sZCA9IE1hdGgubWF4KHRocmVzaG9sZCwgMC4zKTtcbiAgICAgICAgcmV0dXJuIHRocmVzaG9sZDtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgcmV0dXJuIDAuNTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIGNhbGNTeW5jPFQ+ICh2YWx1ZXM6IEFycmF5PFQ+IHwgQXJyYXlMaWtlPFQ+LCBmbk5hbWU6IEtub3duTWV0cmljcywgZGlzdGFuY2VGbjogRnVuY3Rpb24sIHRocmVzaG9sZDogbnVtYmVyKSB7XG4gICAgICBjb25zdCBpOiBudW1iZXJbXSA9IFtdO1xuICAgICAgY29uc3QgajogbnVtYmVyW10gPSBbXTtcbiAgICAgIGNvbnN0IGRpc3RhbmNlczogbnVtYmVyW10gPSBbXTtcbiAgICAgIGxldCBjbnQgPSAwO1xuICAgICAgbGV0IG1pID0gMDtcbiAgICAgIGxldCBtaiA9IDA7XG4gICAgICBjb25zdCBmdWxsU2l6ZSA9IHZhbHVlcy5sZW5ndGggKiAodmFsdWVzLmxlbmd0aCAtIDEpIC8gMjtcbiAgICAgIHdoaWxlIChjbnQgPCBmdWxsU2l6ZSkge1xuICAgICAgICAvL2NvbnN0IHZhbHVlID0gc2VxMUxpc3RbbWldICYmIHNlcTFMaXN0W21qXSA/IGhhbW1pbmcoc2VxMUxpc3RbbWldLCBzZXExTGlzdFttal0pIDogMDtcbiAgICAgICAgY29uc3QgdmFsdWUgPSAhaXNOaWwodmFsdWVzW21pXSkgJiYgIWlzTmlsKHZhbHVlc1ttal0pID9cbiAgICAgICAgICBkaXN0YW5jZUZuKHZhbHVlc1ttaV0sIHZhbHVlc1ttal0pIDogMTtcbiAgICAgICAgY29uc3Qgc2ltaWxhcml0eSA9IE9iamVjdC52YWx1ZXMoQml0QXJyYXlNZXRyaWNzTmFtZXMpLnNvbWUoKGEpID0+IGEgPT09IGZuTmFtZSkgPyBnZXRTaW1pbGFyaXR5RnJvbURpc3RhbmNlKHZhbHVlKSA6IDEgLSB2YWx1ZTtcbiAgICAgICAgaWYgKHNpbWlsYXJpdHkgPj0gdGhyZXNob2xkKSB7XG4gICAgICAgICAgaS5wdXNoKG1pKTtcbiAgICAgICAgICBqLnB1c2gobWopO1xuICAgICAgICAgIGRpc3RhbmNlcy5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBjbnQrKztcbiAgICAgICAgbWorKztcbiAgICAgICAgaWYgKG1qID09PSB2YWx1ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgbWkrKztcbiAgICAgICAgICBtaiA9IG1pICsgMTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIFxuICAgICAgY29uc3QgaUFycmF5ID0gbmV3IEludDMyQXJyYXkoaSk7XG4gICAgICBjb25zdCBqQXJyYXkgPSBuZXcgSW50MzJBcnJheShqKTtcbiAgICAgIGNvbnN0IGRpc3RhbmNlQXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KGRpc3RhbmNlcyk7XG5cbiAgICAgIHJldHVybiB7aTogaUFycmF5LCBqOiBqQXJyYXksIGRpc3RhbmNlOiBkaXN0YW5jZUFycmF5fTtcbiAgICB9XG59Il19","/* eslint-disable max-len */\nimport { TSNE } from '@keckelt/tsne';\nimport { Vector, } from '@datagrok-libraries/utils/src/type-declarations';\nimport { transposeMatrix, assert, } from '@datagrok-libraries/utils/src/vector-operations';\nimport { SPEBase, PSPEBase, OriginalSPE } from './spe';\nimport { Measure, AvailableMetrics, isBitArrayMetric } from './typed-metrics/typed-metrics';\nimport BitArray from '@datagrok-libraries/utils/src/bit-array';\nimport { UMAP } from './umap';\nimport { DistanceMatrix, DistanceMatrixService, distanceMatrixProxy, dmLinearIndex } from './distance-matrix';\nimport { SparseMatrixService } from './distance-matrix/sparse-matrix-service';\nexport var DimReductionMethods;\n(function (DimReductionMethods) {\n DimReductionMethods[\"UMAP\"] = \"UMAP\";\n DimReductionMethods[\"T_SNE\"] = \"t-SNE\";\n})(DimReductionMethods || (DimReductionMethods = {}));\n/** Umap uses precalculated distance matrix to save time. though for too much data, memory becomes constraint.\n * if we have 100 000 rows, distance matrix will take ~10gb of memory and probably overflow.\n */\nexport const MAX_DISTANCE_MATRIX_ROWS = 20000;\nexport class UMAPOptions {\n constructor() {\n this.learningRate = { uiName: 'Learinig rate', value: 1, tooltip: 'The initial learning rate for the embedding optimization' };\n this.nComponents = { uiName: 'Components', value: 2, tooltip: 'The number of components (dimensions) to project the data to' };\n this.nEpochs = { uiName: 'Epochs', value: 0, tooltip: 'The number of epochs to optimize embeddings via SGD. Computed automatically if set to 0' };\n this.nNeighbors = { uiName: 'Neighbors', value: 15, tooltip: 'The number of nearest neighbors to construct the fuzzy manifold' };\n this.spread = { uiName: 'Spread', value: 1, tooltip: 'The effective scale of embedded points, used with min distance to control the clumped/dispersed nature of the embedding' };\n this.minDist = { uiName: 'Min distance', value: 0.1, tooltip: 'The effective minimum distance between embedded points, used with spread to control the clumped/dispersed nature of the embedding' };\n }\n ;\n}\nexport class TSNEOptions {\n constructor() {\n this.epsilon = { uiName: 'Epsilon', value: 10, tooltip: 'Epsilon is learning rate' };\n this.perplexity = { uiName: 'Perplexity', value: 30, tooltip: 'Roughly how many neighbors each point influences' };\n this.dim = { uiName: 'Dimensionality', value: 2, tooltip: 'Dimensionality of the embedding' };\n }\n ;\n}\n/** Abstract dimensionality reducer */\nclass Reducer {\n constructor(options) {\n this.data = options.data;\n }\n}\n/** t-SNE dimensionality reduction. */\nclass TSNEReducer extends Reducer {\n /**\n * Creates an instance of TSNEReducer.\n * @param {Options} options Options to pass to the constructor.\n * @memberof TSNEReducer\n */\n constructor(options) {\n super(options);\n this.reducer = new TSNE(options);\n this.iterations = options?.iterations ?? 100;\n this.distanceFname = options.distanceFname;\n this.distanceFn = options.distanceFn;\n }\n /**\n * Embeds the data given into the two-dimensional space using t-SNE method.\\\n * @param {boolean} [parallelDistanceWorkers] Whether to use parallel distance workers.\n * @return {any} Cartesian coordinate of this embedding and distance matrix where applicable.\n */\n async transform(parallelDistanceWorkers) {\n const distance = parallelDistanceWorkers ? await (async () => {\n const matrixService = new DistanceMatrixService(true, false);\n try {\n const dist = await matrixService.calc(this.data, this.distanceFname);\n matrixService.terminate();\n return dist;\n }\n catch (e) {\n matrixService.terminate();\n throw e;\n }\n })() :\n (() => { const ret = DistanceMatrix.calc(this.data, (a, b) => this.distanceFn(a, b)); ret.normalize(); return ret.data; })();\n const matrixProxy = distanceMatrixProxy(distance, this.data.length);\n this.reducer.initDataDist(matrixProxy);\n for (let i = 0; i < this.iterations; ++i)\n this.reducer.step(); // every time you call this, solution gets better\n return { distance: distance, embedding: this.reducer.getSolution() };\n }\n}\n/**\n * Implements UMAP dimensionality reduction.\n *\n * @class UMAPReducer\n * @extends {Reducer}\n */\nclass UMAPReducer extends Reducer {\n /**\n * Creates an instance of UMAPReducer.\n * @param {Options} options Options to pass to the constructor.\n * @memberof UMAPReducer\n */\n constructor(options) {\n super(options);\n assert('distanceFname' in options);\n assert('distanceFn' in options);\n this.distanceFnArgs = options?.distanceFnArgs;\n this.distanceFn = options.distanceFn;\n this.progressFunc = options.progressFunc;\n this.distanceFname = options.distanceFname;\n this.dmIndexFunc = dmLinearIndex(this.data.length);\n //Umap uses vector indexing, so we need to create an array of vectors as indeces.\n this.vectors = new Array(this.data.length).fill(0).map((_, i) => i);\n options.distanceFn = this._encodedDistance.bind(this);\n if (this.data.length < 15)\n options.nNeighbors = this.data.length - 1;\n this.reducer = new UMAP(options);\n // this.reducer.distanceFn = this._encodedDistance.bind(this);\n }\n /**\n * Custom distance wrapper to have numeric inputs instead of string ones.\n *\n * @protected\n * @param {number[]} a The first item.\n * @param {number[]} b The first item.\n * @return {number} Distance metric.\n * @memberof UMAPReducer\n */\n // protected _encodedDistanceMatrix(a: number, b: number): number {\n // if (a === b)\n // return 0;\n // if (a > b)\n // return this.distanceMatrix![this.dmIndexFunc(b, a)];\n // return this.distanceMatrix![this.dmIndexFunc(a, b)];\n // }\n _encodedSparseMatrix(a, b) {\n return this.sparseMatrix.get(a)?.get(b) ?? this.sparseMatrix.get(b)?.get(a) ?? 1;\n }\n _encodedDistance(a, b) {\n return this.distanceFn(this.data[a], this.data[b]);\n }\n /**\n * Embeds the data given into the two-dimensional space using UMAP method.\n * @param {boolean} [_parallelDistanceWorkers] Whether to use parallel distance matrix workers.\n * @return {any} Cartesian coordinate of this embedding.\n */\n async transform(_parallelDistanceWorkers) {\n console.time('knn graph');\n const knnRes = await new SparseMatrixService().getKNN(this.data, this.distanceFname, this.reducer.neighbors, this.distanceFnArgs);\n console.timeEnd('knn graph');\n this.reducer.setPrecomputedKNN(knnRes.knnIndexes, knnRes.knnDistances);\n // needed so that garbage collector can free memory from distance matrix\n await new Promise((resolve) => {\n setTimeout(() => {\n resolve();\n }, 500);\n });\n const embedding = await this.reducer.fitAsync(this.vectors, (epoc) => {\n if (this.progressFunc)\n this.progressFunc(epoc, this.reducer.getNEpochs(), this.reducer.getEmbedding());\n });\n function arrayCast2Coordinates(data) {\n return new Array(data.length).fill(0).map((_, i) => (Vector.from(data[i])));\n }\n return { embedding: arrayCast2Coordinates(embedding), ...(this.distanceMatrix ? { distance: this.distanceMatrix } : {}) };\n }\n}\n/**\n * Implements original SPE dimensionality reduction.\n *\n * @class SPEReducer\n * @extends {Reducer}\n */\nclass SPEReducer extends Reducer {\n /**\n * Creates an instance of SPEReducer.\n * @param {Options} options Options to pass to the constructor.\n * @memberof SPEReducer\n */\n constructor(options) {\n super(options);\n this.reducer = new SPEBase(options);\n }\n /**\n * Embeds the data given into the two-dimensional space using the original SPE method.\n * @return {any} Cartesian coordinate of this embedding and distance matrix where applicable.\n */\n async transform() {\n const emb = await this.reducer.embed(this.data);\n return { distance: this.reducer.distance, embedding: emb };\n }\n}\n/**\n * Implements modified SPE dimensionality reduction.\n *\n * @class PSPEReducer\n * @extends {Reducer}\n */\nclass PSPEReducer extends Reducer {\n /**\n * Creates an instance of PSPEReducer.\n * @param {Options} options Options to pass to the constructor.\n * @memberof PSPEReducer\n */\n constructor(options) {\n super(options);\n this.reducer = new PSPEBase(options);\n }\n /**\n * Embeds the data given into the two-dimensional space using the modified SPE method.\n * @return {any} Cartesian coordinate of this embedding and distance matrix where applicable.\n */\n async transform() {\n const emb = await this.reducer.embed(this.data);\n return { distance: this.reducer.distance, embedding: emb };\n }\n}\n/**\n * Implements original SPE dimensionality reduction.\n *\n * @class OriginalSPEReducer\n * @extends {Reducer}\n */\nclass OriginalSPEReducer extends Reducer {\n /**\n * Creates an instance of OriginalSPEReducer.\n * @param {Options} options Options to pass to the constructor.\n * @memberof OriginalSPEReducer\n */\n constructor(options) {\n super(options);\n this.reducer = new OriginalSPE(options);\n }\n /**\n * Embeds the data given into the two-dimensional space using the original SPE method.\n * @return {any} Cartesian coordinate of this embedding and distance matrix where applicable.\n */\n async transform() {\n const emb = await this.reducer.embed(this.data);\n return { distance: this.reducer.distance, embedding: emb };\n }\n}\nconst AvailableReducers = {\n 'UMAP': UMAPReducer,\n 't-SNE': TSNEReducer,\n 'SPE': SPEReducer,\n 'pSPE': PSPEReducer,\n 'OriginalSPE': OriginalSPEReducer,\n};\n/**\n * Unified class implementing different dimensionality reduction methods.\n *\n * @export\n * @class DimensionalityReducer\n */\nexport class DimensionalityReducer {\n /**\n * Creates an instance of DimensionalityReducer.\n * @param {any[]} data Vectors to embed.\n * @param {KnownMethods} method Embedding method to be applied\n * @param {KnownMetrics} metric Distance metric to be computed between each of the vectors.\n * @param {Options} [options] Options to pass to the implementing embedders.\n * @memberof DimensionalityReducer\n */\n constructor(data, method, metric, options) {\n const measure = new Measure(metric).getMeasure(options?.distanceFnArgs);\n let specOptions = {};\n let bitArrayLength = 2048;\n for (let i = 0; i < data.length; ++i) {\n if (data[i] && data[i]._length) {\n bitArrayLength = data[i]._length;\n break;\n }\n }\n if (isBitArrayMetric(metric)) {\n for (let i = 0; i < data.length; ++i) {\n if (data[i] && data[i]._data)\n data[i] = new BitArray(data[i]._data, data[i]._length);\n else\n data[i] = new BitArray(bitArrayLength);\n }\n }\n if (method == 'UMAP') {\n specOptions = {\n ...{ data: data },\n ...{ distanceFn: measure },\n ...{ distanceFname: metric },\n ...{ nEpochs: options?.cycles },\n ...options,\n };\n }\n else if (method == 't-SNE') {\n specOptions = {\n ...{ data: data },\n ...{ distanceFn: measure },\n ...{ distanceFname: metric },\n ...{ iterations: options?.cycles ?? undefined },\n ...options,\n };\n }\n else if (method == 'SPE') {\n specOptions = { ...{ data: data }, ...{ distance: measure }, distanceFunctionName: metric, ...options };\n }\n else {\n specOptions = { ...{ data: data }, ...{ distance: measure }, distanceFunctionName: metric, ...options };\n }\n this.reducer = new AvailableReducers[method](specOptions);\n }\n /**\n * Embeds the data given into the two-dimensional space using the chosen method.\n *\n * @param {boolean} transpose Whether to transform coordinates to have columns-first orientation.\n * @param {boolean} parallelDistanceWorkers Whether to use parallel distance computation.\n * @throws {Error} If the embedding method was not found.\n * @return {any} Cartesian coordinate of this embedding and distance matrix where applicable.\n * @memberof DimensionalityReducer\n */\n async transform(transpose = false, parallelDistanceWorkers) {\n if (this.reducer === undefined)\n throw new Error('Reducer was not defined.');\n let { embedding, distance } = await this.reducer.transform(parallelDistanceWorkers);\n if (transpose)\n embedding = transposeMatrix(embedding);\n return { distance: distance, embedding: embedding };\n }\n /**\n * Returns metrics available by type.\n *\n * @param {AvailableDataTypes} typeName type name\n * @return {string[]} Metric names which expects the given data type\n * @memberof DimensionalityReducer\n */\n static availableMetricsByType(typeName) {\n return Object.keys(AvailableMetrics[typeName]);\n }\n /**\n * Returns dimensionality reduction methods available.\n *\n * @readonly\n * @memberof DimensionalityReducer\n */\n static get availableMethods() {\n return Object.keys(AvailableReducers);\n }\n /**\n * Returns metrics available.\n *\n * @readonly\n * @memberof DimensionalityReducer\n */\n static get availableMetrics() {\n let ans = [];\n Object.values(AvailableMetrics).forEach((obj) => {\n const array = Object.values(obj);\n ans = [...ans, ...array];\n });\n return ans;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdWNlLWRpbWVuc2lvbmFsaXR5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicmVkdWNlLWRpbWVuc2lvbmFsaXR5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDRCQUE0QjtBQUM1QixPQUFPLEVBQUMsSUFBSSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ25DLE9BQU8sRUFHTCxNQUFNLEdBR1AsTUFBTSxpREFBaUQsQ0FBQztBQUN6RCxPQUFPLEVBQ0wsZUFBZSxFQUNmLE1BQU0sR0FDUCxNQUFNLGlEQUFpRCxDQUFDO0FBQ3pELE9BQU8sRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBQyxNQUFNLE9BQU8sQ0FBQztBQUNyRCxPQUFPLEVBQUMsT0FBTyxFQUFnQixnQkFBZ0IsRUFDN0MsZ0JBQWdCLEVBQXFCLE1BQU0sK0JBQStCLENBQUM7QUFDN0UsT0FBTyxRQUFRLE1BQU0seUNBQXlDLENBQUM7QUFDL0QsT0FBTyxFQUFpQixJQUFJLEVBQUMsTUFBTSxRQUFRLENBQUM7QUFDNUMsT0FBTyxFQUFDLGNBQWMsRUFBRSxxQkFBcUIsRUFBRSxtQkFBbUIsRUFBRSxhQUFhLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUM1RyxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSx5Q0FBeUMsQ0FBQztBQWU1RSxNQUFNLENBQU4sSUFBWSxtQkFHWDtBQUhELFdBQVksbUJBQW1CO0lBQzdCLG9DQUFhLENBQUE7SUFDYixzQ0FBZSxDQUFBO0FBQ2pCLENBQUMsRUFIVyxtQkFBbUIsS0FBbkIsbUJBQW1CLFFBRzlCO0FBNkJEOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUcsS0FBSyxDQUFDO0FBRTlDLE1BQU0sT0FBTyxXQUFXO0lBUXRCO1FBUEEsaUJBQVksR0FBdUIsRUFBQyxNQUFNLEVBQUUsZUFBZSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLDBEQUEwRCxFQUFDLENBQUM7UUFDNUksZ0JBQVcsR0FBdUIsRUFBQyxNQUFNLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLDhEQUE4RCxFQUFDLENBQUM7UUFDNUksWUFBTyxHQUF1QixFQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUseUZBQXlGLEVBQUMsQ0FBQztRQUMvSixlQUFVLEdBQXVCLEVBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxpRUFBaUUsRUFBQyxDQUFDO1FBQzlJLFdBQU0sR0FBdUIsRUFBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLHlIQUF5SCxFQUFDLENBQUM7UUFDOUwsWUFBTyxHQUF1QixFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsbUlBQW1JLEVBQUMsQ0FBQztJQUVsTSxDQUFDO0lBQUEsQ0FBQztDQUNsQjtBQUVELE1BQU0sT0FBTyxXQUFXO0lBS3RCO1FBSkEsWUFBTyxHQUF1QixFQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsMEJBQTBCLEVBQUMsQ0FBQztRQUNsRyxlQUFVLEdBQXVCLEVBQUMsTUFBTSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxrREFBa0QsRUFBQyxDQUFDO1FBQ2hJLFFBQUcsR0FBdUIsRUFBQyxNQUFNLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsaUNBQWlDLEVBQUMsQ0FBQztJQUU1RixDQUFDO0lBQUEsQ0FBQztDQUNsQjtBQUVELHNDQUFzQztBQUN0QyxNQUFlLE9BQU87SUFHcEIsWUFBWSxPQUFnQjtRQUMxQixJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7SUFDM0IsQ0FBQztDQUtGO0FBRUQsc0NBQXNDO0FBQ3RDLE1BQU0sV0FBWSxTQUFRLE9BQU87SUFNL0I7Ozs7T0FJRztJQUNILFlBQVksT0FBZ0I7UUFDMUIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNqQyxJQUFJLENBQUMsVUFBVSxHQUFHLE9BQU8sRUFBRSxVQUFVLElBQUksR0FBRyxDQUFDO1FBQzdDLElBQUksQ0FBQyxhQUFhLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQztRQUMzQyxJQUFJLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUM7SUFDdkMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxLQUFLLENBQUMsU0FBUyxDQUFDLHVCQUFpQztRQUN0RCxNQUFNLFFBQVEsR0FBRyx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSSxFQUFFO1lBQzNELE1BQU0sYUFBYSxHQUFHLElBQUkscUJBQXFCLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzdELElBQUk7Z0JBQ0YsTUFBTSxJQUFJLEdBQUcsTUFBTSxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO2dCQUNyRSxhQUFhLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQzFCLE9BQU8sSUFBSSxDQUFDO2FBQ2I7WUFBQyxPQUFPLENBQUMsRUFBRTtnQkFDVixhQUFhLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQzFCLE1BQU0sQ0FBQyxDQUFDO2FBQ1Q7UUFDSCxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDSixDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU0sR0FBRyxHQUFHLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBRS9ILE1BQU0sV0FBVyxHQUFHLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3BFLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRXZDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQztZQUN0QyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsaURBQWlEO1FBRXhFLE9BQU8sRUFBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxFQUFDLENBQUM7SUFDckUsQ0FBQztDQUNGO0FBVUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFdBQVksU0FBUSxPQUFPO0lBVS9COzs7O09BSUc7SUFDSCxZQUFZLE9BQW9CO1FBQzlCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNmLE1BQU0sQ0FBQyxlQUFlLElBQUksT0FBTyxDQUFDLENBQUM7UUFDbkMsTUFBTSxDQUFDLFlBQVksSUFBSSxPQUFPLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsY0FBYyxHQUFHLE9BQU8sRUFBRSxjQUFjLENBQUM7UUFDOUMsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsVUFBVyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQztRQUV6QyxJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQyxhQUFjLENBQUM7UUFDNUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNuRCxpRkFBaUY7UUFDakYsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVwRSxPQUFPLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFdEQsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFO1lBQ3ZCLE9BQU8sQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDakMsOERBQThEO0lBQ2hFLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILG1FQUFtRTtJQUNuRSxpQkFBaUI7SUFDakIsZ0JBQWdCO0lBQ2hCLGVBQWU7SUFDZiwyREFBMkQ7SUFDM0QseURBQXlEO0lBQ3pELElBQUk7SUFFTSxvQkFBb0IsQ0FBQyxDQUFTLEVBQUUsQ0FBUztRQUNqRCxPQUFPLElBQUksQ0FBQyxZQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsWUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3JGLENBQUM7SUFFUyxnQkFBZ0IsQ0FBQyxDQUFTLEVBQUUsQ0FBUztRQUM3QyxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxLQUFLLENBQUMsU0FBUyxDQUFDLHdCQUFrQztRQUN2RCxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzFCLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxtQkFBbUIsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2xJLE9BQU8sQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDN0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUV2RSx3RUFBd0U7UUFDeEUsTUFBTSxJQUFJLE9BQU8sQ0FBTyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ2xDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ2QsT0FBTyxFQUFFLENBQUM7WUFDWixDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDVixDQUFDLENBQUMsQ0FBQztRQUVILE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ25FLElBQUksSUFBSSxDQUFDLFlBQVk7Z0JBQ25CLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO1FBQ3BGLENBQUMsQ0FBQyxDQUFDO1FBRUgsU0FBUyxxQkFBcUIsQ0FBQyxJQUFnQjtZQUM3QyxPQUFPLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5RSxDQUFDO1FBRUQsT0FBTyxFQUFDLFNBQVMsRUFBRSxxQkFBcUIsQ0FBQyxTQUFTLENBQUMsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsRUFBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLGNBQWMsRUFBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBQyxDQUFDO0lBQ3hILENBQUM7Q0FDRjtBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFXLFNBQVEsT0FBTztJQUc5Qjs7OztPQUlHO0lBQ0gsWUFBWSxPQUFnQjtRQUMxQixLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDZixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRDs7O09BR0c7SUFDSSxLQUFLLENBQUMsU0FBUztRQUNwQixNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoRCxPQUFPLEVBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUMsQ0FBQztJQUMzRCxDQUFDO0NBQ0Y7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sV0FBWSxTQUFRLE9BQU87SUFHL0I7Ozs7T0FJRztJQUNILFlBQVksT0FBZ0I7UUFDMUIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksS0FBSyxDQUFDLFNBQVM7UUFDcEIsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEQsT0FBTyxFQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFDLENBQUM7SUFDM0QsQ0FBQztDQUNGO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLGtCQUFtQixTQUFRLE9BQU87SUFHdEM7Ozs7T0FJRztJQUNILFlBQVksT0FBZ0I7UUFDMUIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksS0FBSyxDQUFDLFNBQVM7UUFDcEIsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEQsT0FBTyxFQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFDLENBQUM7SUFDM0QsQ0FBQztDQUNGO0FBRUQsTUFBTSxpQkFBaUIsR0FBRztJQUN4QixNQUFNLEVBQUUsV0FBVztJQUNuQixPQUFPLEVBQUUsV0FBVztJQUNwQixLQUFLLEVBQUUsVUFBVTtJQUNqQixNQUFNLEVBQUUsV0FBVztJQUNuQixhQUFhLEVBQUUsa0JBQWtCO0NBQ2xDLENBQUM7QUFJRjs7Ozs7R0FLRztBQUNILE1BQU0sT0FBTyxxQkFBcUI7SUFHaEM7Ozs7Ozs7T0FPRztJQUNILFlBQVksSUFBVyxFQUFFLE1BQW9CLEVBQUUsTUFBb0IsRUFBRSxPQUFpQjtRQUNwRixNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQ3hFLElBQUksV0FBVyxHQUFHLEVBQUUsQ0FBQztRQUNyQixJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDMUIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLEVBQUU7WUFDcEMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRTtnQkFDOUIsY0FBYyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7Z0JBQ2pDLE1BQU07YUFDUDtTQUNGO1FBQ0QsSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUM1QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRTtnQkFDcEMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUs7b0JBQzFCLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQzs7b0JBRXZELElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLFFBQVEsQ0FBQyxjQUFjLENBQUMsQ0FBQzthQUMxQztTQUNGO1FBRUQsSUFBSSxNQUFNLElBQUksTUFBTSxFQUFFO1lBQ3BCLFdBQVcsR0FBRztnQkFDWixHQUFHLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBQztnQkFDZixHQUFHLEVBQUMsVUFBVSxFQUFFLE9BQU8sRUFBQztnQkFDeEIsR0FBRyxFQUFDLGFBQWEsRUFBRSxNQUFNLEVBQUM7Z0JBQzFCLEdBQUcsRUFBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBQztnQkFDN0IsR0FBRyxPQUFPO2FBQ1gsQ0FBQztTQUNIO2FBQU0sSUFBSSxNQUFNLElBQUksT0FBTyxFQUFFO1lBQzVCLFdBQVcsR0FBRztnQkFDWixHQUFHLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBQztnQkFDZixHQUFHLEVBQUMsVUFBVSxFQUFFLE9BQU8sRUFBQztnQkFDeEIsR0FBRyxFQUFDLGFBQWEsRUFBRSxNQUFNLEVBQUM7Z0JBQzFCLEdBQUcsRUFBQyxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0sSUFBSSxTQUFTLEVBQUM7Z0JBQzdDLEdBQUcsT0FBTzthQUNYLENBQUM7U0FDSDthQUFNLElBQUksTUFBTSxJQUFJLEtBQUssRUFBRTtZQUMxQixXQUFXLEdBQUcsRUFBQyxHQUFHLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBQyxFQUFFLEdBQUcsRUFBQyxRQUFRLEVBQUUsT0FBTyxFQUFDLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxFQUFFLEdBQUcsT0FBTyxFQUFDLENBQUM7U0FDbkc7YUFBTTtZQUNMLFdBQVcsR0FBRyxFQUFDLEdBQUcsRUFBQyxJQUFJLEVBQUUsSUFBSSxFQUFDLEVBQUUsR0FBRyxFQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUMsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLEVBQUUsR0FBRyxPQUFPLEVBQUMsQ0FBQztTQUNuRztRQUNELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSSxLQUFLLENBQUMsU0FBUyxDQUFDLFlBQXFCLEtBQUssRUFBRSx1QkFBaUM7UUFDbEYsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVM7WUFDNUIsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBRTlDLElBQUksRUFBQyxTQUFTLEVBQUUsUUFBUSxFQUFDLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBRWxGLElBQUksU0FBUztZQUNYLFNBQVMsR0FBRyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFekMsT0FBTyxFQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBQyxDQUFDO0lBQ3BELENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxNQUFNLENBQUMsc0JBQXNCLENBQUMsUUFBNEI7UUFDeEQsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsTUFBTSxLQUFLLGdCQUFnQjtRQUN6QixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxNQUFNLEtBQUssZ0JBQWdCO1FBQ3pCLElBQUksR0FBRyxHQUFhLEVBQUUsQ0FBQztRQUN2QixNQUFNLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDOUMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNqQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsRUFBRSxHQUFHLEtBQUssQ0FBQyxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5pbXBvcnQge1RTTkV9IGZyb20gJ0BrZWNrZWx0L3RzbmUnO1xuaW1wb3J0IHtcbiAgT3B0aW9ucyxcbiAgQ29vcmRpbmF0ZXMsXG4gIFZlY3RvcixcbiAgVmVjdG9ycyxcbiAgTWF0cml4LFxufSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy90eXBlLWRlY2xhcmF0aW9ucyc7XG5pbXBvcnQge1xuICB0cmFuc3Bvc2VNYXRyaXgsXG4gIGFzc2VydCxcbn0gZnJvbSAnQGRhdGFncm9rLWxpYnJhcmllcy91dGlscy9zcmMvdmVjdG9yLW9wZXJhdGlvbnMnO1xuaW1wb3J0IHtTUEVCYXNlLCBQU1BFQmFzZSwgT3JpZ2luYWxTUEV9IGZyb20gJy4vc3BlJztcbmltcG9ydCB7TWVhc3VyZSwgS25vd25NZXRyaWNzLCBBdmFpbGFibGVNZXRyaWNzLFxuICBpc0JpdEFycmF5TWV0cmljLCBBdmFpbGFibGVEYXRhVHlwZXN9IGZyb20gJy4vdHlwZWQtbWV0cmljcy90eXBlZC1tZXRyaWNzJztcbmltcG9ydCBCaXRBcnJheSBmcm9tICdAZGF0YWdyb2stbGlicmFyaWVzL3V0aWxzL3NyYy9iaXQtYXJyYXknO1xuaW1wb3J0IHtVTUFQUGFyYW1ldGVycywgVU1BUH0gZnJvbSAnLi91bWFwJztcbmltcG9ydCB7RGlzdGFuY2VNYXRyaXgsIERpc3RhbmNlTWF0cml4U2VydmljZSwgZGlzdGFuY2VNYXRyaXhQcm94eSwgZG1MaW5lYXJJbmRleH0gZnJvbSAnLi9kaXN0YW5jZS1tYXRyaXgnO1xuaW1wb3J0IHtTcGFyc2VNYXRyaXhTZXJ2aWNlfSBmcm9tICcuL2Rpc3RhbmNlLW1hdHJpeC9zcGFyc2UtbWF0cml4LXNlcnZpY2UnO1xuaW1wb3J0IHtnZXRLbm5HcmFwaCwgZ2V0S25uR3JhcGhGcm9tRE19IGZyb20gJy4vdW1hcC9rbm5HcmFwaCc7XG5cbmV4cG9ydCB0eXBlIFNwYXJzZU1hdHJpeFRyYW5zZmVyVHlwZSA9IHtcbiAgaTogSW50MzJBcnJheSxcbiAgajogSW50MzJBcnJheSxcbiAgZGlzdGFuY2U6IEZsb2F0MzJBcnJheSxcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJUmVkdWNlRGltZW5zaW9uYWxpdHlSZXN1bHQge1xuICBkaXN0YW5jZT86IEZsb2F0MzJBcnJheTtcbiAgc3BhcnNlTWF0cml4PzogTWFwPG51bWJlciwgTWFwPG51bWJlciwgbnVtYmVyPj47XG4gIGVtYmVkZGluZzogTWF0cml4O1xufVxuXG5leHBvcnQgZW51bSBEaW1SZWR1Y3Rpb25NZXRob2Rze1xuICBVTUFQID0gJ1VNQVAnLFxuICBUX1NORSA9ICd0LVNORSdcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJVU1BUE9wdGlvbnMge1xuICBsZWFybmluZ1JhdGU/OiBudW1iZXI7XG4gIG5Db21wb25lbnRzPzogbnVtYmVyO1xuICBuRXBvY2hzPzogbnVtYmVyO1xuICBuTmVpZ2hib3JzPzogbnVtYmVyO1xuICBzcHJlYWQ/OiBudW1iZXI7XG4gIG1pbkRpc3Q/OiBudW1iZXI7XG4gIHNwYXJzZU1hdHJpeFRocmVzaG9sZD86IG51bWJlcjtcbiAgcHJlQ2FsY3VsYXRlRGlzdGFuY2VNYXRyaXg/OiBib29sZWFuO1xuICB1c2luZ1NwYXJzZU1hdHJpeD86IGJvb2xlYW47XG4gIHNwYXJzZU1hdHJpeD86IFNwYXJzZU1hdHJpeFRyYW5zZmVyVHlwZTtcbiAgcHJvZ3Jlc3NGdW5jPzogKGVwb2M6IG51bWJlciwgZXBvY2hzTGVuZ3RoOiBudW1iZXIsIGVtYmVkZGluZ3M6IG51bWJlcltdW10pID0+IHZvaWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVRTTkVPcHRpb25zIHtcbiAgZXBzaWxvbj86IG51bWJlcjtcbiAgcGVycGxleGl0eT86IG51bWJlcjtcbiAgZGltPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElEaW1SZWR1Y3Rpb25QYXJhbSB7XG4gIHVpTmFtZTogc3RyaW5nO1xuICB2YWx1ZTogbnVtYmVyIHwgbnVsbDtcbiAgdG9vbHRpcDogc3RyaW5nO1xuICBwbGFjZWhvbGRlcj86IHN0cmluZztcbn1cblxuLyoqIFVtYXAgdXNlcyBwcmVjYWxjdWxhdGVkIGRpc3RhbmNlIG1hdHJpeCB0byBzYXZlIHRpbWUuIHRob3VnaCBmb3IgdG9vIG11Y2ggZGF0YSwgbWVtb3J5IGJlY29tZXMgY29uc3RyYWludC5cbiAqIGlmIHdlIGhhdmUgMTAwIDAwMCByb3dzLCBkaXN0YW5jZSBtYXRyaXggd2lsbCB0YWtlIH4xMGdiIG9mIG1lbW9yeSBhbmQgcHJvYmFibHkgb3ZlcmZsb3cuXG4gKi9cbmV4cG9ydCBjb25zdCBNQVhfRElTVEFOQ0VfTUFUUklYX1JPV1MgPSAyMDAwMDtcblxuZXhwb3J0IGNsYXNzIFVNQVBPcHRpb25zIHtcbiAgbGVhcm5pbmdSYXRlOiBJRGltUmVkdWN0aW9uUGFyYW0gPSB7dWlOYW1lOiAnTGVhcmluaWcgcmF0ZScsIHZhbHVlOiAxLCB0b29sdGlwOiAnVGhlIGluaXRpYWwgbGVhcm5pbmcgcmF0ZSBmb3IgdGhlIGVtYmVkZGluZyBvcHRpbWl6YXRpb24nfTtcbiAgbkNvbXBvbmVudHM6IElEaW1SZWR1Y3Rpb25QYXJhbSA9IHt1aU5hbWU6ICdDb21wb25lbnRzJywgdmFsdWU6IDIsIHRvb2x0aXA6ICdUaGUgbnVtYmVyIG9mIGNvbXBvbmVudHMgKGRpbWVuc2lvbnMpIHRvIHByb2plY3QgdGhlIGRhdGEgdG8nfTtcbiAgbkVwb2NoczogSURpbVJlZHVjdGlvblBhcmFtID0ge3VpTmFtZTogJ0Vwb2NocycsIHZhbHVlOiAwLCB0b29sdGlwOiAnVGhlIG51bWJlciBvZiBlcG9jaHMgdG8gb3B0aW1pemUgZW1iZWRkaW5ncyB2aWEgU0dELiBDb21wdXRlZCBhdXRvbWF0aWNhbGx5IGlmIHNldCB0byAwJ307XG4gIG5OZWlnaGJvcnM6IElEaW1SZWR1Y3Rpb25QYXJhbSA9IHt1aU5hbWU6ICdOZWlnaGJvcnMnLCB2YWx1ZTogMTUsIHRvb2x0aXA6ICdUaGUgbnVtYmVyIG9mIG5lYXJlc3QgbmVpZ2hib3JzIHRvIGNvbnN0cnVjdCB0aGUgZnV6enkgbWFuaWZvbGQnfTtcbiAgc3ByZWFkOiBJRGltUmVkdWN0aW9uUGFyYW0gPSB7dWlOYW1lOiAnU3ByZWFkJywgdmFsdWU6IDEsIHRvb2x0aXA6ICdUaGUgZWZmZWN0aXZlIHNjYWxlIG9mIGVtYmVkZGVkIHBvaW50cywgdXNlZCB3aXRoIG1pbiBkaXN0YW5jZSB0byBjb250cm9sIHRoZSBjbHVtcGVkL2Rpc3BlcnNlZCBuYXR1cmUgb2YgdGhlIGVtYmVkZGluZyd9O1xuICBtaW5EaXN0OiBJRGltUmVkdWN0aW9uUGFyYW0gPSB7dWlOYW1lOiAnTWluIGRpc3RhbmNlJywgdmFsdWU6IDAuMSwgdG9vbHRpcDogJ1RoZSBlZmZlY3RpdmUgbWluaW11bSBkaXN0YW5jZSBiZXR3ZWVuIGVtYmVkZGVkIHBvaW50cywgdXNlZCB3aXRoIHNwcmVhZCB0byBjb250cm9sIHRoZSBjbHVtcGVkL2Rpc3BlcnNlZCBuYXR1cmUgb2YgdGhlIGVtYmVkZGluZyd9O1xuXG4gIGNvbnN0cnVjdG9yKCkge307XG59XG5cbmV4cG9ydCBjbGFzcyBUU05FT3B0aW9ucyB7XG4gIGVwc2lsb246IElEaW1SZWR1Y3Rpb25QYXJhbSA9IHt1aU5hbWU6ICdFcHNpbG9uJywgdmFsdWU6IDEwLCB0b29sdGlwOiAnRXBzaWxvbiBpcyBsZWFybmluZyByYXRlJ307XG4gIHBlcnBsZXhpdHk6IElEaW1SZWR1Y3Rpb25QYXJhbSA9IHt1aU5hbWU6ICdQZXJwbGV4aXR5JywgdmFsdWU6IDMwLCB0b29sdGlwOiAnUm91Z2hseSBob3cgbWFueSBuZWlnaGJvcnMgZWFjaCBwb2ludCBpbmZsdWVuY2VzJ307XG4gIGRpbTogSURpbVJlZHVjdGlvblBhcmFtID0ge3VpTmFtZTogJ0RpbWVuc2lvbmFsaXR5JywgdmFsdWU6IDIsIHRvb2x0aXA6ICdEaW1lbnNpb25hbGl0eSBvZiB0aGUgZW1iZWRkaW5nJ307XG5cbiAgY29uc3RydWN0b3IoKSB7fTtcbn1cblxuLyoqIEFic3RyYWN0IGRpbWVuc2lvbmFsaXR5IHJlZHVjZXIgKi9cbmFic3RyYWN0IGNsYXNzIFJlZHVjZXIge1xuICBwcm90ZWN0ZWQgZGF0YTogVmVjdG9ycztcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBPcHRpb25zKSB7XG4gICAgdGhpcy5kYXRhID0gb3B0aW9ucy5kYXRhO1xuICB9XG5cbiAgLyoqIEVtYmVkcyB0aGUgZGF0YSBnaXZlbiBpbnRvIHRoZSB0d28tZGltZW5zaW9uYWwgc3BhY2UuXG4gICAqIEByZXR1cm4ge2FueX0gQ2FydGVzaWFuIGNvb3JkaW5hdGUgb2YgdGhpcyBlbWJlZGRpbmcgYW5kIGRpc3RhbmNlIG1hdHJpeCB3aGVyZSBhcHBsaWNhYmxlLiAqL1xuICBhYnN0cmFjdCB0cmFuc2Zvcm0ocGFyYWxsZWxEaXN0YW5jZVdvcmtlcnM/OiBib29sZWFuKTogUHJvbWlzZTxJUmVkdWNlRGltZW5zaW9uYWxpdHlSZXN1bHQ+O1xufVxuXG4vKiogdC1TTkUgZGltZW5zaW9uYWxpdHkgcmVkdWN0aW9uLiAqL1xuY2xhc3MgVFNORVJlZHVjZXIgZXh0ZW5kcyBSZWR1Y2VyIHtcbiAgcHJvdGVjdGVkIHJlZHVjZXI6IFRTTkU7XG4gIHByb3RlY3RlZCBpdGVyYXRpb25zOiBudW1iZXI7XG4gIHByb3RlY3RlZCBkaXN0YW5jZUZuYW1lOiBLbm93bk1ldHJpY3M7XG4gIHByb3RlY3RlZCBkaXN0YW5jZUZuOiAoYTogYW55LCBiOiBhbnkpID0+IG51bWJlcjtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBUU05FUmVkdWNlci5cbiAgICogQHBhcmFtIHtPcHRpb25zfSBvcHRpb25zIE9wdGlvbnMgdG8gcGFzcyB0byB0aGUgY29uc3RydWN0b3IuXG4gICAqIEBtZW1iZXJvZiBUU05FUmVkdWNlclxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9uczogT3B0aW9ucykge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgIHRoaXMucmVkdWNlciA9IG5ldyBUU05FKG9wdGlvbnMpO1xuICAgIHRoaXMuaXRlcmF0aW9ucyA9IG9wdGlvbnM/Lml0ZXJhdGlvbnMgPz8gMTAwO1xuICAgIHRoaXMuZGlzdGFuY2VGbmFtZSA9IG9wdGlvbnMuZGlzdGFuY2VGbmFtZTtcbiAgICB0aGlzLmRpc3RhbmNlRm4gPSBvcHRpb25zLmRpc3RhbmNlRm47XG4gIH1cblxuICAvKipcbiAgICogRW1iZWRzIHRoZSBkYXRhIGdpdmVuIGludG8gdGhlIHR3by1kaW1lbnNpb25hbCBzcGFjZSB1c2luZyB0LVNORSBtZXRob2QuXFxcbiAgICogQHBhcmFtIHtib29sZWFufSBbcGFyYWxsZWxEaXN0YW5jZVdvcmtlcnNdIFdoZXRoZXIgdG8gdXNlIHBhcmFsbGVsIGRpc3RhbmNlIHdvcmtlcnMuXG4gICAqIEByZXR1cm4ge2FueX0gQ2FydGVzaWFuIGNvb3JkaW5hdGUgb2YgdGhpcyBlbWJlZGRpbmcgYW5kIGRpc3RhbmNlIG1hdHJpeCB3aGVyZSBhcHBsaWNhYmxlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHRyYW5zZm9ybShwYXJhbGxlbERpc3RhbmNlV29ya2Vycz86IGJvb2xlYW4pOiBQcm9taXNlPElSZWR1Y2VEaW1lbnNpb25hbGl0eVJlc3VsdD4ge1xuICAgIGNvbnN0IGRpc3RhbmNlID0gcGFyYWxsZWxEaXN0YW5jZVdvcmtlcnMgPyBhd2FpdCAoYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgbWF0cml4U2VydmljZSA9IG5ldyBEaXN0YW5jZU1hdHJpeFNlcnZpY2UodHJ1ZSwgZmFsc2UpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZGlzdCA9IGF3YWl0IG1hdHJpeFNlcnZpY2UuY2FsYyh0aGlzLmRhdGEsIHRoaXMuZGlzdGFuY2VGbmFtZSk7XG4gICAgICAgIG1hdHJpeFNlcnZpY2UudGVybWluYXRlKCk7XG4gICAgICAgIHJldHVybiBkaXN0O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBtYXRyaXhTZXJ2aWNlLnRlcm1pbmF0ZSgpO1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH0pKCkgOlxuICAgICAgKCgpID0+IHsgY29uc3QgcmV0ID0gRGlzdGFuY2VNYXRyaXguY2FsYyh0aGlzLmRhdGEsIChhLCBiKSA9PiB0aGlzLmRpc3RhbmNlRm4oYSwgYikpOyByZXQubm9ybWFsaXplKCk7IHJldHVybiByZXQuZGF0YTsgfSkoKTtcblxuICAgIGNvbnN0IG1hdHJpeFByb3h5ID0gZGlzdGFuY2VNYXRyaXhQcm94eShkaXN0YW5jZSwgdGhpcy5kYXRhLmxlbmd0aCk7XG4gICAgdGhpcy5yZWR1Y2VyLmluaXREYXRhRGlzdChtYXRyaXhQcm94eSk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuaXRlcmF0aW9uczsgKytpKVxuICAgICAgdGhpcy5yZWR1Y2VyLnN0ZXAoKTsgLy8gZXZlcnkgdGltZSB5b3UgY2FsbCB0aGlzLCBzb2x1dGlvbiBnZXRzIGJldHRlclxuXG4gICAgcmV0dXJuIHtkaXN0YW5jZTogZGlzdGFuY2UsIGVtYmVkZGluZzogdGhpcy5yZWR1Y2VyLmdldFNvbHV0aW9uKCl9O1xuICB9XG59XG5cbmV4cG9ydCB0eXBlIFVtYXBPcHRpb25zID0gT3B0aW9ucyAmIFVNQVBQYXJhbWV0ZXJzICYge1xuICBwcmVDYWxjdWxhdGVEaXN0YW5jZU1hdHJpeD86IGJvb2xlYW4sXG4gIHVzaW5nU3BhcnNlTWF0cml4PzogYm9vbGVhbixcbiAgc3BhcnNlTWF0cml4VGhyZXNob2xkPzogbnVtYmVyLFxuICBzcGFyc2VNYXRyaXg/OiBTcGFyc2VNYXRyaXhUcmFuc2ZlclR5cGUsXG4gIHByb2dyZXNzRnVuYz86IChlcG9jOiBudW1iZXIsIGVwb2Noc0xlbmd0aDogbnVtYmVyLCBlbWJlZGRpbmdzOiBudW1iZXJbXVtdKSA9PiB2b2lkLFxufTtcblxuLyoqXG4gKiBJbXBsZW1lbnRzIFVNQVAgZGltZW5zaW9uYWxpdHkgcmVkdWN0aW9uLlxuICpcbiAqIEBjbGFzcyBVTUFQUmVkdWNlclxuICogQGV4dGVuZHMge1JlZHVjZXJ9XG4gKi9cbmNsYXNzIFVNQVBSZWR1Y2VyIGV4dGVuZHMgUmVkdWNlciB7XG4gIHByb3RlY3RlZCByZWR1Y2VyOiBVTUFQO1xuICBwcm90ZWN0ZWQgZGlzdGFuY2VGbmFtZTogS25vd25NZXRyaWNzO1xuICBwcm90ZWN0ZWQgZGlzdGFuY2VGbjogRnVuY3Rpb247XG4gIHByb3RlY3RlZCB2ZWN0b3JzOiBudW1iZXJbXTtcbiAgcHJvdGVjdGVkIGRpc3RhbmNlTWF0cml4PzogRmxvYXQzMkFycmF5O1xuICBwcm90ZWN0ZWQgc3BhcnNlTWF0cml4PzogTWFwPG51bWJlciwgTWFwPG51bWJlciwgbnVtYmVyPj47XG4gIHByb3RlY3RlZCBkbUluZGV4RnVuYzogKGk6IG51bWJlciwgajogbnVtYmVyKSA9PiBudW1iZXI7XG4gIHByb3RlY3RlZCBwcm9ncmVzc0Z1bmM/OiAoZXBvYzogbnVtYmVyLCBlcG9jaHNMZW5ndGg6IG51bWJlciwgZW1iZWRkaW5nczogbnVtYmVyW11bXSkgPT4gdm9pZDtcbiAgcHJvdGVjdGVkIGRpc3RhbmNlRm5BcmdzPzoge1tfOiBzdHJpbmddOiBhbnl9O1xuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBVTUFQUmVkdWNlci5cbiAgICogQHBhcmFtIHtPcHRpb25zfSBvcHRpb25zIE9wdGlvbnMgdG8gcGFzcyB0byB0aGUgY29uc3RydWN0b3IuXG4gICAqIEBtZW1iZXJvZiBVTUFQUmVkdWNlclxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9uczogVW1hcE9wdGlvbnMpIHtcbiAgICBzdXBlcihvcHRpb25zKTtcbiAgICBhc3NlcnQoJ2Rpc3RhbmNlRm5hbWUnIGluIG9wdGlvbnMpO1xuICAgIGFzc2VydCgnZGlzdGFuY2VGbicgaW4gb3B0aW9ucyk7XG4gICAgdGhpcy5kaXN0YW5jZUZuQXJncyA9IG9wdGlvbnM/LmRpc3RhbmNlRm5BcmdzO1xuICAgIHRoaXMuZGlzdGFuY2VGbiA9IG9wdGlvbnMuZGlzdGFuY2VGbiE7XG4gICAgdGhpcy5wcm9ncmVzc0Z1bmMgPSBvcHRpb25zLnByb2dyZXNzRnVuYztcblxuICAgIHRoaXMuZGlzdGFuY2VGbmFtZSA9IG9wdGlvbnMuZGlzdGFuY2VGbmFtZSE7XG4gICAgdGhpcy5kbUluZGV4RnVuYyA9IGRtTGluZWFySW5kZXgodGhpcy5kYXRhLmxlbmd0aCk7XG4gICAgLy9VbWFwIHVzZXMgdmVjdG9yIGluZGV4aW5nLCBzbyB3ZSBuZWVkIHRvIGNyZWF0ZSBhbiBhcnJheSBvZiB2ZWN0b3JzIGFzIGluZGVjZXMuXG4gICAgdGhpcy52ZWN0b3JzID0gbmV3IEFycmF5KHRoaXMuZGF0YS5sZW5ndGgpLmZpbGwoMCkubWFwKChfLCBpKSA9PiBpKTtcblxuICAgIG9wdGlvbnMuZGlzdGFuY2VGbiA9IHRoaXMuX2VuY29kZWREaXN0YW5jZS5iaW5kKHRoaXMpO1xuICAgIFxuICAgIGlmICh0aGlzLmRhdGEubGVuZ3RoIDwgMTUpXG4gICAgICBvcHRpb25zLm5OZWlnaGJvcnMgPSB0aGlzLmRhdGEubGVuZ3RoIC0gMTtcbiAgICB0aGlzLnJlZHVjZXIgPSBuZXcgVU1BUChvcHRpb25zKTtcbiAgICAvLyB0aGlzLnJlZHVjZXIuZGlzdGFuY2VGbiA9IHRoaXMuX2VuY29kZWREaXN0YW5jZS5iaW5kKHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEN1c3RvbSBkaXN0YW5jZSB3cmFwcGVyIHRvIGhhdmUgbnVtZXJpYyBpbnB1dHMgaW5zdGVhZCBvZiBzdHJpbmcgb25lcy5cbiAgICpcbiAgICogQHByb3RlY3RlZFxuICAgKiBAcGFyYW0ge251bWJlcltdfSBhIFRoZSBmaXJzdCBpdGVtLlxuICAgKiBAcGFyYW0ge251bWJlcltdfSBiIFRoZSBmaXJzdCBpdGVtLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IERpc3RhbmNlIG1ldHJpYy5cbiAgICogQG1lbWJlcm9mIFVNQVBSZWR1Y2VyXG4gICAqL1xuICAvLyBwcm90ZWN0ZWQgX2VuY29kZWREaXN0YW5jZU1hdHJpeChhOiBudW1iZXIsIGI6IG51bWJlcik6IG51bWJlciB7XG4gIC8vICAgaWYgKGEgPT09IGIpXG4gIC8vICAgICByZXR1cm4gMDtcbiAgLy8gICBpZiAoYSA+IGIpXG4gIC8vICAgICByZXR1cm4gdGhpcy5kaXN0YW5jZU1hdHJpeCFbdGhpcy5kbUluZGV4RnVuYyhiLCBhKV07XG4gIC8vICAgcmV0dXJuIHRoaXMuZGlzdGFuY2VNYXRyaXghW3RoaXMuZG1JbmRleEZ1bmMoYSwgYildO1xuICAvLyB9XG5cbiAgcHJvdGVjdGVkIF9lbmNvZGVkU3BhcnNlTWF0cml4KGE6IG51bWJlciwgYjogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zcGFyc2VNYXRyaXghLmdldChhKT8uZ2V0KGIpID8/IHRoaXMuc3BhcnNlTWF0cml4IS5nZXQoYik/LmdldChhKSA/PyAxO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9lbmNvZGVkRGlzdGFuY2UoYTogbnVtYmVyLCBiOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmRpc3RhbmNlRm4odGhpcy5kYXRhW2FdLCB0aGlzLmRhdGFbYl0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEVtYmVkcyB0aGUgZGF0YSBnaXZlbiBpbnRvIHRoZSB0d28tZGltZW5zaW9uYWwgc3BhY2UgdXNpbmcgVU1BUCBtZXRob2QuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW19wYXJhbGxlbERpc3RhbmNlV29ya2Vyc10gV2hldGhlciB0byB1c2UgcGFyYWxsZWwgZGlzdGFuY2UgbWF0cml4IHdvcmtlcnMuXG4gICAqIEByZXR1cm4ge2FueX0gQ2FydGVzaWFuIGNvb3JkaW5hdGUgb2YgdGhpcyBlbWJlZGRpbmcuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgdHJhbnNmb3JtKF9wYXJhbGxlbERpc3RhbmNlV29ya2Vycz86IGJvb2xlYW4pOiBQcm9taXNlPElSZWR1Y2VEaW1lbnNpb25hbGl0eVJlc3VsdD4ge1xuICAgIGNvbnNvbGUudGltZSgna25uIGdyYXBoJyk7XG4gICAgY29uc3Qga25uUmVzID0gYXdhaXQgbmV3IFNwYXJzZU1hdHJpeFNlcnZpY2UoKS5nZXRLTk4odGhpcy5kYXRhLCB0aGlzLmRpc3RhbmNlRm5hbWUsIHRoaXMucmVkdWNlci5uZWlnaGJvcnMsIHRoaXMuZGlzdGFuY2VGbkFyZ3MpO1xuICAgIGNvbnNvbGUudGltZUVuZCgna25uIGdyYXBoJyk7XG4gICAgdGhpcy5yZWR1Y2VyLnNldFByZWNvbXB1dGVkS05OKGtublJlcy5rbm5JbmRleGVzLCBrbm5SZXMua25uRGlzdGFuY2VzKTtcblxuICAgIC8vIG5lZWRlZCBzbyB0aGF0IGdhcmJhZ2UgY29sbGVjdG9yIGNhbiBmcmVlIG1lbW9yeSBmcm9tIGRpc3RhbmNlIG1hdHJpeFxuICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSwgNTAwKTtcbiAgICB9KTtcbiAgICBcbiAgICBjb25zdCBlbWJlZGRpbmcgPSBhd2FpdCB0aGlzLnJlZHVjZXIuZml0QXN5bmModGhpcy52ZWN0b3JzLCAoZXBvYykgPT4ge1xuICAgICAgaWYgKHRoaXMucHJvZ3Jlc3NGdW5jKVxuICAgICAgICB0aGlzLnByb2dyZXNzRnVuYyhlcG9jLCB0aGlzLnJlZHVjZXIuZ2V0TkVwb2NocygpLCB0aGlzLnJlZHVjZXIuZ2V0RW1iZWRkaW5nKCkpO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gYXJyYXlDYXN0MkNvb3JkaW5hdGVzKGRhdGE6IG51bWJlcltdW10pOiBDb29yZGluYXRlcyB7XG4gICAgICByZXR1cm4gbmV3IEFycmF5KGRhdGEubGVuZ3RoKS5maWxsKDApLm1hcCgoXywgaSkgPT4gKFZlY3Rvci5mcm9tKGRhdGFbaV0pKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtlbWJlZGRpbmc6IGFycmF5Q2FzdDJDb29yZGluYXRlcyhlbWJlZGRpbmcpLCAuLi4odGhpcy5kaXN0YW5jZU1hdHJpeCA/IHtkaXN0YW5jZTogdGhpcy5kaXN0YW5jZU1hdHJpeH0gOiB7fSl9O1xuICB9XG59XG5cbi8qKlxuICogSW1wbGVtZW50cyBvcmlnaW5hbCBTUEUgZGltZW5zaW9uYWxpdHkgcmVkdWN0aW9uLlxuICpcbiAqIEBjbGFzcyBTUEVSZWR1Y2VyXG4gKiBAZXh0ZW5kcyB7UmVkdWNlcn1cbiAqL1xuY2xhc3MgU1BFUmVkdWNlciBleHRlbmRzIFJlZHVjZXIge1xuICBwcm90ZWN0ZWQgcmVkdWNlcjogU1BFQmFzZTtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBTUEVSZWR1Y2VyLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyB0byBwYXNzIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICogQG1lbWJlcm9mIFNQRVJlZHVjZXJcbiAgICovXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE9wdGlvbnMpIHtcbiAgICBzdXBlcihvcHRpb25zKTtcbiAgICB0aGlzLnJlZHVjZXIgPSBuZXcgU1BFQmFzZShvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWJlZHMgdGhlIGRhdGEgZ2l2ZW4gaW50byB0aGUgdHdvLWRpbWVuc2lvbmFsIHNwYWNlIHVzaW5nIHRoZSBvcmlnaW5hbCBTUEUgbWV0aG9kLlxuICAgKiBAcmV0dXJuIHthbnl9IENhcnRlc2lhbiBjb29yZGluYXRlIG9mIHRoaXMgZW1iZWRkaW5nIGFuZCBkaXN0YW5jZSBtYXRyaXggd2hlcmUgYXBwbGljYWJsZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyB0cmFuc2Zvcm0oKTogUHJvbWlzZTxJUmVkdWNlRGltZW5zaW9uYWxpdHlSZXN1bHQ+IHtcbiAgICBjb25zdCBlbWIgPSBhd2FpdCB0aGlzLnJlZHVjZXIuZW1iZWQodGhpcy5kYXRhKTtcbiAgICByZXR1cm4ge2Rpc3RhbmNlOiB0aGlzLnJlZHVjZXIuZGlzdGFuY2UsIGVtYmVkZGluZzogZW1ifTtcbiAgfVxufVxuXG4vKipcbiAqIEltcGxlbWVudHMgbW9kaWZpZWQgU1BFIGRpbWVuc2lvbmFsaXR5IHJlZHVjdGlvbi5cbiAqXG4gKiBAY2xhc3MgUFNQRVJlZHVjZXJcbiAqIEBleHRlbmRzIHtSZWR1Y2VyfVxuICovXG5jbGFzcyBQU1BFUmVkdWNlciBleHRlbmRzIFJlZHVjZXIge1xuICBwcm90ZWN0ZWQgcmVkdWNlcjogUFNQRUJhc2U7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgUFNQRVJlZHVjZXIuXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9ucyBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIGNvbnN0cnVjdG9yLlxuICAgKiBAbWVtYmVyb2YgUFNQRVJlZHVjZXJcbiAgICovXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE9wdGlvbnMpIHtcbiAgICBzdXBlcihvcHRpb25zKTtcbiAgICB0aGlzLnJlZHVjZXIgPSBuZXcgUFNQRUJhc2Uob3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogRW1iZWRzIHRoZSBkYXRhIGdpdmVuIGludG8gdGhlIHR3by1kaW1lbnNpb25hbCBzcGFjZSB1c2luZyB0aGUgbW9kaWZpZWQgU1BFIG1ldGhvZC5cbiAgICogQHJldHVybiB7YW55fSBDYXJ0ZXNpYW4gY29vcmRpbmF0ZSBvZiB0aGlzIGVtYmVkZGluZyBhbmQgZGlzdGFuY2UgbWF0cml4IHdoZXJlIGFwcGxpY2FibGUuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgdHJhbnNmb3JtKCk6IFByb21pc2U8SVJlZHVjZURpbWVuc2lvbmFsaXR5UmVzdWx0PiB7XG4gICAgY29uc3QgZW1iID0gYXdhaXQgdGhpcy5yZWR1Y2VyLmVtYmVkKHRoaXMuZGF0YSk7XG4gICAgcmV0dXJuIHtkaXN0YW5jZTogdGhpcy5yZWR1Y2VyLmRpc3RhbmNlLCBlbWJlZGRpbmc6IGVtYn07XG4gIH1cbn1cblxuLyoqXG4gKiBJbXBsZW1lbnRzIG9yaWdpbmFsIFNQRSBkaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24uXG4gKlxuICogQGNsYXNzIE9yaWdpbmFsU1BFUmVkdWNlclxuICogQGV4dGVuZHMge1JlZHVjZXJ9XG4gKi9cbmNsYXNzIE9yaWdpbmFsU1BFUmVkdWNlciBleHRlbmRzIFJlZHVjZXIge1xuICBwcm90ZWN0ZWQgcmVkdWNlcjogT3JpZ2luYWxTUEU7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgT3JpZ2luYWxTUEVSZWR1Y2VyLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucyB0byBwYXNzIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICogQG1lbWJlcm9mIE9yaWdpbmFsU1BFUmVkdWNlclxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9uczogT3B0aW9ucykge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgIHRoaXMucmVkdWNlciA9IG5ldyBPcmlnaW5hbFNQRShvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWJlZHMgdGhlIGRhdGEgZ2l2ZW4gaW50byB0aGUgdHdvLWRpbWVuc2lvbmFsIHNwYWNlIHVzaW5nIHRoZSBvcmlnaW5hbCBTUEUgbWV0aG9kLlxuICAgKiBAcmV0dXJuIHthbnl9IENhcnRlc2lhbiBjb29yZGluYXRlIG9mIHRoaXMgZW1iZWRkaW5nIGFuZCBkaXN0YW5jZSBtYXRyaXggd2hlcmUgYXBwbGljYWJsZS5cbiAgICovXG4gIHB1YmxpYyBhc3luYyB0cmFuc2Zvcm0oKTogUHJvbWlzZTxJUmVkdWNlRGltZW5zaW9uYWxpdHlSZXN1bHQ+IHtcbiAgICBjb25zdCBlbWIgPSBhd2FpdCB0aGlzLnJlZHVjZXIuZW1iZWQodGhpcy5kYXRhKTtcbiAgICByZXR1cm4ge2Rpc3RhbmNlOiB0aGlzLnJlZHVjZXIuZGlzdGFuY2UsIGVtYmVkZGluZzogZW1ifTtcbiAgfVxufVxuXG5jb25zdCBBdmFpbGFibGVSZWR1Y2VycyA9IHtcbiAgJ1VNQVAnOiBVTUFQUmVkdWNlcixcbiAgJ3QtU05FJzogVFNORVJlZHVjZXIsXG4gICdTUEUnOiBTUEVSZWR1Y2VyLFxuICAncFNQRSc6IFBTUEVSZWR1Y2VyLFxuICAnT3JpZ2luYWxTUEUnOiBPcmlnaW5hbFNQRVJlZHVjZXIsXG59O1xuXG5leHBvcnQgdHlwZSBLbm93bk1ldGhvZHMgPSBrZXlvZiB0eXBlb2YgQXZhaWxhYmxlUmVkdWNlcnM7XG5cbi8qKlxuICogVW5pZmllZCBjbGFzcyBpbXBsZW1lbnRpbmcgZGlmZmVyZW50IGRpbWVuc2lvbmFsaXR5IHJlZHVjdGlvbiBtZXRob2RzLlxuICpcbiAqIEBleHBvcnRcbiAqIEBjbGFzcyBEaW1lbnNpb25hbGl0eVJlZHVjZXJcbiAqL1xuZXhwb3J0IGNsYXNzIERpbWVuc2lvbmFsaXR5UmVkdWNlciB7XG4gIHByaXZhdGUgcmVkdWNlcjogUmVkdWNlciB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBEaW1lbnNpb25hbGl0eVJlZHVjZXIuXG4gICAqIEBwYXJhbSB7YW55W119IGRhdGEgVmVjdG9ycyB0byBlbWJlZC5cbiAgICogQHBhcmFtIHtLbm93bk1ldGhvZHN9IG1ldGhvZCBFbWJlZGRpbmcgbWV0aG9kIHRvIGJlIGFwcGxpZWRcbiAgICogQHBhcmFtIHtLbm93bk1ldHJpY3N9IG1ldHJpYyBEaXN0YW5jZSBtZXRyaWMgdG8gYmUgY29tcHV0ZWQgYmV0d2VlbiBlYWNoIG9mIHRoZSB2ZWN0b3JzLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IFtvcHRpb25zXSBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIGltcGxlbWVudGluZyBlbWJlZGRlcnMuXG4gICAqIEBtZW1iZXJvZiBEaW1lbnNpb25hbGl0eVJlZHVjZXJcbiAgICovXG4gIGNvbnN0cnVjdG9yKGRhdGE6IGFueVtdLCBtZXRob2Q6IEtub3duTWV0aG9kcywgbWV0cmljOiBLbm93bk1ldHJpY3MsIG9wdGlvbnM/OiBPcHRpb25zKSB7XG4gICAgY29uc3QgbWVhc3VyZSA9IG5ldyBNZWFzdXJlKG1ldHJpYykuZ2V0TWVhc3VyZShvcHRpb25zPy5kaXN0YW5jZUZuQXJncyk7XG4gICAgbGV0IHNwZWNPcHRpb25zID0ge307XG4gICAgbGV0IGJpdEFycmF5TGVuZ3RoID0gMjA0ODtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyArK2kpIHtcbiAgICAgIGlmIChkYXRhW2ldICYmIGRhdGFbaV0uX2xlbmd0aCkge1xuICAgICAgICBiaXRBcnJheUxlbmd0aCA9IGRhdGFbaV0uX2xlbmd0aDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpc0JpdEFycmF5TWV0cmljKG1ldHJpYykpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7ICsraSkge1xuICAgICAgICBpZiAoZGF0YVtpXSAmJiBkYXRhW2ldLl9kYXRhKVxuICAgICAgICAgIGRhdGFbaV0gPSBuZXcgQml0QXJyYXkoZGF0YVtpXS5fZGF0YSwgZGF0YVtpXS5fbGVuZ3RoKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIGRhdGFbaV0gPSBuZXcgQml0QXJyYXkoYml0QXJyYXlMZW5ndGgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChtZXRob2QgPT0gJ1VNQVAnKSB7XG4gICAgICBzcGVjT3B0aW9ucyA9IHtcbiAgICAgICAgLi4ue2RhdGE6IGRhdGF9LFxuICAgICAgICAuLi57ZGlzdGFuY2VGbjogbWVhc3VyZX0sXG4gICAgICAgIC4uLntkaXN0YW5jZUZuYW1lOiBtZXRyaWN9LFxuICAgICAgICAuLi57bkVwb2Noczogb3B0aW9ucz8uY3ljbGVzfSxcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChtZXRob2QgPT0gJ3QtU05FJykge1xuICAgICAgc3BlY09wdGlvbnMgPSB7XG4gICAgICAgIC4uLntkYXRhOiBkYXRhfSxcbiAgICAgICAgLi4ue2Rpc3RhbmNlRm46IG1lYXN1cmV9LFxuICAgICAgICAuLi57ZGlzdGFuY2VGbmFtZTogbWV0cmljfSxcbiAgICAgICAgLi4ue2l0ZXJhdGlvbnM6IG9wdGlvbnM/LmN5Y2xlcyA/PyB1bmRlZmluZWR9LFxuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKG1ldGhvZCA9PSAnU1BFJykge1xuICAgICAgc3BlY09wdGlvbnMgPSB7Li4ue2RhdGE6IGRhdGF9LCAuLi57ZGlzdGFuY2U6IG1lYXN1cmV9LCBkaXN0YW5jZUZ1bmN0aW9uTmFtZTogbWV0cmljLCAuLi5vcHRpb25zfTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3BlY09wdGlvbnMgPSB7Li4ue2RhdGE6IGRhdGF9LCAuLi57ZGlzdGFuY2U6IG1lYXN1cmV9LCBkaXN0YW5jZUZ1bmN0aW9uTmFtZTogbWV0cmljLCAuLi5vcHRpb25zfTtcbiAgICB9XG4gICAgdGhpcy5yZWR1Y2VyID0gbmV3IEF2YWlsYWJsZVJlZHVjZXJzW21ldGhvZF0oc3BlY09wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVtYmVkcyB0aGUgZGF0YSBnaXZlbiBpbnRvIHRoZSB0d28tZGltZW5zaW9uYWwgc3BhY2UgdXNpbmcgdGhlIGNob3NlbiBtZXRob2QuXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gdHJhbnNwb3NlIFdoZXRoZXIgdG8gdHJhbnNmb3JtIGNvb3JkaW5hdGVzIHRvIGhhdmUgY29sdW1ucy1maXJzdCBvcmllbnRhdGlvbi5cbiAgICogQHBhcmFtIHtib29sZWFufSBwYXJhbGxlbERpc3RhbmNlV29ya2VycyBXaGV0aGVyIHRvIHVzZSBwYXJhbGxlbCBkaXN0YW5jZSBjb21wdXRhdGlvbi5cbiAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBlbWJlZGRpbmcgbWV0aG9kIHdhcyBub3QgZm91bmQuXG4gICAqIEByZXR1cm4ge2FueX0gQ2FydGVzaWFuIGNvb3JkaW5hdGUgb2YgdGhpcyBlbWJlZGRpbmcgYW5kIGRpc3RhbmNlIG1hdHJpeCB3aGVyZSBhcHBsaWNhYmxlLlxuICAgKiBAbWVtYmVyb2YgRGltZW5zaW9uYWxpdHlSZWR1Y2VyXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgdHJhbnNmb3JtKHRyYW5zcG9zZTogYm9vbGVhbiA9IGZhbHNlLCBwYXJhbGxlbERpc3RhbmNlV29ya2Vycz86IGJvb2xlYW4pOiBQcm9taXNlPElSZWR1Y2VEaW1lbnNpb25hbGl0eVJlc3VsdD4ge1xuICAgIGlmICh0aGlzLnJlZHVjZXIgPT09IHVuZGVmaW5lZClcbiAgICAgIHRocm93IG5ldyBFcnJvcignUmVkdWNlciB3YXMgbm90IGRlZmluZWQuJyk7XG5cbiAgICBsZXQge2VtYmVkZGluZywgZGlzdGFuY2V9ID0gYXdhaXQgdGhpcy5yZWR1Y2VyLnRyYW5zZm9ybShwYXJhbGxlbERpc3RhbmNlV29ya2Vycyk7XG5cbiAgICBpZiAodHJhbnNwb3NlKVxuICAgICAgZW1iZWRkaW5nID0gdHJhbnNwb3NlTWF0cml4KGVtYmVkZGluZyk7XG5cbiAgICByZXR1cm4ge2Rpc3RhbmNlOiBkaXN0YW5jZSwgZW1iZWRkaW5nOiBlbWJlZGRpbmd9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgbWV0cmljcyBhdmFpbGFibGUgYnkgdHlwZS5cbiAgICpcbiAgICogQHBhcmFtIHtBdmFpbGFibGVEYXRhVHlwZXN9IHR5cGVOYW1lIHR5cGUgbmFtZVxuICAgKiBAcmV0dXJuIHtzdHJpbmdbXX0gTWV0cmljIG5hbWVzIHdoaWNoIGV4cGVjdHMgdGhlIGdpdmVuIGRhdGEgdHlwZVxuICAgKiBAbWVtYmVyb2YgRGltZW5zaW9uYWxpdHlSZWR1Y2VyXG4gICAqL1xuICBzdGF0aWMgYXZhaWxhYmxlTWV0cmljc0J5VHlwZSh0eXBlTmFtZTogQXZhaWxhYmxlRGF0YVR5cGVzKSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKEF2YWlsYWJsZU1ldHJpY3NbdHlwZU5hbWVdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGRpbWVuc2lvbmFsaXR5IHJlZHVjdGlvbiBtZXRob2RzIGF2YWlsYWJsZS5cbiAgICpcbiAgICogQHJlYWRvbmx5XG4gICAqIEBtZW1iZXJvZiBEaW1lbnNpb25hbGl0eVJlZHVjZXJcbiAgICovXG4gIHN0YXRpYyBnZXQgYXZhaWxhYmxlTWV0aG9kcygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMoQXZhaWxhYmxlUmVkdWNlcnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgbWV0cmljcyBhdmFpbGFibGUuXG4gICAqXG4gICAqIEByZWFkb25seVxuICAgKiBAbWVtYmVyb2YgRGltZW5zaW9uYWxpdHlSZWR1Y2VyXG4gICAqL1xuICBzdGF0aWMgZ2V0IGF2YWlsYWJsZU1ldHJpY3MoKSB7XG4gICAgbGV0IGFuczogc3RyaW5nW10gPSBbXTtcbiAgICBPYmplY3QudmFsdWVzKEF2YWlsYWJsZU1ldHJpY3MpLmZvckVhY2goKG9iaikgPT4ge1xuICAgICAgY29uc3QgYXJyYXkgPSBPYmplY3QudmFsdWVzKG9iaik7XG4gICAgICBhbnMgPSBbLi4uYW5zLCAuLi5hcnJheV07XG4gICAgfSk7XG4gICAgcmV0dXJuIGFucztcbiAgfVxufVxuIl19","import { DimensionalityReducer } from '../reduce-dimensionality';\n/**\n * Worker thread receiving data function.\n *\n * @param {any[]} columnData Samples to process.\n * @param {KnownMethods} method Embedding method.\n * @param {KnownMetrics} measure Distance metric.\n * @param {any} options Options to pass to algorithm.\n * @param {boolean} parallelDistanceWorkers Whether to use parallel distance workers.\n * @return {any} Embedding (and distance matrix where applicable).\n */\nasync function onMessage(columnData, method, measure, options, parallelDistanceWorkers) {\n const reducer = new DimensionalityReducer(columnData, method, measure, { ...options, progressFunc });\n return await reducer.transform(true, parallelDistanceWorkers);\n}\nasync function progressFunc(epochNum, epochsLength, embedding) {\n if (epochNum % 5 === 0)\n self.postMessage({ epochNum, epochsLength, embedding });\n}\nself.onmessage = async ({ data: { columnData, method, measure, options, parallelDistanceWorkers } }) => {\n let data;\n try {\n data = await onMessage(columnData, method, measure, options, parallelDistanceWorkers);\n }\n catch (e) {\n data = { error: e };\n }\n self.postMessage({\n error: data.error,\n distance: data.distance,\n embedding: data.embedding,\n });\n};\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGltZW5zaW9uYWxpdHktcmVkdWNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImRpbWVuc2lvbmFsaXR5LXJlZHVjZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLHFCQUFxQixFQUFlLE1BQU0sMEJBQTBCLENBQUM7QUFHN0U7Ozs7Ozs7OztHQVNHO0FBQ0gsS0FBSyxVQUFVLFNBQVMsQ0FBQyxVQUFpQixFQUFFLE1BQW9CLEVBQUUsT0FBcUIsRUFDckYsT0FBYSxFQUFFLHVCQUFpQztJQUNoRCxNQUFNLE9BQU8sR0FBRyxJQUFJLHFCQUFxQixDQUN2QyxVQUFVLEVBQ1YsTUFBTSxFQUNOLE9BQU8sRUFDUCxFQUFDLEdBQUcsT0FBTyxFQUFFLFlBQVksRUFBQyxDQUMzQixDQUFDO0lBQ0YsT0FBTyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLHVCQUF1QixDQUFDLENBQUM7QUFDaEUsQ0FBQztBQUVELEtBQUssVUFBVSxZQUFZLENBQUUsUUFBZ0IsRUFBRSxZQUFvQixFQUFFLFNBQXFCO0lBQ3hGLElBQUksUUFBUSxHQUFHLENBQUMsS0FBSyxDQUFDO1FBQ3BCLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBQyxRQUFRLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBQyxDQUFDLENBQUM7QUFDMUQsQ0FBQztBQUVELElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxFQUFFLEVBQUMsSUFBSSxFQUFFLEVBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLHVCQUF1QixFQUFDLEVBQUMsRUFBRSxFQUFFO0lBQ2pHLElBQUksSUFBb0QsQ0FBQztJQUN6RCxJQUFJO1FBQ0YsSUFBSSxHQUFHLE1BQU0sU0FBUyxDQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO0tBQ3ZGO0lBQUMsT0FBTyxDQUFNLEVBQUU7UUFDZixJQUFJLEdBQUcsRUFBQyxLQUFLLEVBQUUsQ0FBQyxFQUFDLENBQUM7S0FDbkI7SUFDRCxJQUFJLENBQUMsV0FBVyxDQUFDO1FBQ2YsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO1FBQ2pCLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtRQUN2QixTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7S0FDMUIsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtEaW1lbnNpb25hbGl0eVJlZHVjZXIsIEtub3duTWV0aG9kc30gZnJvbSAnLi4vcmVkdWNlLWRpbWVuc2lvbmFsaXR5JztcbmltcG9ydCB7S25vd25NZXRyaWNzfSBmcm9tICcuLi90eXBlZC1tZXRyaWNzL3R5cGVkLW1ldHJpY3MnO1xuXG4vKipcbiAqIFdvcmtlciB0aHJlYWQgcmVjZWl2aW5nIGRhdGEgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIHthbnlbXX0gY29sdW1uRGF0YSBTYW1wbGVzIHRvIHByb2Nlc3MuXG4gKiBAcGFyYW0ge0tub3duTWV0aG9kc30gbWV0aG9kIEVtYmVkZGluZyBtZXRob2QuXG4gKiBAcGFyYW0ge0tub3duTWV0cmljc30gbWVhc3VyZSBEaXN0YW5jZSBtZXRyaWMuXG4gKiBAcGFyYW0ge2FueX0gb3B0aW9ucyBPcHRpb25zIHRvIHBhc3MgdG8gYWxnb3JpdGhtLlxuICogQHBhcmFtIHtib29sZWFufSBwYXJhbGxlbERpc3RhbmNlV29ya2VycyBXaGV0aGVyIHRvIHVzZSBwYXJhbGxlbCBkaXN0YW5jZSB3b3JrZXJzLlxuICogQHJldHVybiB7YW55fSBFbWJlZGRpbmcgKGFuZCBkaXN0YW5jZSBtYXRyaXggd2hlcmUgYXBwbGljYWJsZSkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIG9uTWVzc2FnZShjb2x1bW5EYXRhOiBhbnlbXSwgbWV0aG9kOiBLbm93bk1ldGhvZHMsIG1lYXN1cmU6IEtub3duTWV0cmljcyxcbiAgb3B0aW9ucz86IGFueSwgcGFyYWxsZWxEaXN0YW5jZVdvcmtlcnM/OiBib29sZWFuKTogUHJvbWlzZTx7ZGlzdGFuY2U/OiBhbnksIGVtYmVkZGluZz86IGFueX0+IHtcbiAgY29uc3QgcmVkdWNlciA9IG5ldyBEaW1lbnNpb25hbGl0eVJlZHVjZXIoXG4gICAgY29sdW1uRGF0YSxcbiAgICBtZXRob2QsXG4gICAgbWVhc3VyZSxcbiAgICB7Li4ub3B0aW9ucywgcHJvZ3Jlc3NGdW5jfSxcbiAgKTtcbiAgcmV0dXJuIGF3YWl0IHJlZHVjZXIudHJhbnNmb3JtKHRydWUsIHBhcmFsbGVsRGlzdGFuY2VXb3JrZXJzKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcHJvZ3Jlc3NGdW5jIChlcG9jaE51bTogbnVtYmVyLCBlcG9jaHNMZW5ndGg6IG51bWJlciwgZW1iZWRkaW5nOiBudW1iZXJbXVtdKSB7XG4gIGlmIChlcG9jaE51bSAlIDUgPT09IDApXG4gICAgc2VsZi5wb3N0TWVzc2FnZSh7ZXBvY2hOdW0sIGVwb2Noc0xlbmd0aCwgZW1iZWRkaW5nfSk7XG59XG5cbnNlbGYub25tZXNzYWdlID0gYXN5bmMgKHtkYXRhOiB7Y29sdW1uRGF0YSwgbWV0aG9kLCBtZWFzdXJlLCBvcHRpb25zLCBwYXJhbGxlbERpc3RhbmNlV29ya2Vyc319KSA9PiB7XG4gIGxldCBkYXRhOiB7ZXJyb3I/OiBhbnksIGRpc3RhbmNlPzogYW55LCBlbWJlZGRpbmc/OiBhbnl9O1xuICB0cnkge1xuICAgIGRhdGEgPSBhd2FpdCBvbk1lc3NhZ2UoY29sdW1uRGF0YSwgbWV0aG9kLCBtZWFzdXJlLCBvcHRpb25zLCBwYXJhbGxlbERpc3RhbmNlV29ya2Vycyk7XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGRhdGEgPSB7ZXJyb3I6IGV9O1xuICB9XG4gIHNlbGYucG9zdE1lc3NhZ2Uoe1xuICAgIGVycm9yOiBkYXRhLmVycm9yLFxuICAgIGRpc3RhbmNlOiBkYXRhLmRpc3RhbmNlLFxuICAgIGVtYmVkZGluZzogZGF0YS5lbWJlZGRpbmcsXG4gIH0pO1xufTtcbiJdfQ==","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.TSNE = void 0;\nvar tsne_1 = require(\"./tsne\");\nObject.defineProperty(exports, \"TSNE\", { enumerable: true, get: function () { return tsne_1.TSNE; } });\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.TSNE = void 0;\nclass TSNE {\n constructor(opt) {\n // return 0 mean unit standard deviation random number\n this.returnV = false;\n this.vValue = 0.0;\n this.iter = 0;\n opt = opt || {};\n this.perplexity = this.getopt(opt, 'perplexity', 30); // effective number of nearest neighbors\n this.dim = this.getopt(opt, 'dim', 2); // by default 2-D tSNE\n this.epsilon = this.getopt(opt, 'epsilon', 10); // learning rate\n }\n assert(condition, message) {\n if (!condition) {\n throw message || 'Assertion failed';\n }\n }\n // syntax sugar\n getopt(opt, field, defaultval) {\n if (opt.hasOwnProperty(field)) {\n return opt[field];\n }\n else {\n return defaultval;\n }\n }\n gaussRandom() {\n if (this.returnV) {\n this.returnV = false;\n return this.vValue;\n }\n const u = 2 * Math.random() - 1;\n const v = 2 * Math.random() - 1;\n const r = u * u + v * v;\n if (r === 0 || r > 1) {\n return this.gaussRandom();\n }\n const c = Math.sqrt(-2 * Math.log(r) / r);\n this.vValue = v * c; // cache this for next function call for efficiency\n this.returnV = true;\n return u * c;\n }\n // return random normal number\n randn(mu, std) { return mu + this.gaussRandom() * std; }\n // utilitity that creates contiguous vector of zeros of size n\n zeros(n) {\n if (typeof (n) === 'undefined' || isNaN(n)) {\n return [];\n }\n if (typeof ArrayBuffer === 'undefined') {\n // lacking browser support\n const arr = new Array(n);\n for (let i = 0; i < n; i++) {\n arr[i] = 0;\n }\n return arr;\n }\n else {\n return new Float64Array(n); // typed arrays are faster\n }\n }\n // utility that returns 2d array filled with random numbers\n // or with value s, if provided\n randn2d(n, d, s) {\n const uses = typeof s !== 'undefined';\n const x = [];\n for (let i = 0; i < n; i++) {\n const xhere = [];\n for (let j = 0; j < d; j++) {\n if (uses) {\n xhere.push(s);\n }\n else {\n xhere.push(this.randn(0.0, 1e-4));\n }\n }\n x.push(xhere);\n }\n return x;\n }\n // compute L2 distance between two vectors\n L2(x1, x2) {\n const D = x1.length;\n let d = 0;\n for (let i = 0; i < D; i++) {\n const x1i = x1[i];\n const x2i = x2[i];\n d += (x1i - x2i) * (x1i - x2i);\n }\n return d;\n }\n // compute pairwise distance in all vectors in X\n xtod(X) {\n const N = X.length;\n const dist = this.zeros(N * N); // allocate contiguous array\n for (let i = 0; i < N; i++) {\n for (let j = i + 1; j < N; j++) {\n const d = this.L2(X[i], X[j]);\n dist[i * N + j] = d;\n dist[j * N + i] = d;\n }\n }\n return dist;\n }\n // compute (p_{i|j} + p_{j|i})/(2n)\n d2p(D, perplexity, tol) {\n const nf = Math.sqrt(D.length); // this better be an integer\n const n = Math.floor(nf);\n this.assert(n === nf, 'D should have square number of elements.');\n const hTarget = Math.log(perplexity); // target entropy of distribution\n const P = this.zeros(n * n); // temporary probability matrix\n const prow = this.zeros(n); // a temporary storage compartment\n for (let i = 0; i < n; i++) {\n let betamin = -Infinity;\n let betamax = Infinity;\n let beta = 1; // initial value of precision\n let done = false;\n const maxtries = 50;\n // perform binary search to find a suitable precision beta\n // so that the entropy of the distribution is appropriate\n let num = 0;\n while (!done) {\n //debugger;\n // compute entropy and kernel row with beta precision\n let psum = 0.0;\n for (let j = 0; j < n; j++) {\n let pj = Math.exp(-D[i * n + j] * beta);\n if (i === j) {\n pj = 0;\n } // we dont care about diagonals\n prow[j] = pj;\n psum += pj;\n }\n // normalize p and compute entropy\n let nHere = 0.0;\n for (let j = 0; j < n; j++) {\n let pj;\n if (psum === 0) {\n pj = 0;\n }\n else {\n pj = prow[j] / psum;\n }\n prow[j] = pj;\n if (pj > 1e-7) {\n nHere -= pj * Math.log(pj);\n }\n }\n // adjust beta based on result\n if (nHere > hTarget) {\n // entropy was too high (distribution too diffuse)\n // so we need to increase the precision for more peaky distribution\n betamin = beta; // move up the bounds\n if (betamax === Infinity) {\n beta = beta * 2;\n }\n else {\n beta = (beta + betamax) / 2;\n }\n }\n else {\n // converse case. make distrubtion less peaky\n betamax = beta;\n if (betamin === -Infinity) {\n beta = beta / 2;\n }\n else {\n beta = (beta + betamin) / 2;\n }\n }\n // stopping conditions: too many tries or got a good precision\n num++;\n if (Math.abs(nHere - hTarget) < tol) {\n done = true;\n }\n if (num >= maxtries) {\n done = true;\n }\n }\n // console.log('data point ' + i + ' gets precision ' + beta + ' after ' + num + ' binary search steps.');\n // copy over the final prow to P at row i\n for (let j = 0; j < n; j++) {\n P[i * n + j] = prow[j];\n }\n } // end loop over examples i\n // symmetrize P and normalize it to sum to 1 over all ij\n const pOut = this.zeros(n * n);\n const N2 = n * 2;\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++) {\n pOut[i * n + j] = Math.max((P[i * n + j] + P[j * n + i]) / N2, 1e-100);\n }\n }\n return pOut;\n }\n // helper function\n sign(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }\n // this function takes a set of high-dimensional points\n // and creates matrix P from them using gaussian kernel\n initDataRaw(X) {\n const N = X.length;\n const D = X[0].length;\n this.assert(N > 0, ' X is empty? You must have some data!');\n this.assert(D > 0, ' X[0] is empty? Where is the data?');\n const dists = this.xtod(X); // convert X to distances using gaussian kernel\n this.P = this.d2p(dists, this.perplexity, 1e-4); // attach to object\n this.N = N; // back up the size of the dataset\n this.initSolution(); // refresh this\n }\n // this function takes a given distance matrix and creates\n // matrix P from them.\n // D is assumed to be provided as a list of lists, and should be symmetric\n initDataDist(D) {\n const N = D.length;\n this.assert(N > 0, ' X is empty? You must have some data!');\n // convert D to a (fast) typed array version\n const dists = this.zeros(N * N); // allocate contiguous array\n for (let i = 0; i < N; i++) {\n for (let j = i + 1; j < N; j++) {\n const d = D[i][j];\n dists[i * N + j] = d;\n dists[j * N + i] = d;\n }\n }\n this.P = this.d2p(dists, this.perplexity, 1e-4);\n this.N = N;\n this.initSolution(); // refresh this\n }\n // (re)initializes the solution to random\n initSolution() {\n // generate random solution to t-SNE\n this.Y = this.randn2d(this.N, this.dim); // the solution\n this.gains = this.randn2d(this.N, this.dim, 1.0); // step gains to accelerate progress in unchanging directions\n this.ystep = this.randn2d(this.N, this.dim, 0.0); // momentum accumulator\n this.iter = 0;\n }\n // return pointer to current solution\n getSolution() {\n return this.Y;\n }\n // perform a single step of optimization to improve the embedding\n step() {\n this.iter += 1;\n const N = this.N;\n const cg = this.costGrad(this.Y); // evaluate gradient\n const cost = cg.cost;\n const grad = cg.grad;\n // perform gradient step\n const ymean = this.zeros(this.dim);\n for (let i = 0; i < N; i++) {\n for (let d = 0; d < this.dim; d++) {\n const gid = grad[i][d];\n const sid = this.ystep[i][d];\n const gainid = this.gains[i][d];\n // compute gain update\n let newgain = this.sign(gid) === this.sign(sid) ? gainid * 0.8 : gainid + 0.2;\n if (newgain < 0.01) {\n newgain = 0.01;\n } // clamp\n this.gains[i][d] = newgain; // store for next turn\n // compute momentum step direction\n const momval = this.iter < 250 ? 0.5 : 0.8;\n const newsid = momval * sid - this.epsilon * newgain * grad[i][d];\n this.ystep[i][d] = newsid; // remember the step we took\n // step!\n this.Y[i][d] += newsid;\n ymean[d] += this.Y[i][d]; // accumulate mean so that we can center later\n }\n }\n // reproject Y to be zero mean\n for (let i = 0; i < N; i++) {\n for (let d = 0; d < this.dim; d++) {\n this.Y[i][d] -= ymean[d] / N;\n }\n }\n //if(this.iter%100===0) console.log('iter ' + this.iter + ', cost: ' + cost);\n return cost; // return current cost\n }\n // for debugging: gradient check\n debugGrad() {\n const N = this.N;\n const cg = this.costGrad(this.Y); // evaluate gradient\n const cost = cg.cost;\n const grad = cg.grad;\n const e = 1e-5;\n for (let i = 0; i < N; i++) {\n for (let d = 0; d < this.dim; d++) {\n const yold = this.Y[i][d];\n this.Y[i][d] = yold + e;\n const cg0 = this.costGrad(this.Y);\n this.Y[i][d] = yold - e;\n const cg1 = this.costGrad(this.Y);\n const analytic = grad[i][d];\n const numerical = (cg0.cost - cg1.cost) / (2 * e);\n console.log(i + ',' + d + ': gradcheck analytic: ' + analytic + ' vs. numerical: ' + numerical);\n this.Y[i][d] = yold;\n }\n }\n }\n // return cost and gradient, given an arrangement\n costGrad(Y) {\n const N = this.N;\n const dim = this.dim; // dim of output space\n const P = this.P;\n const pmul = this.iter < 100 ? 4 : 1; // trick that helps with local optima\n // compute current Q distribution, unnormalized first\n const quArr = this.zeros(N * N);\n let qsum = 0.0;\n for (let i = 0; i < N; i++) {\n for (let j = i + 1; j < N; j++) {\n let dsum = 0.0;\n for (let d = 0; d < dim; d++) {\n const dhere = Y[i][d] - Y[j][d];\n dsum += dhere * dhere;\n }\n const qu = 1.0 / (1.0 + dsum); // Student t-distribution\n quArr[i * N + j] = qu;\n quArr[j * N + i] = qu;\n qsum += 2 * qu;\n }\n }\n // normalize Q distribution to sum to 1\n const NN = N * N;\n const Q = this.zeros(NN);\n for (let q = 0; q < NN; q++) {\n Q[q] = Math.max(quArr[q] / qsum, 1e-100);\n }\n let cost = 0.0;\n const grad = [];\n for (let i = 0; i < N; i++) {\n const gsum = new Array(dim); // init grad for point i\n for (let d = 0; d < dim; d++) {\n gsum[d] = 0.0;\n }\n for (let j = 0; j < N; j++) {\n cost += -P[i * N + j] * Math.log(Q[i * N + j]); // accumulate cost (the non-constant portion at least...)\n const premult = 4 * (pmul * P[i * N + j] - Q[i * N + j]) * quArr[i * N + j];\n for (let d = 0; d < dim; d++) {\n gsum[d] += premult * (Y[i][d] - Y[j][d]);\n }\n }\n grad.push(gsum);\n }\n return { cost, grad };\n }\n}\nexports.TSNE = TSNE;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n// the startup function\n__webpack_require__.x = () => {\n\t// Load entry module and return exports\n\t// This entry module depends on other loaded chunks and execution need to be delayed\n\tvar __webpack_exports__ = __webpack_require__.O(undefined, [562,44], () => (__webpack_require__(3935)))\n\t__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n\treturn __webpack_exports__;\n};\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__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = (chunkId) => {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks and sibling chunks for the entrypoint\n__webpack_require__.u = (chunkId) => {\n\t// return url for filenames based on template\n\treturn \"\" + chunkId + \".js\";\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","var scriptUrl;\nif (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + \"\";\nvar document = __webpack_require__.g.document;\nif (!scriptUrl && document) {\n\tif (document.currentScript)\n\t\tscriptUrl = document.currentScript.src;\n\tif (!scriptUrl) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tif(scripts.length) {\n\t\t\tvar i = scripts.length - 1;\n\t\t\twhile (i > -1 && !scriptUrl) scriptUrl = scripts[i--].src;\n\t\t}\n\t}\n}\n// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration\n// or pass an empty string (\"\") and set the __webpack_public_path__ variable from your code to use your own logic.\nif (!scriptUrl) throw new Error(\"Automatic publicPath is not supported in this browser\");\nscriptUrl = scriptUrl.replace(/#.*$/, \"\").replace(/\\?.*$/, \"\").replace(/\\/[^\\/]+$/, \"/\");\n__webpack_require__.p = scriptUrl;","__webpack_require__.b = self.location + \"\";\n\n// object to store loaded chunks\n// \"1\" means \"already loaded\"\nvar installedChunks = {\n\t935: 1\n};\n\n// importScripts chunk loading\nvar installChunk = (data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\tfor(var moduleId in moreModules) {\n\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t}\n\t}\n\tif(runtime) runtime(__webpack_require__);\n\twhile(chunkIds.length)\n\t\tinstalledChunks[chunkIds.pop()] = 1;\n\tparentChunkLoadingFunction(data);\n};\n__webpack_require__.f.i = (chunkId, promises) => {\n\t// \"1\" is the signal for \"already loaded\"\n\tif(!installedChunks[chunkId]) {\n\t\tif(true) { // all chunks have JS\n\t\t\timportScripts(__webpack_require__.p + __webpack_require__.u(chunkId));\n\t\t}\n\t}\n};\n\nvar chunkLoadingGlobal = self[\"webpackChunkbio\"] = self[\"webpackChunkbio\"] || [];\nvar parentChunkLoadingFunction = chunkLoadingGlobal.push.bind(chunkLoadingGlobal);\nchunkLoadingGlobal.push = installChunk;\n\n// no HMR\n\n// no HMR manifest","// run startup\nvar __webpack_exports__ = __webpack_require__.x();\n"],"names":["deferred","next","Float32Array","randomFloat","range","Math","random","floor","assert","condition","message","Error","vectorAdd","p","q","multiplier","nItems","length","total","i","fillRandomMatrix","dimension1","dimension2","scale","matrix","fill","Array","map","initCoordinates","j","calculateEuclideanDistance","result","len","pow","sqrt","dmLinearIndex","size","DistanceMatrixService","constructor","useConcurrentWorkers","terminateOnComplete","threadCount","navigator","hardwareConcurrency","this","_workerCount","max","_workers","Worker","URL","_terminateOnComplete","async","values","fnName","normalize","opts","Promise","resolve","reject","promises","totalLength","min","chunkSize","distanceMatrix","endRow","endCol","lmin","lmax","Number","MIN_VALUE","start","end","startRow","startCol","postMessage","chunckSize","resolveWorker","rejectWorker","onmessage","data","error","distanceMatrixData","terminate","set","all","forEach","value","index","e","worker","SPEBase","options","steps","cycles","cutoff","lambda","dlambda","lambda2","dlambda2","epsilon","distanceFunction","distance","distanceFunctionName","vectors","dmIndexFunct","matrixService","calc","calcDistance","index1","index2","coordinates","dimension","initDistance","cycle","step","rowi","rowj","r","d","diffIJ","PSPEBase","OriginalSPE","super","radiusPercent","maxDistance","maxDistanceSteps","n","radius","StringMetricsNames","VectorMetricsNames","BitArrayMetricsNames","IntArrayMetricsNames","DistanceMetricsSubjects","NumberMetricsNames","tanimotoSimilarity","x","y","trueCount","common","andWithCountBits","getDistanceFromSimilarity","similarity","Tanimoto","Dice","Asymmetric","BraunBlanquet","Cosine","Kulczynski","McConnaughey","RogotGoldberg","Russel","Sokal","Hamming","Euclidean","HAMMING","LEVENSHTEIN","MONOMER_CHEMICAL_DISTANCE","NEEDLEMANN_WUNSCH","vectorDistanceMetricsMethods","stringDistanceMetricsMethods","Levenshtein","JaroWinkler","Manhattan","s1","s2","dist","bitArrayDistanceMetricsMethods","diceSimilarity","asymmetricSimilarity","braunBlanquetSimilarity","cosineSimilarity","totalProd","kulczynskiSimilarity","mcConnaugheySimilarity","countBits","diff","rogotGoldbergSimilarity","russelSimilarity","sokalSimilarity","intArrayDistanceMetricsMethods","TanimotoIntArray","numberDistanceMetricsMethods","Difference","abs","AvailableMetrics","Vector","String","BitArray","MacroMolecule","IntArray","MetricToDataType","Object","keys","reduce","ret","key","val","Measure","method","dataType","getMeasure","dict","hasOwnProperty","name","toString","static","availableMeasures","tauRandInt","tauRand","empty","output","push","undefined","_","filled","v","zeros","mean","input","sum","rejectionSample","nSamples","poolSize","rejectSample","broken","k","reshape2d","a","b","rows","count","col","makeHeap","nPoints","makeArrays","fillValue","heap","Infinity","heapPush","row","weight","flag","indices","weights","uncheckedHeapPush","isNew","iSwap","ic1","ic2","heapShape2","buildCandidates","currentGraph","nVertices","nNeighbors","maxCandidates","candidateNeighbors","idx","isn","deheapSort","indHeap","distHeap","indHeapIndex","distHeapIndex","temp1","temp2","siftDown","heap1","heap2","ceiling","elt","leftChild","rightChild","swap","smallestFlagged","ind","minDist","resultIndex","SparseMatrix","cols","dims","entries","Map","nRows","nCols","checkDims","makeKey","has","get","defaultValue","getAll","ordered","rowColValues","sort","getDims","getRows","from","getCols","getValues","fn","vals","toArray","oldRows","oldCols","oldVals","matlen","Int32Array","pairwiseMultiply","elementWise","add","subtract","multiplyScalar","scalar","eliminateZeros","m","zeroIndices","Set","removeByZeroIndex","nextValues","filter","nextRows","nextCols","normType","normFn","normFns","colsByRow","nextMatrix","norm","xs","op","visited","operate","nextValue","valuesA","rowsA","colsA","valuesB","rowsB","colsB","getCSR","indptr","currentRow","FlatTree","hyperplanes","offsets","children","makeForest","nTrees","leafSize","trees","makeEuclideanTree","makeTree","forest","tree","nNodes","numNodes","nLeaves","numLeaves","hyperplane","recursiveFlatten","flattenTree","splitResults","leftIndex","rightIndex","left","right","hyperplaneOffset","hyperplaneVector","nLeft","nRight","side","margin","indicesLeft","indicesRight","offset","euclideanRandomProjectionSplit","isLeaf","nodeNum","leafNum","splice","oldNodeNum","res","selectSide","point","searchFlatTree","node","prototype","isAnyArray","object","call","endsWith","errorCalculation","parameters","parameterizedFunction","func","rescale","arguments","TypeError","currentMin","_options$fromIndex","fromIndex","_options$toIndex","toIndex","isInteger","minValue","currentMax","maxValue","RangeError","_options$min","autoMinMax","_options$max","factor","indent","repeat","indentData","inspectMatrixWithOptions","maxRows","maxColumns","maxNumSize","padMinus","columns","maxI","maxJ","loop","line","formatNumber","join","inspectData","num","formatNumber2","padEnd","str","fix","toFixed","startsWith","exp","toExponential","slice","checkRowIndex","outer","checkColumnIndex","checkRowVector","vector","to1DArray","checkColumnVector","checkRange","startColumn","endColumn","checkNumber","newArray","array","checkNonEmpty","isEmpty","AbstractMatrix","newRows","newColumns","newData","newMatrix","column","interval","round","l","matrix1","matrix2","checkMatrix","isMatrix","klass","apply","callback","to2DArray","copy","toJSON","isRowVector","isColumnVector","isVector","isSquare","isSymmetric","isEchelonForm","previousColumn","checked","isReducedEchelonForm","echelonForm","clone","h","iMax","swapRows","tmp","reducedEchelonForm","maxRow","pivot","setSubMatrix","neg","mulS","getRow","getRowVector","rowVector","setRow","row1","row2","temp","getColumn","getColumnVector","columnVector","setColumn","swapColumns","column1","column2","addRowVector","subRowVector","mulRowVector","divRowVector","addColumnVector","subColumnVector","mulColumnVector","divColumnVector","mulRow","mulColumn","by","NaN","NEGATIVE_INFINITY","maxIndex","POSITIVE_INFINITY","minIndex","maxRowIndex","minRow","minRowIndex","maxColumn","maxColumnIndex","minColumn","minColumnIndex","diag","type","cumulativeSum","dot","vector2","vector1","mmul","other","Bcolj","Float64Array","s","strassen2x2","a11","b11","a12","b12","a21","b21","a22","b22","m1","m2","m3","m4","m5","c00","c01","c10","c11","strassen3x3","a00","a01","a02","a10","a20","b00","b01","b02","b10","b20","m6","m7","m8","m9","m12","m13","m14","m15","m16","m17","m18","c02","c12","c20","c21","c22","mmulStrassen","r1","c1","r2","c2","embed","mat","c","resultat","console","warn","blockMult","halfRows","parseInt","halfCols","subMatrix","sub","scaleRows","isFinite","scaleColumns","flipRows","middle","ceil","first","last","flipColumns","kroneckerProduct","kroneckerSum","AxI","eye","IxB","transpose","sortRows","compareFunction","compareNumbers","sortColumns","subMatrixRow","subMatrixColumn","selection","rowIndices","columnIndices","checkRowIndices","checkColumnIndices","rowIndex","columnIndex","trace","sumByRow","sumByColumn","sumAll","product","productByRow","productByColumn","productAll","variance","unbiased","sum1","sum2","varianceByRow","varianceByColumn","varianceAll","standardDeviation","center","centerByRow","centerByColumn","centerAll","getScaleByRow","scaleByRow","getScaleByColumn","scaleByColumn","divider","getScaleAll","scaleAll","Symbol","for","rand","randomInt","randInt","diagonal","identity","negate","tensorProduct","nColumns","arrayData","every","element","removeRow","addRow","removeColumn","newRow","addColumn","Matrix","addS","addM","subS","subM","subtractS","subtractM","mul","mulM","multiply","multiplyS","multiplyM","div","divS","divM","divide","divideS","divideM","mod","modS","modM","modulus","modulusS","modulusM","and","andS","andM","or","orS","orM","xor","xorS","xorM","leftShift","leftShiftS","leftShiftM","signPropagatingRightShift","signPropagatingRightShiftS","signPropagatingRightShiftM","rightShift","rightShiftS","rightShiftM","zeroFillRightShift","zeroFillRightShiftS","zeroFillRightShiftM","not","acos","acosh","asin","asinh","atan","atanh","cbrt","clz32","cos","cosh","expm1","fround","log","log1p","log10","log2","sign","sin","sinh","tan","tanh","trunc","arg0","powS","powM","installMathOperations","WrapperMatrix2D","LuDecomposition","t","LUcolj","kmax","lu","pivotVector","pivotSign","LU","isSingular","solve","X","determinant","lowerTriangularMatrix","upperTriangularMatrix","pivotPermutationVector","hypotenuse","QrDecomposition","qr","rdiag","nrm","QR","Rdiag","isFullRank","orthogonalMatrix","SingularValueDecomposition","computeLeftSingularVectors","computeRightSingularVectors","autoTranspose","wantu","Boolean","wantv","swapped","aux","nu","ni","U","V","work","si","nct","nrt","mrc","pp","iter","eps","EPSILON","kase","alpha","isNaN","ks","f","cs","sn","sp","spm1","epm1","sk","ek","shift","g","Y","threshold","scols","Ls","rightSingularVectors","VL","vrows","urows","VLU","solveForDiagonal","inverse","vcols","ucols","norm2","rank","tol","ii","leftSingularVectors","diagonalMatrix","params","damping","gradientDifference","evaluatedData","gradientFunc","paramFunction","ans","param","auxParams","funcParam","gradientFunction","matrixFunc","matrixFunction","inverseMatrix","useSVD","leftHandSide","rightHandSide","SMOOTH_K_TOLERANCE","MIN_K_DIST_SCALE","UMAP","neighbors","learningRate","localConnectivity","nComponents","nEpochs","negativeSampleRate","repulsionStrength","setOpMixRatio","spread","transformQueueSize","targetMetric","targetWeight","targetNNeighbors","distanceFn","numeric","isInitialized","rpForest","embedding","optimizationState","OptimizationState","setParam","fit","initializeFit","optimizeLayout","optimizeLayoutAsync","setSupervisedProjection","setPrecomputedKNN","knnIndices","knnDistances","getNEpochs","knnResults","nearestNeighbors","graph","fuzzySimplicialSet","makeSearchFns","searchGraph","makeSearchGraph","processGraphForSupervisedProjection","head","tail","epochsPerSample","initializeSimplicialSetEmbedding","initializeOptimization","prepareForOptimizationLoop","initFromTree","initFromRandom","queryPoints","_heap","_tree","search","initialization","tried","vertex","candidates","candidate","knn","distances","neighbor","transform","toTransform","rawData","init","results","adjustedLocalConnectivity","sigmas","rhos","smoothKNNDistance","computeMembershipStrengths","csrMatrix","z","initTransform","graphMax","makeEpochsPerSample","assignOptimizationStateParameters","headEmbedding","tailEmbedding","currentEpoch","farDist","categoricalSimplicialSetIntersection","optimizeLayoutStep","getEmbedding","metricNNDescent","leafArray","nIters","delta","rho","rpTreeInit","cj","ck","sparseMatrix","prodMatrix","simplicialSet","target","unknownDist","intersection","fastIntersection","resetLocalConnectivity","nIter","bandwidth","lo","hi","mid","ithDistances","nonZeroDists","interpolation","psum","meanIthDistances","meanDistances","graphValues","entry","w","state","assign","dim","moveOther","epochsPerNegativeSample","epochOfNextNegativeSample","epochOfNextSample","initialAlpha","gamma","xv","yv","parameterValues","maxIterations","errorTolerance","minValues","maxValues","initialValues","parLen","MAX_SAFE_INTEGER","MIN_SAFE_INTEGER","iteration","converged","parameterError","iterations","findABParams","current","distSquared","rDist","gradCoeff","gradD","clip","nNegSamples","epochCallback","epochCompleted","shouldStop","isFinished","setTimeout","err","clipValue","isNil","insertSmaller","distancesAr","indexes","newPosition","findIndex","pop","DistanceMatrix","_data","_size","dataLength","_linearizeIJ","list","square","SparseMatrixService","matSize","minThreshold","getMinimalThreshold","workers","startIdx","endIdx","fullSize","acc","nNeighbours","knnIndexes","knnRes","thresholdWorkers","shuffledValues","maxSampleSize","sampleSise","testSetSizePerWorker","tPromises","sampleLength","getSampleDistances","cnt","mi","mj","some","DimReductionMethods","Reducer","AvailableReducers","distanceFnArgs","progressFunc","distanceFname","dmIndexFunc","_encodedDistance","bind","reducer","_encodedSparseMatrix","_parallelDistanceWorkers","time","getKNN","timeEnd","fitAsync","epoc","parallelDistanceWorkers","matrixProxy","condensedArray","linearFunc","linearIndex","iNum","jNum","idx1Handler","idx1","_receiver","Proxy","idx2","idx2Handler","distanceMatrixProxy","initDataDist","getSolution","emb","DimensionalityReducer","metric","measure","specOptions","bitArrayLength","_length","typeName","availableMethods","availableMetrics","obj","epochNum","epochsLength","self","columnData","onMessage","exports","tsne_1","defineProperty","enumerable","TSNE","opt","returnV","vValue","perplexity","getopt","field","defaultval","gaussRandom","u","randn","mu","std","ArrayBuffer","arr","randn2d","uses","xhere","L2","x1","x2","D","x1i","x2i","xtod","N","d2p","nf","hTarget","P","prow","betamin","betamax","beta","done","maxtries","pj","nHere","pOut","N2","initDataRaw","dists","initSolution","gains","ystep","cg","costGrad","cost","grad","ymean","gid","sid","gainid","newgain","newsid","debugGrad","yold","cg0","cg1","analytic","numerical","pmul","quArr","qsum","dsum","dhere","qu","NN","Q","gsum","premult","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","module","__webpack_modules__","__webpack_exports__","O","chunkIds","priority","notFulfilled","fulfilled","definition","o","chunkId","globalThis","Function","window","prop","scriptUrl","importScripts","location","document","currentScript","src","scripts","getElementsByTagName","replace","installedChunks","chunkLoadingGlobal","parentChunkLoadingFunction","moreModules","runtime","then"],"sourceRoot":""}
|