{"version":3,"sources":["jsdelivr-header.js","/npm/jsmind-simbiotico@0.5.6/js/jsmind.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;CCEE,SAAW,GACT,aAGA,IAAI,EAAW,SAEX,EAAc,QAEd,EAAa,mBAGb,EAAQ,WAAc,EACtB,EAA6B,oBAAZ,QAA2B,CAC5C,IAAK,EAAO,MAAO,EAAO,MAAO,EAAO,KAAM,EAAO,KAAM,GAC3D,QAGJ,GAAsB,oBAAX,QAA2B,OAAO,cACd,IAAhB,EAAG,GADlB,CAQA,IAAI,EAAK,EAAG,SAER,EAAK,SAAU,GAAO,OAAO,EAAG,cAAc,EAAM,EACpD,EAAK,SAAU,EAAG,GAAS,EAAE,gBAAmB,EAAE,WAAW,UAAY,EAAY,EAAE,YAAY,EAAG,eAAe,GAAO,EAE5H,EAAK,SAAU,EAAG,GACd,aAAa,aACb,EAAE,UAAY,GACd,EAAE,YAAY,IAEd,EAAE,UAAY,CAEtB,EAG0C,mBAA/B,OAAO,UAAU,aAA4B,OAAO,UAAU,WAAa,SAAU,GAAK,OAAO,KAAK,MAAM,EAAG,EAAE,UAAY,CAAG,GAE3I,IAAI,EAAkB,CAClB,UAAW,GACX,UAAU,EACV,MAAO,KACP,KAAM,OACN,cAAc,EAEd,KAAM,CACF,OAAQ,SACR,QAAS,IACT,QAAS,GACT,WAAY,EACZ,WAAY,OACZ,WAAW,EACX,gCAAgC,EAChC,cAAe,UAEnB,OAAQ,CACJ,OAAQ,GACR,OAAQ,GACR,OAAQ,IAEZ,qBAAsB,CAClB,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,GAE9B,SAAU,CACN,QAAQ,EACR,QAAS,CACT,EACA,QAAS,CACL,SAAU,CAAC,GAAI,MACf,WAAY,GACZ,SAAU,IACV,QAAS,GACT,OAAQ,GACR,KAAM,GACN,GAAI,GACJ,MAAO,GACP,KAAM,MAMd,EAAK,SAAU,GACf,EAAG,QAAU,KAEb,KAAK,QAAU,EACf,IAAI,EAAO,CAAC,EACZ,EAAG,KAAK,KAAK,MAAM,EAAM,GACzB,EAAG,KAAK,KAAK,MAAM,EAAM,GAEpB,EAAK,WAIV,KAAK,QAAU,EACf,KAAK,aAAc,EACnB,KAAK,KAAO,KACZ,KAAK,cAAgB,GACrB,KAAK,QAPD,EAAO,MAAM,qDAQrB,EAGA,EAAG,UAAY,CACX,MAAO,EAAG,OAAQ,EAAG,MAAO,EAAG,GAAI,SAAU,GACzC,OAAK,IAAgB,IAAT,GAAsB,IAAR,GAAqB,IAAR,EAG3B,OAAR,GAAwB,MAAR,GAAuB,MAAR,EACxB,SAAS,GAEM,SAAtB,EAAI,cACG,KAAK,KAEU,UAAtB,EAAI,cACG,KAAK,MAEU,WAAtB,EAAI,cACG,KAAK,YADhB,EAXW,CAcf,GAEJ,EAAG,WAAa,CAAE,KAAM,EAAG,OAAQ,EAAG,KAAM,EAAG,OAAQ,GACvD,EAAG,IAAM,CAAE,KAAM,KAAS,KAAM,KAAS,IAAK,KAAS,MAAO,MAE9D,EAAG,KAAO,SAAU,EAAK,EAAQ,EAAQ,EAAO,EAAS,EAAS,EAAY,GACrE,EACgB,iBAAV,QACc,IAAd,IAA6B,GAAY,GACpD,KAAK,GAAK,EACV,KAAK,MAAQ,EACb,KAAK,MAAQ,EACb,KAAK,KAAO,GAAS,CAAC,EACtB,KAAK,OAAS,EACd,KAAK,OAAS,EACd,KAAK,UAAY,EACjB,KAAK,WAAa,EAClB,KAAK,SAAW,GAChB,KAAK,MAAQ,CAAC,GAXmB,EAAO,MAAM,sBADlC,EAAO,MAAM,kBAa7B,EAEA,EAAG,KAAK,QAAU,SAAU,EAAO,GAE/B,IACI,EAAK,EAAM,MACX,EAAK,EAAM,MAaf,OAZI,GAAM,GAAK,GAAM,EACb,EAAK,GACK,GAAP,IAAmB,GAAP,EACf,GACU,GAAP,EACH,GACU,GAAP,GACF,EAED,CAIZ,EAEA,EAAG,KAAK,UAAY,SAAU,EAAO,GACjC,GAAM,GAAW,EAAM,CACnB,GAAI,EAAM,KAAO,EAAK,GAClB,OAAO,EAEX,GAAI,EAAM,OACN,OAAO,EAIX,IAFA,IAAI,EAAM,EAAM,GACZ,EAAI,GACA,EAAE,QAEN,IADA,EAAI,EAAE,QACA,KAAO,EACT,OAAO,CAGnB,CACA,OAAO,CACX,EAEA,EAAG,KAAK,QAAU,SAAU,GACxB,QAAS,GAAK,aAAa,EAAG,IAClC,EAEA,EAAG,KAAK,UAAY,CAChB,aAAc,WACV,IAAI,EAAK,KAAK,MAAM,KACpB,MAAO,CACH,EAAG,EAAG,MACN,EAAG,EAAG,MAEd,EACA,SAAU,WACN,IAAI,EAAK,KAAK,MAAM,KACpB,MAAO,CACH,EAAG,EAAG,MACN,EAAG,EAAG,OAEd,GAIJ,EAAG,KAAO,WACN,KAAK,KAAO,KACZ,KAAK,OAAS,KACd,KAAK,QAAU,KACf,KAAK,KAAO,KACZ,KAAK,SAAW,KAChB,KAAK,MAAQ,CAAC,CAClB,EAEA,EAAG,KAAK,UAAY,CAChB,SAAU,SAAU,GAChB,OAAI,KAAU,KAAK,MACR,KAAK,MAAM,IAElB,EAAO,KAAK,eAAiB,EAAS,sBAC/B,KAEf,EAEA,SAAU,SAAU,EAAQ,EAAO,GAC/B,OAAiB,MAAb,KAAK,MACL,KAAK,KAAO,IAAI,EAAG,KAAK,EAAQ,EAAG,EAAO,GAAM,GAChD,KAAK,UAAU,KAAK,MACb,KAAK,OAEZ,EAAO,MAAM,8BACN,KAEf,EAEA,SAAU,SAAU,EAAa,EAAQ,EAAO,EAAM,EAAW,EAAU,GACvE,IAAK,EAAG,KAAK,QAAQ,GAEjB,OADA,EAAO,MAAM,mBAAqB,EAAc,mBACzC,KAEX,IAAI,EAAa,IAAQ,EACrB,EAAO,IAAI,EAAG,KAAK,EAAQ,EAAY,EAAO,GAAM,EAAO,EAAa,EAAY,UAAW,GAWnG,OAVI,EAAY,SACZ,EAAK,UAAY,GAAa,EAAG,UAAU,OAE3C,KAAK,UAAU,IACf,EAAY,SAAS,KAAK,GAC1B,KAAK,SAAS,KAEd,EAAO,MAAM,qBAAwB,EAAK,GAAK,6BAC/C,EAAO,MAEJ,CACX,EAEA,mBAAoB,SAAU,EAAa,EAAQ,EAAO,EAAM,GAC5D,IAAK,EAAG,KAAK,QAAQ,GAEjB,OADA,EAAO,MAAM,mBAAqB,EAAc,mBACzC,KAEX,IAAI,EAAa,EAAY,MAAQ,GACrC,OAAO,KAAK,SAAS,EAAY,OAAQ,EAAQ,EAAO,EAAM,GAAW,EAAM,EACnF,EAEA,gBAAiB,SAAU,GACvB,IAAK,EAAG,KAAK,QAAQ,GAAO,CACxB,IAAI,EAAW,KAAK,SAAS,GAC7B,OAAK,EAIM,KAAK,gBAAgB,IAH5B,EAAO,MAAM,eAAiB,EAAO,uBAC9B,KAIf,CACA,GAAI,EAAK,OAAU,OAAO,KAC1B,IAAI,EAAM,EAAK,MAAQ,EACvB,OAAI,GAAO,EACA,EAAK,OAAO,SAAS,GAErB,IAEf,EAEA,kBAAmB,SAAU,EAAY,EAAQ,EAAO,EAAM,GAC1D,IAAK,EAAG,KAAK,QAAQ,GAEjB,OADA,EAAO,MAAM,kBAAoB,EAAa,mBACvC,KAEX,IAAI,EAAa,EAAW,MAAQ,GACpC,OAAO,KAAK,SAAS,EAAW,OAAQ,EAAQ,EAAO,EAAM,GAAW,EAAM,EAClF,EAEA,eAAgB,SAAU,GACtB,IAAK,EAAG,KAAK,QAAQ,GAAO,CACxB,IAAI,EAAW,KAAK,SAAS,GAC7B,OAAK,EAIM,KAAK,eAAe,IAH3B,EAAO,MAAM,eAAiB,EAAO,uBAC9B,KAIf,CACA,GAAI,EAAK,OAAU,OAAO,KAC1B,IAAI,EAAM,EAAK,MAEf,OADe,EAAK,OAAO,SACd,OAAS,EACX,EAAK,OAAO,SAAS,GAErB,IAEf,EAEA,UAAW,SAAU,EAAM,EAAW,EAAW,GAC7C,OAAK,EAAG,KAAK,QAAQ,IAIhB,IACD,EAAY,EAAK,OAAO,IAErB,KAAK,WAAW,EAAM,EAAW,EAAW,KAN/C,EAAO,MAAM,sBAAwB,EAAO,mBACrC,KAMf,EAEA,qBAAsB,SAAU,EAAM,QACT,IAAd,EACP,EAAY,EAAK,UAEjB,EAAK,UAAY,EAGrB,IADA,IAAI,EAAM,EAAK,SAAS,OACjB,KACH,KAAK,qBAAqB,EAAK,SAAS,GAAM,EAEtD,EAEA,oBAAqB,SAAU,EAAM,GACjC,GAAM,GAAU,EACZ,GAAgB,UAAZ,EACA,EAAK,OAAS,EACd,KAAK,SAAS,EAAK,aAChB,GAAgB,WAAZ,EACP,EAAK,MAAQ,EACb,KAAK,SAAS,EAAK,YAChB,CACH,IAAI,EAAiB,EAAY,KAAK,SAAS,GAAY,KACxC,MAAf,GAA6C,MAAtB,EAAY,QAAkB,EAAY,OAAO,IAAM,EAAK,OAAO,KAC1F,EAAK,MAAQ,EAAY,MAAQ,GACjC,KAAK,SAAS,EAAK,QAE3B,CAEJ,OAAO,CACX,EAEA,WAAY,SAAU,EAAM,EAAU,EAAU,GAC5C,GAAM,GAAU,EAAU,CACtB,IAAI,EAAc,KAAK,SAAS,GAChC,GAAI,EAAG,KAAK,UAAU,EAAM,GAExB,OADA,EAAO,MAAM,uCACN,KAEX,GAAI,EAAK,OAAO,IAAM,EAAU,CAI5B,IAFA,IAAI,EAAU,EAAK,OAAO,SACtB,EAAK,EAAQ,OACV,KACH,GAAI,EAAQ,GAAI,IAAM,EAAK,GAAI,CAC3B,EAAQ,OAAO,EAAI,GACnB,KACJ,CAEJ,EAAK,OAAS,EACd,EAAY,SAAS,KAAK,EAC9B,CAEI,EAAK,OAAO,OACR,GAAa,EAAG,UAAU,KAC1B,EAAK,UAAY,EAEjB,EAAK,UAAY,EAAG,UAAU,MAGlC,EAAK,UAAY,EAAK,OAAO,UAEjC,KAAK,oBAAoB,EAAM,GAC/B,KAAK,qBAAqB,EAC9B,CACA,OAAO,CACX,EAEA,YAAa,SAAU,GACnB,IAAK,EAAG,KAAK,QAAQ,GAEjB,OADA,EAAO,MAAM,sBAAwB,EAAO,oBACrC,EAEX,GAAI,EAAK,OAEL,OADA,EAAO,MAAM,mCACN,EAEU,MAAjB,KAAK,UAAoB,KAAK,SAAS,IAAM,EAAK,KAClD,KAAK,SAAW,MAKpB,IAFA,IAAI,EAAW,EAAK,SAChB,EAAK,EAAS,OACX,KACH,KAAK,YAAY,EAAS,IAG9B,EAAS,OAAS,EAIlB,IAFA,IAAI,EAAU,EAAK,OAAO,SACtB,EAAK,EAAQ,OACV,KACH,GAAI,EAAQ,GAAI,IAAM,EAAK,GAAI,CAC3B,EAAQ,OAAO,EAAI,GACnB,KACJ,CAKJ,IAAK,IAAI,YAFF,KAAK,MAAM,EAAK,IAET,SACH,EAAK,GAKhB,OAFA,EAAO,MAEA,CACX,EAEA,UAAW,SAAU,GACjB,OAAI,EAAK,MAAM,KAAK,OAChB,EAAO,KAAK,eAAkB,EAAK,GAAK,8BACjC,IAEP,KAAK,MAAM,EAAK,IAAM,GACf,EAEf,EAEA,SAAU,SAAU,GAChB,GAAI,aAAgB,EAAG,KAAM,CACzB,EAAK,SAAS,KAAK,EAAG,KAAK,SAC3B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,SAAS,OAAQ,IACtC,EAAK,SAAS,GAAG,MAAQ,EAAI,CAErC,CACJ,GAGJ,EAAG,OAAS,CACR,UAAW,CACP,QAAS,CACL,KAAQ,CACJ,KAAQ,EACR,OAAU,EACV,QAAW,GAEf,OAAU,YACV,KAAQ,CAAE,GAAM,OAAQ,MAAS,mBAErC,SAAU,SAAU,GAChB,IAAI,EAAK,EAAG,OAAO,UACf,EAAO,IAAI,EAAG,KAKlB,OAJA,EAAK,KAAO,EAAO,KAAK,KACxB,EAAK,OAAS,EAAO,KAAK,OAC1B,EAAK,QAAU,EAAO,KAAK,QAC3B,EAAG,OAAO,EAAM,EAAO,MAChB,CACX,EACA,SAAU,SAAU,GAChB,IAAI,EAAK,EAAG,OAAO,UACf,EAAO,CAAC,EAQZ,OAPA,EAAK,KAAO,CACR,KAAM,EAAK,KACX,OAAQ,EAAK,OACb,QAAS,EAAK,SAElB,EAAK,OAAS,YACd,EAAK,KAAO,EAAG,WAAW,EAAK,MACxB,CACX,EAEA,OAAQ,SAAU,EAAM,GACpB,IAAI,EAAK,EAAG,OAAO,UACf,EAAO,EAAG,cAAc,GAE5B,GADA,EAAK,SAAS,EAAU,GAAI,EAAU,MAAO,GACzC,aAAc,EAEd,IADA,IAAI,EAAW,EAAU,SAChB,EAAI,EAAG,EAAI,EAAS,OAAQ,IACjC,EAAG,iBAAiB,EAAM,EAAK,KAAM,EAAS,GAG1D,EAEA,cAAe,SAAU,GACrB,IAAI,EAAO,CAAC,EACZ,IAAK,IAAI,KAAK,EACD,MAAL,GAAkB,SAAL,GAAqB,YAAL,GAAwB,aAAL,GAAyB,YAAL,IAGxE,EAAK,GAAK,EAAU,IAExB,OAAO,CACX,EAEA,iBAAkB,SAAU,EAAM,EAAa,GAC3C,IAAI,EAAK,EAAG,OAAO,UACf,EAAO,EAAG,cAAc,GACxB,EAAI,KACJ,EAAY,SACZ,EAA2B,QAAvB,EAAU,UAAsB,EAAG,UAAU,KAAO,EAAG,UAAU,OAEzE,IAAI,EAAO,EAAK,SAAS,EAAa,EAAU,GAAI,EAAU,MAAO,EAAM,EAAG,EAAU,UACxF,GAAM,EAAoB,SAEtB,IADA,IAAI,EAAW,EAAU,SAChB,EAAI,EAAG,EAAI,EAAS,OAAQ,IACjC,EAAG,iBAAiB,EAAM,EAAM,EAAS,GAGrD,EAEA,WAAY,SAAU,GAClB,IAAI,EAAK,EAAG,OAAO,UACnB,GAAM,aAAgB,EAAG,KAAzB,CACA,IAAI,EAAI,CACJ,GAAI,EAAK,GACT,MAAO,EAAK,MACZ,SAAU,EAAK,UAKnB,GAHM,EAAK,QAAU,EAAK,OAAO,SAC7B,EAAE,UAAY,EAAK,WAAa,EAAG,UAAU,KAAO,OAAS,SAEhD,MAAb,EAAK,KAAc,CACnB,IAAI,EAAY,EAAK,KACrB,IAAK,IAAI,KAAK,EACV,EAAE,GAAK,EAAU,EAEzB,CACA,IAAI,EAAW,EAAK,SACpB,GAAI,EAAS,OAAS,EAAG,CACrB,EAAE,SAAW,GACb,IAAK,IAAI,EAAI,EAAG,EAAI,EAAS,OAAQ,IACjC,EAAE,SAAS,KAAK,EAAG,WAAW,EAAS,IAE/C,CACA,OAAO,CAtBmC,CAuB9C,GAGJ,WAAY,CACR,QAAS,CACL,KAAQ,CACJ,KAAQ,EACR,OAAU,EACV,QAAW,GAEf,OAAU,aACV,KAAQ,CACJ,CAAE,GAAM,OAAQ,MAAS,iBAAkB,QAAU,KAI7D,SAAU,SAAU,GAChB,IAAI,EAAK,EAAG,OAAO,WACf,EAAO,IAAI,EAAG,KAKlB,OAJA,EAAK,KAAO,EAAO,KAAK,KACxB,EAAK,OAAS,EAAO,KAAK,OAC1B,EAAK,QAAU,EAAO,KAAK,QAC3B,EAAG,OAAO,EAAM,EAAO,MAChB,CACX,EAEA,SAAU,SAAU,GAChB,IAAI,EAAK,EAAG,OAAO,WACf,EAAO,CAAC,EASZ,OARA,EAAK,KAAO,CACR,KAAM,EAAK,KACX,OAAQ,EAAK,OACb,QAAS,EAAK,SAElB,EAAK,OAAS,aACd,EAAK,KAAO,GACZ,EAAG,OAAO,EAAM,EAAK,MACd,CACX,EAEA,OAAQ,SAAU,EAAM,GACpB,IAAI,EAAK,EAAG,OAAO,WACf,EAAS,EAAW,MAAM,GAE9B,EAAO,UACP,IAAI,EAAY,EAAG,cAAc,EAAM,GACjC,EACF,EAAG,iBAAiB,EAAM,EAAW,GAErC,EAAO,MAAM,6BAErB,EAEA,cAAe,SAAU,EAAM,GAG3B,IAFA,IAAI,EAAK,EAAG,OAAO,WACf,EAAI,EAAW,OACZ,KACH,GAAI,WAAY,EAAW,IAAM,EAAW,GAAG,OAAQ,CACnD,IAAI,EAAY,EAAW,GACvB,EAAO,EAAG,cAAc,GACxB,EAAO,EAAK,SAAS,EAAU,GAAI,EAAU,MAAO,GAExD,OADA,EAAW,OAAO,EAAG,GACd,CACX,CAEJ,OAAO,IACX,EAEA,iBAAkB,SAAU,EAAM,EAAa,GAM3C,IALA,IAAI,EAAK,EAAG,OAAO,WACf,EAAI,EAAW,OACf,EAAY,KACZ,EAAO,KACP,EAAgB,EACb,KAEH,IADA,EAAY,EAAW,IACT,UAAY,EAAY,GAAI,CACtC,EAAO,EAAG,cAAc,GACxB,IAAI,EAAI,KACJ,EAAiB,EAAU,UACzB,IACF,EAAsB,QAAlB,EAA2B,EAAG,UAAU,KAAO,EAAG,UAAU,OAEpE,IAAI,EAAO,EAAK,SAAS,EAAa,EAAU,GAAI,EAAU,MAAO,EAAM,EAAG,EAAU,UACxF,EAAW,OAAO,EAAG,GACrB,IACA,IAAI,EAAoB,EAAG,iBAAiB,EAAM,EAAM,GACpD,EAAoB,IAEpB,EAAI,EAAW,OACf,GAAiB,EAEzB,CAEJ,OAAO,CACX,EAEA,cAAe,SAAU,GACrB,IAAI,EAAO,CAAC,EACZ,IAAK,IAAI,KAAK,EACD,MAAL,GAAkB,SAAL,GAAqB,YAAL,GAAwB,UAAL,GAAsB,aAAL,GAAyB,YAAL,IAGzF,EAAK,GAAK,EAAU,IAExB,OAAO,CACX,EAEA,OAAQ,SAAU,EAAM,GACX,EAAG,OAAO,WAChB,YAAY,EAAK,KAAM,EAC9B,EAEA,YAAa,SAAU,EAAM,GACzB,IAAI,EAAK,EAAG,OAAO,WACnB,GAAM,aAAgB,EAAG,KAAzB,CACA,IAAI,EAAI,CACJ,GAAI,EAAK,GACT,MAAO,EAAK,MACZ,SAAU,EAAK,UAWnB,GATM,EAAK,SACP,EAAE,SAAW,EAAK,OAAO,IAEzB,EAAK,SACL,EAAE,QAAS,GAET,EAAK,QAAU,EAAK,OAAO,SAC7B,EAAE,UAAY,EAAK,WAAa,EAAG,UAAU,KAAO,OAAS,SAEhD,MAAb,EAAK,KAAc,CACnB,IAAI,EAAY,EAAK,KACrB,IAAK,IAAI,KAAK,EACV,EAAE,GAAK,EAAU,EAEzB,CACA,EAAW,KAAK,GAEhB,IADA,IAAI,EAAK,EAAK,SAAS,OACd,EAAI,EAAG,EAAI,EAAI,IACpB,EAAG,YAAY,EAAK,SAAS,GAAI,EAxBK,CA0B9C,GAGJ,SAAU,CACN,QAAS,CACL,KAAQ,CACJ,KAAQ,EACR,OAAU,EACV,QAAW,GAEf,OAAU,WACV,KAAQ,wEAEZ,SAAU,SAAU,GAChB,IAAI,EAAK,EAAG,OAAO,SACf,EAAO,IAAI,EAAG,KAClB,EAAK,KAAO,EAAO,KAAK,KACxB,EAAK,OAAS,EAAO,KAAK,OAC1B,EAAK,QAAU,EAAO,KAAK,QAC3B,IAAI,EAAM,EAAO,KACb,EAAU,EAAG,WAAW,GACxB,EAAW,EAAG,WAAW,GAE7B,OADA,EAAG,WAAW,EAAM,KAAM,GACnB,CACX,EAEA,SAAU,SAAU,GAChB,IAAI,EAAK,EAAG,OAAO,SACf,EAAO,CAAC,EACZ,EAAK,KAAO,CACR,KAAM,EAAK,KACX,OAAQ,EAAK,OACb,QAAS,EAAK,SAElB,EAAK,OAAS,WACd,IAAI,EAAW,GAKf,OAJA,EAAS,KAAK,yBACd,EAAG,UAAU,EAAK,KAAM,GACxB,EAAS,KAAK,UACd,EAAK,KAAO,EAAS,KAAK,KACnB,CACX,EAEA,WAAY,SAAU,GAClB,IAAI,EAAU,KACV,OAAO,UAEP,GADa,IAAI,WACA,gBAAgB,EAAK,cAEtC,EAAU,IAAI,cAAc,qBACpB,OAAQ,EAChB,EAAQ,QAAQ,IAEpB,OAAO,CACX,EAEA,WAAY,SAAU,GAKlB,IAJA,IAAI,EAAQ,EAAQ,WAChB,EAAO,KAEP,EAAI,KACC,EAAI,EAAG,EAAI,EAAM,OAAQ,IAE9B,GAAkB,IADlB,EAAI,EAAM,IACJ,UAA8B,OAAb,EAAE,QAAkB,CACvC,EAAO,EACP,KACJ,CAEJ,GAAM,EAAM,CACR,IAAI,EAAK,EAAK,WACd,EAAO,KACP,IAAS,EAAI,EAAG,EAAI,EAAG,OAAQ,IAE3B,GAAkB,IADlB,EAAI,EAAG,IACD,UAA8B,QAAb,EAAE,QAAmB,CACxC,EAAO,EACP,KACJ,CAER,CACA,OAAO,CACX,EAEA,WAAY,SAAU,EAAM,EAAa,GACrC,IAAI,EAAK,EAAG,OAAO,SACf,EAAU,EAAS,aAAa,MAChC,EAAa,EAAS,aAAa,QAEvC,GAAkB,MAAd,EAGA,IAFA,IAAI,EAAiB,EAAS,WAC1B,EAAc,KACT,EAAI,EAAG,EAAI,EAAe,OAAQ,IAGvC,GAA4B,IAF5B,EAAc,EAAe,IAEb,UAAyC,gBAAxB,EAAY,QAA2B,CACpE,EAAa,EAAY,YACzB,KACJ,CAGR,IAAI,EAAY,EAAG,iBAAiB,GAChC,IAAiB,aAAc,IAAoC,QAAtB,EAAU,gBACpD,EAAU,SAEjB,IAAI,EAAgB,EAAS,aAAa,YACtC,EAAiB,KACf,IACF,EAAkC,QAAjB,EAA0B,EAAG,UAAU,KAAO,EAAG,UAAU,OAGhF,IAAI,EAAO,KAEP,EADE,EACK,EAAK,SAAS,EAAa,EAAS,EAAY,EAAW,EAAgB,GAE3E,EAAK,SAAS,EAAS,EAAY,GAE9C,IAAI,EAAW,EAAS,WACpB,EAAQ,KACZ,IAAS,EAAI,EAAG,EAAI,EAAS,OAAQ,IAEX,IADtB,EAAQ,EAAS,IACP,UAAkC,QAAjB,EAAM,SAC7B,EAAG,WAAW,EAAM,EAAM,EAGtC,EAEA,iBAAkB,SAAU,GAIxB,IAHA,IAAI,EAAW,EAAS,WACpB,EAAO,KACP,EAAY,CAAC,EACR,EAAI,EAAG,EAAI,EAAS,OAAQ,IAEZ,IADrB,EAAO,EAAS,IACP,UAAkC,cAAjB,EAAK,UAC3B,EAAU,EAAK,aAAa,SAAW,EAAK,aAAa,UAGjE,OAAO,CACX,EAEA,UAAW,SAAU,EAAM,GACvB,IAAI,EAAK,EAAG,OAAO,SACf,EAAM,KACJ,EAAK,QAAU,EAAK,OAAO,SAC7B,EAAM,EAAK,YAAc,EAAG,UAAU,KAAO,OAAS,SAE1D,EAAS,KAAK,SACd,EAAS,KAAK,OAAU,EAAK,GAAK,KAC5B,GACF,EAAS,KAAK,aAAgB,EAAM,KAExC,EAAS,KAAK,SAAY,EAAK,MAAQ,MAGvC,EAAS,KAAK,qCAA0C,EAAK,SAAW,OAGxE,IAAI,EAAY,EAAK,KACrB,GAAiB,MAAb,EACA,IAAK,IAAI,KAAK,EACV,EAAS,KAAK,oBAAuB,EAAI,YAAgB,EAAU,GAAK,OAMhF,IADA,IAAI,EAAW,EAAK,SACX,EAAI,EAAG,EAAI,EAAS,OAAQ,IACjC,EAAG,UAAU,EAAS,GAAI,GAG9B,EAAS,KAAK,UAClB,IAMR,EAAG,KAAO,CACN,QAAS,SAAU,GACf,QAAS,GAAQ,aAAgB,EAAG,IACxC,EACA,KAAM,CACF,QAAS,SAAU,EAAK,EAAO,EAAQ,EAAU,GACrC,EAAG,KAAK,KAAhB,IACI,EAAI,KACJ,EAAY,GAChB,IAAK,IAAI,KAAK,EACV,EAAU,KAAK,mBAAmB,GAAK,IAAM,mBAAmB,EAAM,KAEtE,EAAU,OAAS,IACnB,EAAI,EAAU,KAAK,MAEvB,IAAI,EAAM,IAAI,eACT,IACL,EAAI,mBAAqB,WACrB,GAAsB,GAAlB,EAAI,WACJ,GAAkB,KAAd,EAAI,QAA+B,GAAd,EAAI,QACzB,GAAwB,mBAAb,EAAyB,CAChC,IAAI,EAAO,EAAG,KAAK,KAAK,YAAY,EAAI,cAEpC,EADQ,MAAR,EACS,EAEA,EAAI,aAErB,MAE6B,mBAAlB,EACP,EAAc,GAEd,EAAO,MAAM,sBAAuB,EAIpD,EACA,EAAS,GAAU,MACnB,EAAI,KAAK,EAAQ,GAAK,GACtB,EAAI,iBAAiB,oBAAqB,KAC5B,QAAV,GACA,EAAI,iBAAiB,eAAgB,mDACrC,EAAI,KAAK,IAET,EAAI,OAEZ,EACA,IAAK,SAAU,EAAK,GAChB,OAAO,EAAG,KAAK,KAAK,QAAQ,EAAK,CAAC,EAAG,MAAO,EAChD,EACA,KAAM,SAAU,EAAK,EAAO,GACxB,OAAO,EAAG,KAAK,KAAK,QAAQ,EAAK,EAAO,OAAQ,EACpD,GAGJ,IAAK,CAED,UAAW,SAAU,EAAG,EAAG,GACjB,EAAE,iBACJ,EAAE,iBAAiB,EAAG,GAAG,GAEzB,EAAE,YAAY,KAAO,EAAG,EAEhC,GAGJ,KAAM,CACF,KAAM,SAAU,EAAW,GACvB,IAAI,EAAS,IAAI,WACjB,EAAO,OAAS,WACe,mBAAhB,GACP,EAAY,KAAK,OAAQ,EAAU,KAE3C,EACA,EAAO,WAAW,EACtB,EAEA,KAAM,SAAU,EAAW,EAAM,GAC7B,IAAI,EACJ,GAAuB,mBAAZ,EAAG,KACV,EAAO,IAAI,KAAK,CAAC,GAAY,CAAE,KAAM,QAClC,CACH,IACI,EAAK,IADS,EAAG,aAAe,EAAG,gBAAkB,EAAG,mBAAqB,EAAG,eAEpF,EAAG,OAAO,GACV,EAAO,EAAG,QAAQ,EACtB,CACA,GAAI,UAAU,WACV,UAAU,WAAW,EAAM,OACxB,CACH,IACI,GADM,EAAG,KAAO,EAAG,WACL,gBAAgB,GAC9B,EAAS,EAAG,KAChB,GAAI,aAAc,EAAQ,CACtB,EAAO,MAAM,WAAa,SAC1B,EAAO,KAAO,EACd,EAAO,SAAW,EAClB,EAAG,KAAK,YAAY,GACpB,IAAI,EAAM,EAAG,YAAY,eACzB,EAAI,UAAU,SAAS,GAAM,GAC7B,EAAO,cAAc,GACrB,EAAG,KAAK,YAAY,EACxB,MACI,SAAS,KAAO,CAExB,CACJ,GAGJ,KAAM,CACF,YAAa,SAAU,GACnB,OAAO,KAAK,UAAU,EAC1B,EACA,YAAa,SAAU,GACnB,OAAO,KAAK,MAAM,EACtB,EACA,MAAO,SAAU,EAAG,GAChB,IAAK,IAAI,KAAK,EACN,KAAK,EACe,iBAAT,EAAE,IAC6C,mBAAtD,OAAO,UAAU,SAAS,KAAK,EAAE,IAAI,eACpC,EAAE,GAAG,OAGN,EAAE,GAAK,EAAE,GAFT,EAAG,KAAK,KAAK,MAAM,EAAE,GAAI,EAAE,IAK/B,EAAE,GAAK,EAAE,GAGjB,OAAO,CACX,GAGJ,KAAM,CACF,MAAO,WACH,QAAQ,IAAI,MAAO,UAAU,SAAS,IAAM,KAAK,SAAS,SAAS,IAAI,UAAU,IAAI,UAAU,EAAG,GACtG,GAGJ,KAAM,CACF,SAAU,SAAU,GAChB,OAAK,GACiC,GAA/B,EAAE,QAAQ,MAAO,IAAI,MAChC,IAIR,EAAG,UAAY,CACX,KAAM,WACF,IAAI,KAAK,YAAT,CACA,KAAK,aAAc,EAEnB,IAAI,EAAO,KAAK,QAEZ,EAAc,CACd,KAAM,EAAK,KACX,OAAQ,EAAK,OAAO,OACpB,OAAQ,EAAK,OAAO,OACpB,OAAQ,EAAK,OAAO,QAEpB,EAAY,CACZ,UAAW,EAAK,UAChB,aAAc,EAAK,aACnB,OAAQ,EAAK,KAAK,OAClB,QAAS,EAAK,KAAK,QACnB,QAAS,EAAK,KAAK,QACnB,WAAY,EAAK,KAAK,WACtB,WAAY,EAAK,KAAK,WACtB,UAAW,EAAK,KAAK,UACrB,+BAAgC,EAAK,KAAK,+BAC1C,cAAe,EAAK,KAAK,eAG7B,KAAK,KAAO,IAAI,EAAG,cAAc,MACjC,KAAK,OAAS,IAAI,EAAG,gBAAgB,KAAM,GAC3C,KAAK,KAAO,IAAI,EAAG,cAAc,KAAM,GACvC,KAAK,SAAW,IAAI,EAAG,kBAAkB,KAAM,EAAK,UAEpD,KAAK,KAAK,OACV,KAAK,OAAO,OACZ,KAAK,KAAK,OACV,KAAK,SAAS,OAEd,KAAK,cAEL,EAAG,aAAa,KApCgB,CAqCpC,EAEA,YAAa,WACT,KAAK,QAAQ,UAAW,CAC5B,EAEA,aAAc,WACV,KAAK,QAAQ,UAAW,CAC5B,EAIA,oBAAqB,SAAU,GAC3B,KAAK,QAAQ,qBAAqB,UAAY,EAAe,YAAa,CAC9E,EAIA,qBAAsB,SAAU,GAC5B,KAAK,QAAQ,qBAAqB,UAAY,EAAe,YAAa,CAC9E,EAEA,aAAc,WACV,OAAO,KAAK,QAAQ,QACxB,EAEA,UAAW,SAAU,GACjB,IAAI,EAAY,KAAK,QAAQ,MAC7B,KAAK,QAAQ,MAAW,GAAiB,KACrC,GAAa,KAAK,QAAQ,QAC1B,KAAK,KAAK,cACV,KAAK,KAAK,qBAElB,EACA,YAAa,WACT,KAAK,KAAK,UAAU,KAAM,YAAa,KAAK,kBAC5C,KAAK,KAAK,UAAU,KAAM,QAAS,KAAK,cACxC,KAAK,KAAK,UAAU,KAAM,WAAY,KAAK,iBAC3C,KAAK,KAAK,UAAU,KAAM,aAAc,KAAK,kBACjD,EAEA,iBAAkB,SAAU,GACxB,GAAK,KAAK,QAAQ,qBAA8C,wBAAhE,CAGA,IAAI,EAAU,EAAE,QAAU,MAAM,WAC5B,EAAS,KAAK,KAAK,kBAAkB,GACnC,EACmC,UAAjC,EAAQ,QAAQ,eAChB,KAAK,YAAY,GAGrB,KAAK,cART,CAUJ,EAEA,aAAc,SAAU,GACpB,GAAK,KAAK,QAAQ,qBAA0C,oBAA5D,CAGA,IAAI,EAAU,EAAE,QAAU,MAAM,WAEhC,GADiB,KAAK,KAAK,YAAY,GACvB,CACZ,IAAI,EAAS,KAAK,KAAK,kBAAkB,GACnC,GACF,KAAK,YAAY,EAEzB,CARA,CASJ,EAEA,gBAAiB,SAAU,GACvB,GAAK,KAAK,QAAQ,qBAA6C,wBAG3D,KAAK,eAAgB,CACrB,IAAI,EAAU,EAAE,QAAU,MAAM,WAC5B,EAAS,KAAK,KAAK,kBAAkB,GACnC,GACF,KAAK,WAAW,EAExB,CACJ,EAGA,kBAAmB,SAAU,GAEpB,KAAK,QAAQ,qBAA+C,0BAAM,OAAO,MAAM,UAIpF,EAAM,iBAEF,EAAM,OAAS,EACf,KAAK,KAAK,SAEV,KAAK,KAAK,UAElB,EAEA,WAAY,SAAU,GAClB,IAAK,EAAG,KAAK,QAAQ,GAAO,CACxB,IAAI,EAAW,KAAK,SAAS,GAC7B,OAAK,EAIM,KAAK,WAAW,IAHvB,EAAO,MAAM,eAAiB,EAAO,wBAC9B,EAIf,CACI,KAAK,eACL,KAAK,KAAK,gBAAgB,GAE1B,EAAO,MAAM,uCAGrB,EAEA,SAAU,WACN,KAAK,KAAK,eACd,EAEA,YAAa,SAAU,GACnB,IAAK,EAAG,KAAK,QAAQ,GAAO,CACxB,IAAI,EAAW,KAAK,SAAS,GAC7B,OAAK,EAIM,KAAK,YAAY,QAHxB,EAAO,MAAM,eAAiB,EAAO,sBAK7C,CACI,EAAK,SACT,KAAK,KAAK,cAAc,GACxB,KAAK,OAAO,YAAY,GACxB,KAAK,KAAK,WACV,KAAK,KAAK,iBAAiB,GAC/B,EAEA,YAAa,SAAU,GACnB,IAAK,EAAG,KAAK,QAAQ,GAAO,CACxB,IAAI,EAAW,KAAK,SAAS,GAC7B,OAAK,EAIM,KAAK,YAAY,QAHxB,EAAO,MAAM,eAAiB,EAAO,sBAK7C,CACI,EAAK,SACT,KAAK,KAAK,cAAc,GACxB,KAAK,OAAO,YAAY,GACxB,KAAK,KAAK,WACV,KAAK,KAAK,iBAAiB,GAC/B,EAEA,cAAe,SAAU,GACrB,IAAK,EAAG,KAAK,QAAQ,GAAO,CACxB,IAAI,EAAW,KAAK,SAAS,GAC7B,OAAK,EAIM,KAAK,cAAc,QAH1B,EAAO,MAAM,eAAiB,EAAO,sBAK7C,CACI,EAAK,SACT,KAAK,KAAK,cAAc,GACxB,KAAK,OAAO,cAAc,GAC1B,KAAK,KAAK,WACV,KAAK,KAAK,iBAAiB,GAC/B,EAEA,WAAY,WACR,KAAK,OAAO,aACZ,KAAK,KAAK,UACd,EAEA,aAAc,WACV,KAAK,OAAO,eACZ,KAAK,KAAK,UACd,EAEA,gBAAiB,SAAU,GACvB,KAAK,OAAO,gBAAgB,GAC5B,KAAK,KAAK,UACd,EAEA,OAAQ,WACJ,KAAK,KAAK,QACV,KAAK,OAAO,QACZ,KAAK,KAAK,OACd,EAEA,MAAO,SAAU,GACb,IAAI,EAAI,GAAQ,EAAG,OAAO,WAAW,QAErC,KAAK,KAAO,KAAK,KAAK,KAAK,GACtB,KAAK,MAIN,EAAO,MAAM,gBAGjB,KAAK,KAAK,OACV,EAAO,MAAM,gBAEb,KAAK,OAAO,SACZ,EAAO,MAAM,oBAEb,KAAK,KAAK,MAAK,GACf,EAAO,MAAM,gBAEb,KAAK,oBAAoB,EAAG,WAAW,KAAM,CAAE,KAAM,CAAC,MAflD,EAAO,MAAM,kBAgBrB,EAEA,KAAM,SAAU,GACZ,KAAK,SACL,KAAK,MAAM,EACf,EAEA,SAAU,WACN,MAAO,CACH,KAAM,KAAK,KAAK,KAChB,OAAQ,KAAK,KAAK,OAClB,QAAS,KAAK,KAAK,QAE3B,EAEA,SAAU,SAAU,GAChB,IAAI,EAAK,GAAe,YACxB,OAAO,KAAK,KAAK,SAAS,EAC9B,EAEA,SAAU,WACN,OAAO,KAAK,KAAK,IACrB,EAEA,SAAU,SAAU,GAChB,OAAI,EAAG,KAAK,QAAQ,GACT,EAEJ,KAAK,KAAK,SAAS,EAC9B,EAEA,SAAU,SAAU,EAAa,EAAQ,EAAO,EAAM,GAClD,GAAI,KAAK,eAAgB,CACrB,IAAI,EAAkB,KAAK,SAAS,GAChC,EAAM,EAAG,UAAU,GAAG,QACd,IAAR,IACA,EAAM,KAAK,OAAO,+BAA+B,IAErD,IAAI,EAAO,KAAK,KAAK,SAAS,EAAiB,EAAQ,EAAO,EAAM,GASpE,OARM,IACF,KAAK,KAAK,SAAS,GACnB,KAAK,OAAO,SACZ,KAAK,KAAK,MAAK,GACf,KAAK,KAAK,wBAAwB,GAClC,KAAK,YAAY,GACjB,KAAK,oBAAoB,EAAG,WAAW,KAAM,CAAE,IAAK,WAAY,KAAM,CAAC,EAAgB,GAAI,EAAQ,EAAO,EAAM,GAAM,KAAM,KAEzH,CACX,CAEI,OADA,EAAO,MAAM,uCACN,IAEf,EAEA,mBAAoB,SAAU,EAAa,EAAQ,EAAO,EAAM,GAC5D,GAAI,KAAK,eAAgB,CACrB,IAAI,EAAkB,KAAK,SAAS,GAChC,EAAM,EAAG,UAAU,GAAG,QACd,IAAR,IACA,EAAM,KAAK,OAAO,+BAA+B,EAAgB,SAErE,IAAI,EAAO,KAAK,KAAK,mBAAmB,EAAiB,EAAQ,EAAO,EAAM,GAO9E,OANM,IACF,KAAK,KAAK,SAAS,GACnB,KAAK,OAAO,SACZ,KAAK,KAAK,MAAK,GACf,KAAK,oBAAoB,EAAG,WAAW,KAAM,CAAE,IAAK,qBAAsB,KAAM,CAAC,EAAgB,GAAI,EAAQ,EAAO,EAAM,GAAM,KAAM,KAEnI,CACX,CAEI,OADA,EAAO,MAAM,uCACN,IAEf,EAEA,kBAAmB,SAAU,EAAY,EAAQ,EAAO,EAAM,GAC1D,GAAI,KAAK,eAAgB,CACrB,IAAI,EAAiB,KAAK,SAAS,GAC/B,EAAM,EAAG,UAAU,GAAG,QACd,IAAR,IACA,EAAM,KAAK,OAAO,+BAA+B,EAAe,SAEpE,IAAI,EAAO,KAAK,KAAK,kBAAkB,EAAgB,EAAQ,EAAO,EAAM,GAO5E,OANM,IACF,KAAK,KAAK,SAAS,GACnB,KAAK,OAAO,SACZ,KAAK,KAAK,MAAK,GACf,KAAK,oBAAoB,EAAG,WAAW,KAAM,CAAE,IAAK,oBAAqB,KAAM,CAAC,EAAe,GAAI,EAAQ,EAAO,EAAM,GAAM,KAAM,KAEjI,CACX,CAEI,OADA,EAAO,MAAM,uCACN,IAEf,EAEA,YAAa,SAAU,GACnB,IAAK,EAAG,KAAK,QAAQ,GAAO,CACxB,IAAI,EAAW,KAAK,SAAS,GAC7B,OAAK,EAIM,KAAK,YAAY,IAHxB,EAAO,MAAM,eAAiB,EAAO,wBAC9B,EAIf,CACA,GAAI,KAAK,eAAgB,CACrB,GAAI,EAAK,OAEL,OADA,EAAO,MAAM,mCACN,EAEX,IAAI,EAAS,EAAK,GACd,EAAW,EAAK,OAAO,GACvB,EAAc,KAAK,SAAS,GAQhC,OAPA,KAAK,KAAK,cAAc,GACxB,KAAK,KAAK,YAAY,GACtB,KAAK,KAAK,YAAY,GACtB,KAAK,OAAO,SACZ,KAAK,KAAK,MAAK,GACf,KAAK,KAAK,iBAAiB,GAC3B,KAAK,oBAAoB,EAAG,WAAW,KAAM,CAAE,IAAK,cAAe,KAAM,CAAC,GAAS,KAAM,KAClF,CACX,CAEI,OADA,EAAO,MAAM,wCACN,CAEf,EAEA,YAAa,SAAU,EAAQ,GAC3B,GAAI,KAAK,eACL,GAAI,EAAG,KAAK,KAAK,SAAS,GACtB,EAAO,KAAK,oCADhB,CAIA,IAAI,EAAO,KAAK,SAAS,GACzB,GAAM,EAAM,CACR,GAAI,EAAK,QAAU,EAGf,OAFA,EAAO,KAAK,wBACZ,KAAK,KAAK,YAAY,GAG1B,EAAK,MAAQ,EACb,KAAK,KAAK,YAAY,GACtB,KAAK,OAAO,SACZ,KAAK,KAAK,MAAK,GACf,KAAK,oBAAoB,EAAG,WAAW,KAAM,CAAE,IAAK,cAAe,KAAM,CAAC,EAAQ,GAAQ,KAAM,GACpG,CAbA,MAeA,EAAO,MAAM,sCAGrB,EAEA,UAAW,SAAU,EAAQ,EAAU,EAAU,GAC7C,GAAI,KAAK,eAAT,CACI,IAAI,EAAO,KAAK,SAAS,GACrB,EAAe,KAAK,KAAK,UAAU,EAAM,EAAU,EAAU,GAC3D,IACF,KAAK,KAAK,YAAY,GACtB,KAAK,OAAO,SACZ,KAAK,KAAK,MAAK,GACf,KAAK,oBAAoB,EAAG,WAAW,KAAM,CAAE,IAAK,YAAa,KAAM,CAAC,EAAQ,EAAU,EAAU,GAAY,KAAM,IAK9H,MAFI,EAAO,MAAM,sCAGrB,EAEA,YAAa,SAAU,GACnB,IAAK,EAAG,KAAK,QAAQ,GAAO,CACxB,IAAI,EAAW,KAAK,SAAS,GAC7B,OAAK,EAIM,KAAK,YAAY,QAHxB,EAAO,MAAM,eAAiB,EAAO,sBAK7C,CACK,KAAK,OAAO,WAAW,KAG5B,KAAK,KAAK,SAAW,EACrB,KAAK,KAAK,YAAY,GACtB,KAAK,oBAAoB,EAAG,WAAW,OAAQ,CAAE,IAAK,cAAe,KAAM,GAAI,KAAM,EAAK,KAC9F,EAEA,kBAAmB,WACf,OAAM,KAAK,KACA,KAAK,KAAK,SAEV,IAEf,EAEA,aAAc,WACJ,KAAK,OACP,KAAK,KAAK,SAAW,KACrB,KAAK,KAAK,eAElB,EAEA,gBAAiB,SAAU,GACvB,OAAO,KAAK,OAAO,WAAW,EAClC,EAEA,iBAAkB,SAAU,GACxB,IAAK,EAAG,KAAK,QAAQ,GAAO,CACxB,IAAI,EAAW,KAAK,SAAS,GAC7B,OAAK,EAIM,KAAK,iBAAiB,QAH7B,EAAO,MAAM,eAAiB,EAAO,sBAK7C,CACA,GAAI,EAAK,OAAU,OAAO,KAC1B,IAAI,EAAI,KACR,GAAI,EAAK,OAAO,OAIZ,IAHA,IAAI,EAAI,EAAK,OAAO,SAChB,EAAO,KACP,EAAK,KACA,EAAI,EAAG,EAAI,EAAE,OAAQ,IAC1B,EAAK,EAAE,GACH,EAAK,YAAc,EAAG,YAClB,EAAK,KAAO,EAAG,KACf,EAAI,GAER,EAAO,QAIf,EAAI,KAAK,KAAK,gBAAgB,GAElC,OAAO,CACX,EAEA,gBAAiB,SAAU,GACvB,IAAK,EAAG,KAAK,QAAQ,GAAO,CACxB,IAAI,EAAW,KAAK,SAAS,GAC7B,OAAK,EAIM,KAAK,gBAAgB,QAH5B,EAAO,MAAM,eAAiB,EAAO,sBAK7C,CACA,GAAI,EAAK,OAAU,OAAO,KAC1B,IAAI,EAAI,KACR,GAAI,EAAK,OAAO,QAIZ,IAHA,IAAI,EAAI,EAAK,OAAO,SAChB,GAAU,EACV,EAAK,KACA,EAAI,EAAG,EAAI,EAAE,OAAQ,IAE1B,GADA,EAAK,EAAE,GACH,EAAK,YAAc,EAAG,UAAW,CACjC,GAAI,EAAS,CACT,EAAI,EACJ,KACJ,CACI,EAAK,KAAO,EAAG,KACf,GAAU,EAElB,OAGJ,EAAI,KAAK,KAAK,eAAe,GAEjC,OAAO,CACX,EAEA,eAAgB,SAAU,EAAQ,EAAS,GACvC,IAAI,KAAK,eAaL,OADA,EAAO,MAAM,uCACN,KAZP,IAAI,EAAO,KAAK,KAAK,SAAS,GACxB,IACI,IACF,EAAK,KAAK,oBAAsB,GAE9B,IACF,EAAK,KAAK,oBAAsB,GAEpC,KAAK,KAAK,wBAAwB,GAM9C,EAEA,oBAAqB,SAAU,EAAQ,EAAM,EAAQ,GACjD,IAAI,KAAK,eAmBL,OADA,EAAO,MAAM,uCACN,KAlBP,IAAI,EAAO,KAAK,KAAK,SAAS,GACxB,IACI,IACF,EAAK,KAAK,aAAe,GAEvB,IACF,EAAK,KAAK,eAAiB,GAEzB,IACF,EAAK,KAAK,cAAgB,GAE9B,KAAK,KAAK,wBAAwB,GAClC,KAAK,KAAK,YAAY,GACtB,KAAK,OAAO,SACZ,KAAK,KAAK,MAAK,GAM3B,EAEA,0BAA2B,SAAU,EAAQ,EAAO,EAAO,EAAQ,GAC/D,IAAI,KAAK,eAsBL,OADA,EAAO,MAAM,uCACN,KArBP,IAAI,EAAO,KAAK,KAAK,SAAS,GACxB,IACI,IACF,EAAK,KAAK,oBAAsB,GAE9B,IACF,EAAK,KAAY,MAAI,GAEnB,IACF,EAAK,KAAa,OAAI,GAEpB,IACF,EAAK,KAAK,uBAAyB,GAEvC,KAAK,KAAK,wBAAwB,GAClC,KAAK,KAAK,YAAY,GACtB,KAAK,OAAO,SACZ,KAAK,KAAK,MAAK,GAM3B,EAEA,6BAA8B,SAAU,EAAQ,GAC5C,IAAI,KAAK,eAeL,OADA,EAAO,MAAM,uCACN,KAdP,IAAI,EAAO,KAAK,KAAK,SAAS,GAC9B,GAAM,EAAM,CACR,IAAK,EAAK,KAAK,oBAEX,OADA,EAAO,MAAM,sEACN,KAEX,EAAK,KAAK,uBAAyB,EACnC,KAAK,KAAK,wBAAwB,GAClC,KAAK,KAAK,YAAY,GACtB,KAAK,OAAO,SACZ,KAAK,KAAK,MAAK,EACnB,CAKR,EAEA,OAAQ,WACJ,KAAK,KAAK,QACd,EAGA,mBAAoB,SAAU,GACF,mBAAb,GACP,KAAK,cAAc,KAAK,EAEhC,EAEA,qBAAsB,WAClB,KAAK,cAAgB,EACzB,EAEA,oBAAqB,SAAU,EAAM,GACjC,IAAI,EAAI,KACR,EAAG,YAAW,WACV,EAAE,qBAAqB,EAAM,EACjC,GAAG,EACP,EAEA,qBAAsB,SAAU,EAAM,GAElC,IADA,IAAI,EAAI,KAAK,cAAc,OAClB,EAAI,EAAG,EAAI,EAAG,IACnB,KAAK,cAAc,GAAG,EAAM,EAEpC,GAMJ,EAAG,cAAgB,SAAU,GACzB,KAAK,GAAK,CACd,EAEA,EAAG,cAAc,UAAY,CACzB,KAAM,WACF,EAAO,MAAM,YACjB,EAEA,MAAO,WACH,EAAO,MAAM,aACjB,EAEA,KAAM,SAAU,GACZ,IAAI,EAAK,KACL,EAAO,KAoBX,MATU,eARF,EAFiB,iBAAd,EACD,EAAU,OACP,EAAU,OAEV,YAGJ,YAIL,EAAO,EAAG,OAAO,WAAW,SAAS,GACxB,aAAN,EACP,EAAO,EAAG,OAAO,UAAU,SAAS,GACvB,YAAN,EACP,EAAO,EAAG,OAAO,SAAS,SAAS,GAEnC,EAAO,KAAK,sBAET,CACX,EAEA,SAAU,SAAU,GAChB,IAAI,EAAO,KAUX,MATmB,cAAf,EACA,EAAO,EAAG,OAAO,WAAW,SAAS,KAAK,GAAG,MACvB,aAAf,EACP,EAAO,EAAG,OAAO,UAAU,SAAS,KAAK,GAAG,MACtB,YAAf,EACP,EAAO,EAAG,OAAO,SAAS,SAAS,KAAK,GAAG,MAE3C,EAAO,MAAM,eAAiB,EAAc,WAEzC,CACX,GAKJ,EAAG,gBAAkB,SAAU,EAAI,GAC/B,KAAK,KAAO,EACZ,KAAK,GAAK,EACV,KAAK,OAA4B,QAAlB,KAAK,KAAK,KACzB,KAAK,OAAS,KAEd,KAAK,aAAc,CACvB,EAEA,EAAG,gBAAgB,UAAY,CAC3B,KAAM,WACF,EAAO,MAAM,cACjB,EAEA,MAAO,WACH,EAAO,MAAM,gBACb,KAAK,OAAS,CAAE,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EACzC,EAEA,+BAAgC,SAAU,GACtC,GAAI,KAAK,OACL,OAAO,EAAG,UAAU,MAKxB,IAHA,IAAI,EAAW,EAAK,UAAY,GAC5B,EAAe,EAAS,OACxB,EAAI,EACC,EAAI,EAAG,EAAI,EAAc,IAAW,EAAS,GAAG,YAAc,EAAG,UAAU,KAAQ,IAAc,IAC1G,OAAQ,EAAe,GAAK,EAAI,EAAK,EAAG,UAAU,KAAO,EAAG,UAAU,KAC1E,EAEA,OAAQ,WACJ,EAAO,MAAM,iBACb,KAAK,mBACL,KAAK,eACT,EAEA,iBAAkB,WACd,KAAK,wBACT,EAEA,uBAAwB,WACpB,IAAI,EAAO,KAAK,GAAG,KAAK,KAEpB,EAAc,KACd,WAAY,EAAK,MACjB,EAAc,EAAK,MAAM,QAEzB,EAAc,CAAC,EACf,EAAK,MAAM,OAAS,GAExB,IAAI,EAAW,EAAK,SAChB,EAAiB,EAAS,OAG9B,GAFA,EAAY,UAAY,EAAG,UAAU,OACrC,EAAY,WAAa,EACrB,KAAK,OAEL,IADA,IAAI,EAAI,EACD,KACH,KAAK,uBAAuB,EAAS,GAAI,EAAG,UAAU,MAAO,OAGjE,CAAI,EAAI,EAER,IAFA,IACI,EAAU,KACP,MACH,EAAU,EAAS,IACP,WAAa,EAAG,UAAU,KAClC,KAAK,uBAAuB,EAAS,EAAG,UAAU,KAAM,GAExD,KAAK,uBAAuB,EAAS,EAAG,UAAU,MAAO,EAP3C,CAsB9B,EAEA,uBAAwB,SAAU,EAAM,EAAW,GAC/C,IAAI,EAAc,KACd,WAAY,EAAK,MACjB,EAAc,EAAK,MAAM,QAEzB,EAAc,CAAC,EACf,EAAK,MAAM,OAAS,GAExB,IAAI,EAAW,EAAK,SAChB,EAAiB,EAAS,OAE9B,EAAY,UAAY,EACxB,EAAY,WAAa,EAEzB,IADA,IAAI,EAAI,EACD,KACH,KAAK,uBAAuB,EAAS,GAAI,EAAW,EAE5D,EAEA,cAAe,WACX,IAAI,EAAO,KAAK,GAAG,KAAK,KACpB,EAAc,EAAK,MAAM,OAC7B,EAAY,SAAW,EACvB,EAAY,SAAW,EACvB,EAAY,aAAe,EAM3B,IALA,IAAI,EAAW,EAAK,SAChB,EAAI,EAAS,OACb,EAAa,GACb,EAAc,GACd,EAAU,KACP,MACH,EAAU,EAAS,IACP,MAAM,OAAO,WAAa,EAAG,UAAU,MAC/C,EAAY,QAAQ,GAEpB,EAAW,QAAQ,GAG3B,EAAY,WAAa,EACzB,EAAY,YAAc,EAC1B,EAAY,kBAAoB,KAAK,wBAAwB,GAC7D,EAAY,mBAAqB,KAAK,wBAAwB,GAC9D,KAAK,OAAO,EAAI,EAAK,MAAM,KAAK,MAAQ,EACxC,KAAK,OAAO,EAAI,EAAI,KAAK,OAAO,EAEhC,KAAK,OAAO,EAAI,EAChB,KAAK,OAAO,EAAI,KAAK,IAAI,EAAY,kBAAmB,EAAY,mBACxE,EAGA,wBAAyB,SAAU,GAS/B,IARA,IAAI,EAAe,EACf,EAAc,EAAM,OACpB,EAAI,EACJ,EAAO,KACP,EAAoB,EACpB,EAAc,KACd,EAAS,EACT,EAAK,KACF,KAEH,GADA,EAAO,EAAM,IACM,MAAM,OACf,MAAN,IACA,EAAK,EAAK,OAAO,OAGrB,EAAoB,KAAK,wBAAwB,EAAK,UACjD,EAAK,WACN,EAAoB,EACpB,KAAK,YAAY,EAAK,UAAU,IAEpC,EAAoB,KAAK,IAAI,EAAK,MAAM,KAAK,OAAQ,GAErD,EAAY,aAAe,EAC3B,EAAY,SAAW,EAAS,EAAoB,EACpD,EAAY,SAAW,KAAK,KAAK,OAAS,EAAY,UAAY,EAAG,KAAK,OAAS,EAAG,OAAO,UAAY,EAAY,WAAa,EAC7H,EAAK,OAAO,SACb,EAAY,UAAY,KAAK,KAAK,OAAS,EAAY,WAG3D,EAAS,EAAS,EAAoB,KAAK,KAAK,OAChD,GAAgB,EAEhB,EAAc,IACd,GAAgB,KAAK,KAAK,QAAU,EAAc,IAEtD,EAAI,EAEJ,IADA,IAAI,EAAgB,EAAe,EAC5B,MACH,EAAO,EAAM,IACR,MAAM,OAAO,UAAY,EAElC,OAAO,CACX,EAGA,+BAAgC,SAAU,GAStC,IARA,IAAI,EAAe,EACf,EAAc,EAAM,OACpB,EAAI,EACJ,EAAO,KACP,EAAoB,EACpB,EAAc,KACd,EAAS,EACT,EAAK,KACF,KAEH,GADA,EAAO,EAAM,IACM,MAAM,OACf,MAAN,IACA,EAAK,EAAK,OAAO,OAGrB,EAAoB,KAAK,+BAA+B,EAAK,UACxD,EAAK,WACN,EAAoB,GAExB,EAAoB,KAAK,IAAI,EAAK,MAAM,KAAK,OAAQ,GAErD,EAAY,aAAe,EAC3B,EAAY,SAAW,EAAS,EAAoB,EACpD,EAAS,EAAS,EAAoB,KAAK,KAAK,OAChD,GAAgB,EAEhB,EAAc,IACd,GAAgB,KAAK,KAAK,QAAU,EAAc,IAEtD,EAAI,EAEJ,IADA,IAAI,EAAgB,EAAe,EAC5B,MACH,EAAO,EAAM,IACR,MAAM,OAAO,UAAY,EAIlC,OAAO,CACX,EAEA,gBAAiB,SAAU,GACvB,IAAI,EAAc,EAAK,MAAM,OACzB,EAAe,KAOnB,GANK,aAAc,GAAgB,KAAK,YACpC,EAAe,EAAY,UAE3B,EAAe,CAAE,GAAI,EAAG,GAAI,GAC5B,EAAY,SAAW,IAEJ,GAAnB,EAAa,IAA8B,GAAnB,EAAa,EAAS,CAC9C,IAAI,EAAI,EAAY,SAChB,EAAI,EAAY,SACpB,IAAK,EAAK,OAAQ,CACd,IAAI,EAAW,KAAK,gBAAgB,EAAK,QACzC,GAAK,EAAS,EACd,GAAK,EAAS,CAClB,CACA,EAAa,EAAI,EACjB,EAAa,EAAI,CACrB,CACA,OAAO,CACX,EAEA,eAAgB,SAAU,GACtB,IAAI,EAAY,EAAK,MAAM,KACvB,EAAW,KAAK,gBAAgB,GAEhC,EAAI,CAAC,EAIT,OAHA,EAAE,EAAI,EAAS,EAAI,EAAU,OAAS,EAAK,MAAM,OAAO,UAAY,GAAK,EACzE,EAAE,EAAI,EAAS,EAAI,EAAU,OAAS,EAE/B,CACX,EAEA,kBAAmB,SAAU,GAEzB,OADQ,KAAK,gBAAgB,EAEjC,EAEA,mBAAoB,SAAU,GAC1B,IAAI,EAAc,EAAK,MAAM,OACzB,EAAa,KAOjB,GANK,WAAY,GAAgB,KAAK,YAClC,EAAa,EAAY,QAEzB,EAAa,CAAE,GAAI,EAAG,GAAI,GAC1B,EAAY,OAAS,IAEJ,GAAjB,EAAW,IAA4B,GAAjB,EAAW,EACjC,GAAI,EAAK,OACL,EAAW,EAAI,EACf,EAAW,EAAI,MACZ,CACH,IAAI,EAAY,EAAK,MAAM,KACvB,EAAW,KAAK,gBAAgB,GACpC,EAAW,EAAI,EAAS,GAAK,EAAU,MAAQ,KAAK,KAAK,QAAU,EAAK,MAAM,OAAO,UACrF,EAAW,EAAI,EAAS,CAG5B,CAEJ,OAAO,CACX,EAEA,mBAAoB,SAAU,GAC1B,IAAI,EAAI,KAAK,mBAAmB,GAC5B,EAAO,CAAC,EAOZ,OANI,EAAK,MAAM,OAAO,WAAa,EAAG,UAAU,MAC5C,EAAK,EAAI,EAAE,EAAI,KAAK,KAAK,OAEzB,EAAK,EAAI,EAAE,EAEf,EAAK,EAAI,EAAE,EAAI,KAAK,KAAK,KAAK,KAAK,OAAS,GACrC,CACX,EAEA,aAAc,WACV,IAAI,EAAQ,KAAK,GAAG,KAAK,MACrB,EAAO,KACP,EAAO,KACX,IAAK,IAAI,KAAU,EACf,EAAO,EAAM,IACb,EAAO,KAAK,mBAAmB,IACtB,EAAI,KAAK,OAAO,IAAK,KAAK,OAAO,EAAI,EAAK,GAC/C,EAAK,EAAI,KAAK,OAAO,IAAK,KAAK,OAAO,EAAI,EAAK,GAEvD,MAAO,CACH,EAAG,KAAK,OAAO,EAAI,KAAK,OAAO,EAC/B,EAAG,KAAK,OAAO,EAAI,KAAK,OAAO,EAEvC,EAEA,YAAa,SAAU,GACf,EAAK,SAGL,EAAK,SACL,KAAK,cAAc,GAEnB,KAAK,YAAY,GAEzB,EAEA,YAAa,SAAU,GACnB,EAAK,UAAW,EAChB,KAAK,YAAY,GACjB,KAAK,YAAY,EAAK,UAAU,GAChC,KAAK,GAAG,oBAAoB,EAAG,WAAW,KAAM,CAAE,IAAK,cAAe,KAAM,GAAI,KAAM,EAAK,IAC/F,EAEA,cAAe,SAAU,GACrB,EAAK,UAAW,EAChB,KAAK,YAAY,GACjB,KAAK,YAAY,EAAK,UAAU,GAChC,KAAK,GAAG,oBAAoB,EAAG,WAAW,KAAM,CAAE,IAAK,gBAAiB,KAAM,GAAI,KAAM,EAAK,IACjG,EAEA,WAAY,WACR,IAEI,EAFA,EAAQ,KAAK,GAAG,KAAK,MACrB,EAAI,EAER,IAAK,IAAI,KAAU,GACf,EAAO,EAAM,IACH,WACN,EAAK,UAAW,EAChB,KAGR,GAAI,EAAI,EAAG,CACP,IAAI,EAAO,KAAK,GAAG,KAAK,KACxB,KAAK,YAAY,GACjB,KAAK,YAAY,EAAK,UAAU,EACpC,CACJ,EAEA,aAAc,WACV,IAEI,EAFA,EAAQ,KAAK,GAAG,KAAK,MACrB,EAAI,EAER,IAAK,IAAI,KAAU,GACf,EAAO,EAAM,IACJ,WAAa,EAAK,SACvB,EAAK,UAAW,EAChB,KAGR,GAAI,EAAI,EAAG,CACP,IAAI,EAAO,KAAK,GAAG,KAAK,KACxB,KAAK,YAAY,GACjB,KAAK,YAAY,EAAK,UAAU,EACpC,CACJ,EAEA,gBAAiB,SAAU,EAAc,EAAY,GACjD,KAAI,EAAe,GAKnB,IAJA,IAAI,EAAQ,GAAc,KAAK,GAAG,KAAK,KAAK,SACxC,EAAQ,GAAc,EACtB,EAAI,EAAM,OACV,EAAO,KACJ,KACH,EAAO,EAAM,GACT,EAAQ,IACH,EAAK,UACN,KAAK,YAAY,GAErB,KAAK,gBAAgB,EAAc,EAAK,SAAU,EAAQ,IAE1D,GAAS,GACL,EAAK,UACL,KAAK,cAAc,EAInC,EAEA,YAAa,SAAU,GACnB,IAAI,EAAO,KAAK,GAAG,KAAK,KACxB,GAAM,EAAM,CACR,IAAI,EAAmB,EAAK,MAAM,OAC9B,EAAK,QACL,EAAiB,mBAAqB,KAAK,+BAA+B,EAAiB,aAC3F,EAAiB,kBAAoB,KAAK,+BAA+B,EAAiB,aAEtF,EAAK,MAAM,OAAO,WAAa,EAAG,UAAU,MAC5C,EAAiB,mBAAqB,KAAK,+BAA+B,EAAiB,aAE3F,EAAiB,kBAAoB,KAAK,+BAA+B,EAAiB,YAGlG,KAAK,OAAO,EAAI,KAAK,IAAI,EAAiB,kBAAmB,EAAiB,oBAC9E,KAAK,aAAc,CACvB,MACI,EAAO,KAAK,0BAEpB,EAEA,YAAa,SAAU,EAAO,GAI1B,IAHA,IAAI,EAAI,EAAM,OACV,EAAO,KAEJ,MACH,EAAO,EAAM,IACM,MAAM,OACrB,EAAK,SACL,KAAK,YAAY,EAAK,SAAU,GAEhC,KAAK,YAAY,EAAK,UAAU,GAE/B,EAAK,SACN,EAAK,MAAM,OAAO,QAAU,EAGxC,EAEA,UAAW,SAAU,GACjB,OAAO,EAAK,QAChB,EAEA,WAAY,SAAU,GAClB,IAAI,EAAc,EAAK,MAAM,OAC7B,QAAK,YAAa,IAAiB,EAAY,QAKnD,GAGJ,EAAG,aAAe,SAAU,GACxB,KAAK,KAAO,EAAK,KACjB,KAAK,SAAW,EAAG,UACnB,KAAK,SAAS,UAAY,SAC1B,KAAK,WAAa,KAAK,SAAS,WAAW,MAC3C,KAAK,KAAO,CAAE,EAAG,EAAG,EAAG,EAC3B,EAEA,EAAG,aAAa,UAAY,CACxB,QAAS,WACL,OAAO,KAAK,QAChB,EAEA,SAAU,SAAU,EAAG,GACnB,KAAK,KAAK,EAAI,EACd,KAAK,KAAK,EAAI,EACd,KAAK,SAAS,MAAQ,EACtB,KAAK,SAAS,OAAS,CAC3B,EAEA,MAAO,WACH,KAAK,WAAW,UAAU,EAAG,EAAG,KAAK,KAAK,EAAG,KAAK,KAAK,EAC3D,EAEA,UAAW,SAAU,EAAM,EAAK,GAC5B,IAAI,EAAM,KAAK,WACf,EAAI,YAAc,KAAK,KAAK,WAC5B,EAAI,UAAY,KAAK,KAAK,WAC1B,EAAI,QAAU,QAEd,KAAK,WAAW,EACZ,EAAI,EAAI,EAAO,EACf,EAAI,EAAI,EAAO,EACf,EAAK,EAAI,EAAO,EAChB,EAAK,EAAI,EAAO,EACxB,EAEA,QAAS,SAAU,EAAiB,GAChC,EAAgB,UAAU,KAAK,SAAU,EAAG,GAC1C,GAAY,GAClB,EAEA,WAAY,SAAU,EAAK,EAAI,EAAI,EAAI,GACnC,EAAI,YACJ,EAAI,OAAO,EAAI,GACf,EAAI,cAAc,EAAiB,GAAX,EAAK,GAAU,EAAG,EAAI,EAAI,EAAI,EAAI,GAC1D,EAAI,QACR,EAEA,SAAU,SAAU,EAAK,EAAI,EAAI,EAAI,GACjC,EAAI,YACJ,EAAI,OAAO,EAAI,GACf,EAAI,OAAO,EAAI,GACf,EAAI,QACR,GAGJ,EAAG,UAAY,SAAU,GACrB,KAAK,KAAO,EACZ,KAAK,KAAO,EAAK,KACjB,KAAK,MAAQ,EAAG,UAAU,EAAE,OAC5B,KAAK,MAAM,aAAa,QAAS,UACjC,KAAK,KAAO,CAAE,EAAG,EAAG,EAAG,GACvB,KAAK,MAAQ,EACjB,EAEA,EAAG,UAAU,EAAI,SAAU,GACvB,OAAO,EAAG,gBAAgB,6BAA8B,EAC5D,EAEA,EAAG,UAAU,UAAY,CACrB,QAAS,WACL,OAAO,KAAK,KAChB,EAEA,SAAU,SAAU,EAAG,GACnB,KAAK,KAAK,EAAI,EACd,KAAK,KAAK,EAAI,EACd,KAAK,MAAM,aAAa,QAAS,GACjC,KAAK,MAAM,aAAa,SAAU,EACtC,EAEA,MAAO,WAEH,IADA,IAAI,EAAM,KAAK,MAAM,OACd,KACH,KAAK,MAAM,YAAY,KAAK,MAAM,IAEtC,KAAK,MAAM,OAAS,CACxB,EAEA,UAAW,SAAU,EAAM,EAAK,GAC5B,IAAI,EAAO,EAAG,UAAU,EAAE,QAC1B,EAAK,aAAa,SAAU,KAAK,KAAK,YACtC,EAAK,aAAa,eAAgB,KAAK,KAAK,YAC5C,EAAK,aAAa,OAAQ,eAC1B,KAAK,MAAM,KAAK,GAChB,KAAK,MAAM,YAAY,GACvB,KAAK,WAAW,EAAM,EAAI,EAAI,EAAO,EAAG,EAAI,EAAI,EAAO,EAAG,EAAK,EAAI,EAAO,EAAG,EAAK,EAAI,EAAO,EACjG,EAEA,QAAS,SAAU,EAAiB,GAChC,IAAI,EAAM,IAAI,MACd,EAAI,OAAS,WACT,EAAgB,UAAU,EAAK,EAAG,GAChC,GAAY,GAClB,EACA,EAAI,IAAM,6BAA+B,MAAK,IAAI,eAAgB,kBAAkB,KAAK,OAC7F,EAEA,WAAY,SAAU,EAAM,EAAI,EAAI,EAAI,GACpC,EAAK,aAAa,IAAK,IAAM,EAAK,IAAM,EAAK,OAAS,EAAiB,GAAX,EAAK,GAAU,GAAK,IAAM,EAAK,KAAO,EAAK,IAAM,EAAK,KAAO,EAAK,IAAM,EACxI,EAEA,SAAU,SAAU,EAAM,EAAI,EAAI,EAAI,GAClC,EAAK,aAAa,IAAK,KAAO,EAAK,IAAM,EAAK,MAAQ,EAAK,IAAM,EACrE,GAIJ,EAAG,cAAgB,SAAU,EAAI,GAC7B,KAAK,KAAO,EACZ,KAAK,GAAK,EACV,KAAK,OAAS,EAAG,OAEjB,KAAK,UAAY,KACjB,KAAK,QAAU,KACf,KAAK,QAAU,KAEf,KAAK,KAAO,CAAE,EAAG,EAAG,EAAG,GAEvB,KAAK,cAAgB,KACrB,KAAK,aAAe,KAEpB,KAAK,MAAQ,IACjB,EAEA,EAAG,cAAc,UAAY,CACzB,KAAM,WAruED,IAAU,EAaA,EA4tEX,GAHA,EAAO,MAAM,aAEb,KAAK,WA3tEM,EA2tES,KAAK,KAAK,YA3tEiB,iBAAP,GAAqC,IAAhB,EAAG,UAAwC,iBAAb,EAAG,OAAoD,iBAArB,EAAG,cA2tErF,KAAK,KAAK,WAxuE1C,EAwuEyD,KAAK,KAAK,UAxuEtD,EAAG,eAAe,IAyuErC,KAAK,UAAV,CAIA,KAAK,QAAU,EAAG,OAClB,KAAK,QAAU,EAAG,WAClB,KAAK,SAAW,EAAG,SAEnB,KAAK,MAA2C,QAAnC,KAAK,KAAK,OAAO,cAA0B,IAAI,EAAG,UAAU,MAAQ,IAAI,EAAG,aAAa,MACrG,KAAK,QAAQ,UAAY,gCAAkC,KAAK,KAAK,cACrE,KAAK,QAAQ,SAAW,EACxB,KAAK,QAAQ,YAAY,KAAK,MAAM,WACpC,KAAK,QAAQ,YAAY,KAAK,SAE9B,KAAK,SAAS,UAAY,gBAC1B,KAAK,SAAS,KAAO,OAErB,KAAK,WAAa,EAClB,KAAK,SAAW,GAChB,KAAK,QAAU,GACf,KAAK,QAAU,EAEf,IAAI,EAAI,KACR,EAAG,KAAK,IAAI,UAAU,KAAK,SAAU,WAAW,SAAU,GACtD,IAAI,EAAM,GAAK,MACI,IAAf,EAAI,UAAiB,EAAE,gBAAiB,EAAI,kBACpD,IACA,EAAG,KAAK,IAAI,UAAU,KAAK,SAAU,QAAQ,SAAU,GACnD,EAAE,eACN,IAEA,KAAK,UAAU,YAAY,KAAK,SAGhC,KAAK,kBAAmB,EAExB,KAAK,kBAjCL,MAFI,EAAO,MAAM,qDAoCrB,EAEA,UAAW,SAAU,EAAK,EAAY,GAClC,EAAG,KAAK,IAAI,UAAU,KAAK,QAAS,GAAY,SAAU,GACtD,IAAI,EAAM,GAAK,MACf,EAAa,KAAK,EAAK,EAC3B,GACJ,EAEA,kBAAmB,SAAU,GACzB,GAAe,MAAX,EACA,OAAO,KAEX,IAAI,EAAU,EAAQ,QAAQ,cAC9B,MAAe,WAAX,GAAmC,QAAX,GAAgC,QAAX,EACtC,KAEI,UAAX,GAAkC,cAAX,EAChB,EAAQ,aAAa,UAErB,KAAK,kBAAkB,EAAQ,cAE9C,EAEA,YAAa,SAAU,GACnB,MAAyC,cAAjC,EAAQ,QAAQ,aAC5B,EAEA,MAAO,WACH,EAAO,MAAM,cACb,KAAK,cAAgB,KACrB,KAAK,cACL,KAAK,cACL,KAAK,aACT,EAEA,YAAa,WACT,IAAI,EAAa,KAAK,GAAG,QAAQ,MAE7B,KAAK,QAAQ,UADX,EACuB,SAAW,EAEX,EAEjC,EAEA,mBAAoB,WAChB,IAAI,EAAQ,KAAK,GAAG,KAAK,MACzB,IAAK,IAAI,KAAU,EACf,KAAK,wBAAwB,EAAM,GAE3C,EAEA,KAAM,WACF,EAAO,MAAM,aACb,KAAK,YACT,EAEA,YAAa,WACT,IAAI,EAAW,KAAK,OAAO,eACvB,EAAY,EAAS,EAAwB,EAApB,KAAK,KAAK,QACnC,EAAa,EAAS,EAAwB,EAApB,KAAK,KAAK,QACpC,EAAW,KAAK,QAAQ,YACxB,EAAW,KAAK,QAAQ,aACxB,EAAW,IAAa,EAAW,GACnC,EAAW,IAAc,EAAW,GACxC,KAAK,KAAK,EAAI,EACd,KAAK,KAAK,EAAI,CAClB,EAEA,gBAAiB,SAAU,GACvB,IAAI,EAAY,EAAK,MAAM,KAC3B,EAAU,MAAQ,EAAU,QAAQ,YACpC,EAAU,OAAS,EAAU,QAAQ,YACzC,EAEA,WAAY,WACR,IAAI,EAAQ,KAAK,GAAG,KAAK,MACrB,EAAW,EAAG,yBAClB,IAAK,IAAI,KAAU,EACf,KAAK,oBAAoB,EAAM,GAAS,GAG5C,IAAK,IAAI,KADT,KAAK,QAAQ,YAAY,GACN,EACf,KAAK,gBAAgB,EAAM,GAEnC,EAEA,SAAU,SAAU,GAChB,KAAK,oBAAoB,EAAM,KAAK,SACpC,KAAK,gBAAgB,EACzB,EAEA,oBAAqB,SAAU,EAAM,GACjC,IAAI,EAAY,KACZ,SAAU,EAAK,MACf,EAAY,EAAK,MAAM,MAEvB,EAAY,CAAC,EACb,EAAK,MAAM,KAAO,GAGtB,IAAI,EAAI,EAAG,UACX,GAAI,EAAK,OACL,EAAE,UAAY,WACX,CACH,IAAI,EAAM,EAAG,cACb,EAAG,EAAK,KACR,EAAI,aAAa,SAAU,EAAK,IAChC,EAAI,MAAM,WAAa,SACvB,EAAY,YAAY,GACxB,EAAU,SAAW,CACzB,CACM,EAAK,QACH,KAAK,KAAK,aACV,EAAG,EAAG,EAAK,OAEX,EAAG,EAAG,EAAK,QAGnB,EAAE,aAAa,SAAU,EAAK,IAC9B,EAAE,MAAM,WAAa,SACrB,KAAK,yBAAyB,EAAG,EAAK,MAEtC,EAAY,YAAY,GACxB,EAAU,QAAU,CACxB,EAEA,YAAa,SAAU,GACO,MAAtB,KAAK,eAAyB,KAAK,cAAc,IAAM,EAAK,KAC5D,KAAK,cAAgB,MAEA,MAArB,KAAK,cAAwB,KAAK,aAAa,IAAM,EAAK,KAC1D,EAAK,MAAM,KAAK,QAAQ,YAAY,KAAK,UACzC,KAAK,aAAe,MAIxB,IAFA,IAAI,EAAW,EAAK,SAChB,EAAI,EAAS,OACV,KACH,KAAK,YAAY,EAAS,IAE9B,GAAI,EAAK,MAAM,KAAM,CACjB,IAAI,EAAU,EAAK,MAAM,KAAK,QAC1B,EAAW,EAAK,MAAM,KAAK,SAC/B,KAAK,QAAQ,YAAY,GACzB,KAAK,QAAQ,YAAY,GACzB,EAAK,MAAM,KAAK,QAAU,KAC1B,EAAK,MAAM,KAAK,SAAW,IAC/B,CACJ,EAEA,YAAa,SAAU,GACnB,IAAI,EAAY,EAAK,MAAM,KACvB,EAAU,EAAU,QAQxB,GAPM,EAAK,QACH,KAAK,KAAK,aACV,EAAG,EAAS,EAAK,OAEjB,EAAG,EAAS,EAAK,QAGrB,KAAK,OAAO,WAAW,GACvB,EAAU,MAAQ,EAAQ,YAC1B,EAAU,OAAS,EAAQ,iBACxB,CACH,IAAI,EAAe,EAAQ,aAAa,SACxC,EAAQ,MAAQ,sCAChB,EAAU,MAAQ,EAAQ,YAC1B,EAAU,OAAS,EAAQ,aAC3B,EAAQ,MAAQ,CACpB,CACJ,EAEA,YAAa,SAAU,GACb,KAAK,gBACP,KAAK,cAAc,MAAM,KAAK,QAAQ,UAClC,KAAK,cAAc,MAAM,KAAK,QAAQ,UAAU,QAAQ,iBAAkB,IAC9E,KAAK,wBAAwB,KAAK,gBAEhC,IACF,KAAK,cAAgB,EACrB,EAAK,MAAM,KAAK,QAAQ,WAAa,YACrC,KAAK,wBAAwB,GAErC,EAEA,aAAc,WACV,KAAK,YAAY,KACrB,EAEA,iBAAkB,WACd,OAAO,KAAK,YAChB,EAEA,WAAY,WACR,QAAU,KAAK,YACnB,EAEA,gBAAiB,SAAU,GACvB,GAAK,EAAK,MAAV,CAIyB,MAArB,KAAK,cACL,KAAK,gBAET,KAAK,aAAe,EACpB,IACI,EADY,EAAK,MAAM,KACH,QACpB,EAAQ,EAAK,MACb,EAAM,iBAAiB,GAC3B,KAAK,SAAS,MAAQ,EACtB,KAAK,SAAS,MAAM,MAAS,EAAQ,YAAc,SAAS,EAAI,iBAAiB,iBAAmB,SAAS,EAAI,iBAAiB,kBAAqB,KACvJ,EAAQ,UAAY,GACpB,EAAQ,YAAY,KAAK,UACzB,EAAQ,MAAM,OAAS,EACvB,KAAK,SAAS,QACd,KAAK,SAAS,QAfd,MAFI,EAAO,KAAK,yBAkBpB,EAEA,cAAe,WACX,GAAyB,MAArB,KAAK,aAAsB,CAC3B,IAAI,EAAO,KAAK,aAChB,KAAK,aAAe,KACpB,IACI,EADY,EAAK,MAAM,KACH,QACpB,EAAQ,KAAK,SAAS,MAC1B,EAAQ,MAAM,OAAS,OACvB,EAAQ,YAAY,KAAK,UACrB,EAAG,KAAK,KAAK,SAAS,IAAU,EAAK,QAAU,EAC3C,KAAK,KAAK,aACV,EAAG,EAAS,EAAK,OAEjB,EAAG,EAAS,EAAK,OAGrB,KAAK,GAAG,YAAY,EAAK,GAAI,EAErC,CACA,KAAK,QAAQ,OACjB,EAEA,gBAAiB,WACb,IAAI,EAAS,KAAK,OAAO,OAGzB,MAAO,CAAE,GAFC,KAAK,KAAK,EAAI,EAAO,EAAI,EAAO,GAAK,EAE/B,EADP,KAAK,KAAK,EAAI,EAE3B,EAEA,OAAQ,WACJ,KAAK,MAAM,SAAS,EAAG,GACvB,KAAK,QAAQ,MAAM,MAAQ,MAC3B,KAAK,QAAQ,MAAM,OAAS,MAE5B,KAAK,cACL,KAAK,OACT,EAEA,MAAO,WACH,KAAK,MAAM,SAAS,KAAK,KAAK,EAAG,KAAK,KAAK,GAC3C,KAAK,QAAQ,MAAM,MAAQ,KAAK,KAAK,EAAI,KACzC,KAAK,QAAQ,MAAM,OAAS,KAAK,KAAK,EAAI,KAC1C,KAAK,aACL,KAAK,aAEL,KAAK,GAAG,oBAAoB,EAAG,WAAW,OAAQ,CAAE,KAAM,IAC9D,EAEA,OAAQ,WACJ,OAAO,KAAK,QAAQ,KAAK,WAAa,KAAK,SAC/C,EAEA,QAAS,WACL,OAAO,KAAK,QAAQ,KAAK,WAAa,KAAK,SAC/C,EAEA,QAAS,SAAU,GACf,GAAK,EAAO,KAAK,SAAa,EAAO,KAAK,QACtC,OAAO,EAEX,KAAK,WAAa,EAClB,IAAK,IAAI,EAAI,EAAG,EAAI,KAAK,QAAQ,SAAS,OAAQ,IAC9C,KAAK,QAAQ,SAAS,GAAG,MAAM,KAAO,EAG1C,OADA,KAAK,MAAK,IACH,CAEX,EAEA,aAAc,WAEV,IAAI,EAAU,KAAK,QAAQ,YACvB,EAAU,KAAK,QAAQ,aAC3B,GAAI,KAAK,KAAK,EAAI,EAAS,CACvB,IAAI,EAAU,KAAK,kBACnB,KAAK,QAAQ,WAAa,EAAQ,EAAI,KAAK,WAAa,EAAU,CACtE,CACI,KAAK,KAAK,EAAI,IACd,KAAK,QAAQ,WAAa,KAAK,KAAK,EAAI,KAAK,WAAa,GAAW,EAE7E,EAEA,KAAM,SAAU,GACZ,EAAO,MAAM,aACb,KAAK,cACL,KAAK,QACC,GACF,KAAK,cAEb,EAEA,SAAU,WACN,KAAK,cACL,KAAK,OACT,EAEA,cAAe,SAAU,GACrB,IAAI,EAAK,EAAK,MAAM,KACpB,EAAG,gBAAkB,CACjB,EAAG,SAAS,EAAG,QAAQ,MAAM,MAAQ,KAAK,QAAQ,WAClD,EAAG,SAAS,EAAG,QAAQ,MAAM,KAAO,KAAK,QAAQ,UAEzD,EAEA,iBAAkB,SAAU,GACxB,IAAI,EAAK,EAAK,MAAM,KACpB,KAAK,QAAQ,WAAa,SAAS,EAAG,QAAQ,MAAM,MAAQ,EAAG,gBAAgB,EAC/E,KAAK,QAAQ,UAAY,SAAS,EAAG,QAAQ,MAAM,KAAO,EAAG,gBAAgB,CACjF,EAEA,YAAa,WACT,IAAI,EAAO,KAAK,GAAG,KACnB,GAAY,MAAR,EAAJ,CAGA,IAAI,EAAQ,EAAK,MACb,EAAO,KACX,IAAK,IAAI,KAAU,GACf,EAAO,EAAM,IACR,MAAM,KAAK,QAAU,KAC1B,EAAK,MAAM,KAAK,SAAW,KAE/B,KAAK,QAAQ,UAAY,EARzB,CASJ,EAEA,WAAY,WACR,IAAI,EAAQ,KAAK,GAAG,KAAK,MACrB,EAAO,KACP,EAAe,KACf,EAAW,KACX,EAAI,KACJ,EAAa,KACb,EAAgB,IAChB,EAAY,KACZ,EAAU,KAAK,kBACnB,IAAK,IAAI,KAAU,EAGf,GADA,GADA,EAAO,EAAM,IACI,MAAM,MACE,QACzB,EAAW,EAAU,SAChB,KAAK,OAAO,WAAW,IAK5B,KAAK,wBAAwB,GAC7B,EAAI,KAAK,OAAO,eAAe,GAC/B,EAAU,MAAQ,EAAQ,EAAI,EAAE,EAChC,EAAU,MAAQ,EAAQ,EAAI,EAAE,EAChC,EAAa,MAAM,KAAQ,EAAQ,EAAI,EAAE,EAAK,KAC9C,EAAa,MAAM,IAAO,EAAQ,EAAI,EAAE,EAAK,KAC7C,EAAa,MAAM,QAAU,GAC7B,EAAa,MAAM,WAAa,WAC3B,EAAK,QAAU,EAAK,SAAS,OAAS,IACvC,EAAgB,EAAK,SAAW,IAAM,IACtC,EAAa,KAAK,OAAO,mBAAmB,GAC5C,EAAS,MAAM,KAAQ,EAAQ,EAAI,EAAW,EAAK,KACnD,EAAS,MAAM,IAAO,EAAQ,EAAI,EAAW,EAAK,KAClD,EAAS,MAAM,QAAU,GACzB,EAAS,MAAM,WAAa,UAC5B,EAAG,EAAU,IAGZ,EAAK,QAAkC,GAAxB,EAAK,SAAS,SAC9B,EAAS,MAAM,QAAU,OACzB,EAAS,MAAM,WAAa,YAxB5B,EAAa,MAAM,QAAU,OAC7B,EAAS,MAAM,QAAU,OA0BrC,EAEA,wBAAyB,SAAU,GAC/B,KAAK,yBAAyB,EAAK,MAAM,KAAK,QAAS,EAAK,KAChE,EAEA,yBAA0B,SAAU,EAAc,GAsB9C,GArBI,qBAAsB,IACtB,EAAa,MAAM,gBAAkB,EAAU,qBAE/C,qBAAsB,IACtB,EAAa,MAAM,MAAQ,EAAU,qBAErC,UAAW,IACX,EAAa,MAAM,MAAQ,EAAiB,MAAI,MAEhD,WAAY,IACZ,EAAa,MAAM,OAAS,EAAkB,OAAI,MAElD,cAAe,IACf,EAAa,MAAM,SAAW,EAAU,aAAe,MAEvD,gBAAiB,IACjB,EAAa,MAAM,WAAa,EAAU,gBAE1C,eAAgB,IAChB,EAAa,MAAM,UAAY,EAAU,eAEzC,qBAAsB,EAAW,CACjC,IAAI,EAAkB,EAAU,oBAChC,GAAI,EAAgB,WAAW,SAAW,EAAiB,OAAK,EAAkB,OAAG,CACjF,IAAI,EAAM,IAAI,MAEd,EAAI,OAAS,WACT,IAAI,EAAI,EAAG,UACX,EAAE,MAAQ,EAAa,YACvB,EAAE,OAAS,EAAa,aAExB,GAAI,EAAE,WAAY,CACJ,EAAE,WAAW,MACnB,UAHE,KAGa,EAAG,EAAG,EAAa,YAAa,EAAa,cAChE,IAAI,EAAkB,EAAE,YACxB,EAAa,MAAM,gBAAkB,OAAS,EAAkB,GACpE,CACJ,EACA,EAAI,IAAM,CAEd,MACI,EAAa,MAAM,gBAAkB,OAAS,EAAkB,IAEpE,EAAa,MAAM,eAAiB,MAEhC,wBAAyB,IACzB,EAAa,MAAM,UAAY,UAAY,EAAU,uBAAyB,OAEtF,CACJ,EAEA,wBAAyB,SAAU,GAC/B,IAAI,EAAe,EAAK,MAAM,KAAK,QACnC,EAAa,MAAM,gBAAkB,GACrC,EAAa,MAAM,MAAQ,EAC/B,EAEA,YAAa,WACT,KAAK,MAAM,OACf,EAEA,WAAY,WACR,KAAK,cACL,IAAI,EAAQ,KAAK,GAAG,KAAK,MACrB,EAAO,KACP,EAAM,KACN,EAAO,KACP,EAAU,KAAK,kBACnB,IAAK,IAAI,KAAU,GACf,EAAO,EAAM,IACF,QACN,YAAa,EAAK,MAAM,SAAY,EAAK,MAAM,OAAO,UAC3D,EAAM,KAAK,OAAO,kBAAkB,GACpC,EAAO,KAAK,OAAO,mBAAmB,EAAK,QAC3C,KAAK,MAAM,UAAU,EAAM,EAAK,GAExC,EAGA,iBAAkB,WAEd,GAAI,KAAK,KAAK,UAAW,CAErB,IACI,EAAG,EADH,GAAW,EAEX,KAAK,KAAK,iCAEV,KAAK,QAAQ,MAAQ,oBAGzB,EAAG,KAAK,IAAI,UAAU,KAAK,UAAW,aAAc,IAChD,GAAW,EAEX,EAAI,EAAU,QACd,EAAI,EAAU,WAGlB,EAAG,KAAK,IAAI,UAAU,KAAK,UAAW,WAAW,KAC7C,GAAW,KAGf,EAAG,KAAK,IAAI,UAAU,KAAK,UAAW,aAAc,IAC5C,KAAK,kBAAoB,IACzB,KAAK,QAAQ,SAAS,EAAI,EAAU,QAAS,EAAI,EAAU,SAE3D,EAAI,EAAU,QACd,EAAI,EAAU,QAClB,GAER,CACJ,EAEA,qBAAsB,WAClB,OAAO,KAAK,KAAK,SACrB,EAEA,wBAAyB,WACrB,KAAK,kBAAmB,CAC5B,EAEA,yBAA0B,WACtB,KAAK,kBAAmB,CAC5B,GAKJ,EAAG,kBAAoB,SAAU,EAAI,GACjC,KAAK,GAAK,EACV,KAAK,KAAO,EACZ,KAAK,QAAU,EAAQ,QACvB,KAAK,QAAU,EAAQ,QACvB,KAAK,OAAS,KACd,KAAK,SAAW,CAAC,CACrB,EAEA,EAAG,kBAAkB,UAAY,CAC7B,KAAM,WAaF,IAAK,IAAI,KAZT,EAAG,KAAK,IAAI,UAAU,KAAK,GAAG,KAAK,QAAS,UAAW,KAAK,QAAQ,KAAK,OAEzE,KAAK,QAAkB,SAAI,KAAK,gBAChC,KAAK,QAAoB,WAAI,KAAK,kBAClC,KAAK,QAAkB,SAAI,KAAK,gBAChC,KAAK,QAAiB,QAAI,KAAK,eAC/B,KAAK,QAAgB,OAAI,KAAK,cAC9B,KAAK,QAAY,GAAI,KAAK,UAC1B,KAAK,QAAc,KAAI,KAAK,YAC5B,KAAK,QAAc,KAAI,KAAK,YAC5B,KAAK,QAAe,MAAI,KAAK,aAEV,KAAK,QACpB,GAAM,KAAK,QAAQ,IAAY,KAAU,KAAK,QAAU,CACpD,IAAI,EAAO,KAAK,QAAQ,GACpB,MAAM,QAAQ,KACd,EAAO,CAAC,IAEZ,IAAI,IAAI,KAAO,EACX,KAAK,SAAS,GAAO,KAAK,QAAQ,EAE1C,CAGkC,mBAA3B,KAAK,KAAK,aACjB,KAAK,OAAS,KAAK,KAAK,aAExB,KAAK,OAAS,EAAG,KAAK,KAAK,KAEnC,EAEA,gBAAiB,WACb,KAAK,KAAK,QAAS,CACvB,EAEA,iBAAkB,WACd,KAAK,KAAK,QAAS,CACvB,EAEA,QAAS,SAAU,GAEf,GADe,GAAX,EAAE,OAAc,EAAE,kBAClB,KAAK,GAAG,KAAK,aAAjB,CACA,IAAI,EAAM,GAAK,MACf,IAAK,KAAK,KAAK,OAAU,OAAO,EAChC,IAAI,EAAK,EAAI,SAAW,EAAI,SAAW,KAAO,EAAI,SAAW,KAAO,EAAI,QAAU,KAAO,EAAI,UAAY,IACrG,KAAM,KAAK,UACX,KAAK,SAAS,GAAI,KAAK,KAAM,KAAK,GAAI,EALD,CAO7C,EAEA,gBAAiB,SAAU,EAAK,GAC5B,IAAI,EAAgB,EAAI,oBACxB,GAAM,EAAe,CACjB,IAAI,EAAS,KAAK,SACP,EAAI,SAAS,EAAe,EAAQ,cAE3C,EAAI,YAAY,GAChB,EAAI,WAAW,GAEvB,CACJ,EACA,kBAAmB,SAAU,EAAK,GAC9B,IAAI,EAAgB,EAAI,oBACxB,GAAM,IAAkB,EAAc,OAAQ,CAC1C,IAAI,EAAS,KAAK,SACP,EAAI,kBAAkB,EAAe,EAAQ,cAEpD,EAAI,YAAY,GAChB,EAAI,WAAW,GAEvB,CACJ,EACA,gBAAiB,SAAU,EAAK,GAC5B,IAAI,EAAgB,EAAI,oBAClB,GACF,EAAI,WAAW,EAEvB,EACA,eAAgB,SAAU,EAAK,GAC3B,IAAI,EAAgB,EAAI,oBAClB,IAAkB,EAAc,SAClC,EAAI,YAAY,EAAc,QAC9B,EAAI,YAAY,GAExB,EACA,cAAe,SAAU,EAAK,GAC1B,IAAI,EAAM,GAAK,MACX,EAAgB,EAAI,oBAClB,IACF,EAAI,YAAY,EAAc,IAC9B,EAAI,kBACJ,EAAI,iBAEZ,EACA,UAAW,SAAU,EAAK,GACtB,IAAI,EAAM,GAAK,MACX,EAAgB,EAAI,oBACxB,GAAM,EAAe,CACjB,IAAI,EAAU,EAAI,iBAAiB,GACnC,IAAK,EAAS,CACV,IAAI,EAAK,EAAI,iBAAiB,EAAc,QACtC,GAAM,EAAG,SAAS,OAAS,IAC7B,EAAU,EAAG,SAAS,EAAG,SAAS,OAAS,GAEnD,CACM,GACF,EAAI,YAAY,GAEpB,EAAI,kBACJ,EAAI,gBACR,CACJ,EAEA,YAAa,SAAU,EAAK,GACxB,IAAI,EAAM,GAAK,MACX,EAAgB,EAAI,oBACxB,GAAM,EAAe,CACjB,IAAI,EAAY,EAAI,gBAAgB,GACpC,IAAK,EAAW,CACZ,IAAI,EAAK,EAAI,gBAAgB,EAAc,QACrC,GAAM,EAAG,SAAS,OAAS,IAC7B,EAAY,EAAG,SAAS,GAEhC,CACM,GACF,EAAI,YAAY,GAEpB,EAAI,kBACJ,EAAI,gBACR,CACJ,EAEA,YAAa,SAAU,EAAK,GACxB,KAAK,kBAAkB,EAAK,EAAG,EAAG,UAAU,KAChD,EACA,aAAc,SAAU,EAAK,GACzB,KAAK,kBAAkB,EAAK,EAAG,EAAG,UAAU,MAChD,EACA,kBAAmB,SAAU,EAAK,EAAG,GACjC,IAAI,EAAM,GAAK,MACX,EAAgB,EAAI,oBACpB,EAAO,KACX,GAAM,EAAe,CACjB,GAAI,EAAc,OAAQ,CAGtB,IAFA,IAAI,EAAI,EAAc,SAClB,EAAW,GACN,EAAI,EAAG,EAAI,EAAE,OAAQ,IACtB,EAAE,GAAG,YAAc,GACnB,EAAS,KAAK,GAGtB,EAAO,EAAE,EAAS,KAAK,OAAO,EAAS,OAAS,GAAK,IACzD,MACK,GAAI,EAAc,YAAc,EAAG,CACpC,IACI,GADA,EAAW,EAAc,UACA,OACzB,EAAgB,IAChB,EAAO,EAAS,KAAK,OAAO,EAAgB,GAAK,IAEzD,MACI,EAAO,EAAc,OAEnB,GACF,EAAI,YAAY,GAEpB,EAAI,kBACJ,EAAI,gBACR,CACJ,GAKJ,EAAG,OAAS,SAAU,EAAM,GACxB,KAAK,KAAO,EACZ,KAAK,KAAO,CAChB,EAEA,EAAG,QAAU,GAEb,EAAG,gBAAkB,SAAU,GACvB,aAAkB,EAAG,QACrB,EAAG,QAAQ,KAAK,EAExB,EAEA,EAAG,aAAe,SAAU,GACxB,EAAG,YAAW,WACV,EAAG,cAAc,EACrB,GAAG,EACP,EAEA,EAAG,cAAgB,SAAU,GAGzB,IAFA,IAAI,EAAI,EAAG,QAAQ,OACf,EAAU,KACL,EAAI,EAAG,EAAI,EAAG,IAEI,mBADvB,EAAU,EAAG,QAAQ,GAAG,OAEpB,EAAQ,EAGpB,EAGA,EAAG,KAAO,SAAU,EAAS,GACzB,IAAI,EAAM,IAAI,EAAG,GAEjB,OADA,EAAI,KAAK,GACF,CACX,EAGsB,oBAAX,QAA6C,iBAAZ,QACxC,OAAO,QAAU,EACQ,mBAAX,SAA0B,OAAO,KAAO,OAAO,KAC7D,QAAO,WAAc,OAAO,CAAI,IAEhC,EAAG,GAAY,CA9/FnB,MAHQ,EAAO,IAAI,EAAW,2BAmgGjC,CAthGC,CAshGmB,oBAAX,OAAyB,OAAS","file":"/npm/jsmind-simbiotico@0.5.6/js/jsmind.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/jsmind-simbiotico@0.5.6/js/jsmind.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/**\n * @license BSD\n * @copyright 2014-2023 hizzgdev@163.com\n *\n * Project Home:\n *   https://github.com/hizzgdev/jsmind/\n */\n\n; (function ($w) {\n    'use strict';\n    // set 'jsMind' as the library name.\n    // __name__ should be a const value, Never try to change it easily.\n    var __name__ = 'jsMind';\n    // library version\n    var __version__ = '0.5.2';\n    // author\n    var __author__ = 'hizzgdev@163.com';\n\n    // an noop function define\n    var _noop = function () { };\n    var logger = (typeof console === 'undefined') ? {\n        log: _noop, debug: _noop, error: _noop, warn: _noop, info: _noop\n    } : console;\n\n    // check global variables\n    if (typeof module === 'undefined' || !module.exports) {\n        if (typeof $w[__name__] != 'undefined') {\n            logger.log(__name__ + ' has been already exist.');\n            return;\n        }\n    }\n\n    // shortcut of methods in dom\n    var $d = $w.document;\n    var $g = function (id) { return $d.getElementById(id); };\n    var $c = function (tag) { return $d.createElement(tag); };\n    var $t = function (n, t) { if (n.hasChildNodes()) { n.firstChild.nodeValue = t; } else { n.appendChild($d.createTextNode(t)); } };\n\n    var $h = function (n, t) {\n        if (t instanceof HTMLElement) {\n            n.innerHTML = '';\n            n.appendChild(t);\n        } else {\n            n.innerHTML = t;\n        }\n    };\n    // detect isElement\n    var $i = function (el) { return !!el && (typeof el === 'object') && (el.nodeType === 1) && (typeof el.style === 'object') && (typeof el.ownerDocument === 'object'); };\n    if (typeof String.prototype.startsWith != 'function') { String.prototype.startsWith = function (p) { return this.slice(0, p.length) === p; }; }\n\n    var DEFAULT_OPTIONS = {\n        container: '',   // id of the container\n        editable: false, // you can change it in your options\n        theme: null,\n        mode: 'full',    // full or side\n        support_html: true,\n\n        view: {\n            engine: 'canvas',\n            hmargin: 100,\n            vmargin: 50,\n            line_width: 2,\n            line_color: '#555',\n            draggable: false, // drag the mind map with your mouse, when it's larger that the container\n            hide_scrollbars_when_draggable: false, // hide container scrollbars, when mind map is larger than container and draggable option is true.\n            node_overflow: 'hidden' // hidden or wrap\n        },\n        layout: {\n            hspace: 30,\n            vspace: 20,\n            pspace: 13\n        },\n        default_event_handle: {\n            enable_mousedown_handle: true,\n            enable_click_handle: true,\n            enable_dblclick_handle: true,\n            enable_mousewheel_handle: true\n        },\n        shortcut: {\n            enable: true,\n            handles: {\n            },\n            mapping: {\n                addchild: [45, 4096+13], // Insert, Ctrl+Enter\n                addbrother: 13, // Enter\n                editnode: 113,// F2\n                delnode: 46, // Delete\n                toggle: 32, // Space\n                left: 37, // Left\n                up: 38, // Up\n                right: 39, // Right\n                down: 40, // Down\n            }\n        },\n    };\n\n    // core object\n    var jm = function (options) {\n        jm.current = this;\n\n        this.version = __version__;\n        var opts = {};\n        jm.util.json.merge(opts, DEFAULT_OPTIONS);\n        jm.util.json.merge(opts, options);\n\n        if (!opts.container) {\n            logger.error('the options.container should not be null or empty.');\n            return;\n        }\n        this.options = opts;\n        this.initialized = false;\n        this.mind = null;\n        this.event_handles = [];\n        this.init();\n    };\n\n    // ============= static object =============================================\n    jm.direction = {\n        left: -1, center: 0, right: 1, of: function (dir) {\n            if (!dir || dir === -1 || dir === 0 || dir === 1) {\n                return dir;\n            }\n            if (dir === '-1' || dir === '0' || dir === '1') {\n                return parseInt(dir);\n            }\n            if (dir.toLowerCase() === 'left') {\n                return this.left;\n            }\n            if (dir.toLowerCase() === 'right') {\n                return this.right;\n            }\n            if (dir.toLowerCase() === 'center') {\n                return this.center;\n            }\n        }\n    };\n    jm.event_type = { show: 1, resize: 2, edit: 3, select: 4 };\n    jm.key = { meta: 1 << 13, ctrl: 1 << 12, alt: 1 << 11, shift: 1 << 10 };\n\n    jm.node = function (sId, iIndex, sTopic, oData, bIsRoot, oParent, eDirection, bExpanded) {\n        if (!sId) { logger.error('invalid node id'); return; }\n        if (typeof iIndex != 'number') { logger.error('invalid node index'); return; }\n        if (typeof bExpanded === 'undefined') { bExpanded = true; }\n        this.id = sId;\n        this.index = iIndex;\n        this.topic = sTopic;\n        this.data = oData || {};\n        this.isroot = bIsRoot;\n        this.parent = oParent;\n        this.direction = eDirection;\n        this.expanded = !!bExpanded;\n        this.children = [];\n        this._data = {};\n    };\n\n    jm.node.compare = function (node1, node2) {\n        // '-1' is alwary the last\n        var r = 0;\n        var i1 = node1.index;\n        var i2 = node2.index;\n        if (i1 >= 0 && i2 >= 0) {\n            r = i1 - i2;\n        } else if (i1 == -1 && i2 == -1) {\n            r = 0;\n        } else if (i1 == -1) {\n            r = 1;\n        } else if (i2 == -1) {\n            r = -1;\n        } else {\n            r = 0;\n        }\n        //logger.debug(i1+' <> '+i2+'  =  '+r);\n        return r;\n    };\n\n    jm.node.inherited = function (pnode, node) {\n        if (!!pnode && !!node) {\n            if (pnode.id === node.id) {\n                return true;\n            }\n            if (pnode.isroot) {\n                return true;\n            }\n            var pid = pnode.id;\n            var p = node;\n            while (!p.isroot) {\n                p = p.parent;\n                if (p.id === pid) {\n                    return true;\n                }\n            }\n        }\n        return false;\n    };\n\n    jm.node.is_node = function (n) {\n        return !!n && n instanceof jm.node;\n    };\n\n    jm.node.prototype = {\n        get_location: function () {\n            var vd = this._data.view;\n            return {\n                x: vd.abs_x,\n                y: vd.abs_y\n            };\n        },\n        get_size: function () {\n            var vd = this._data.view;\n            return {\n                w: vd.width,\n                h: vd.height\n            }\n        }\n    };\n\n\n    jm.mind = function () {\n        this.name = null;\n        this.author = null;\n        this.version = null;\n        this.root = null;\n        this.selected = null;\n        this.nodes = {};\n    };\n\n    jm.mind.prototype = {\n        get_node: function (nodeid) {\n            if (nodeid in this.nodes) {\n                return this.nodes[nodeid];\n            } else {\n                logger.warn('the node[id=' + nodeid + '] can not be found');\n                return null;\n            }\n        },\n\n        set_root: function (nodeid, topic, data) {\n            if (this.root == null) {\n                this.root = new jm.node(nodeid, 0, topic, data, true);\n                this._put_node(this.root);\n                return this.root;\n            } else {\n                logger.error('root node is already exist');\n                return null;\n            }\n        },\n\n        add_node: function (parent_node, nodeid, topic, data, direction, expanded, idx) {\n            if (!jm.util.is_node(parent_node)) {\n                logger.error('the parent_node ' + parent_node + ' is not a node.');\n                return null;\n            }\n            var node_index = idx || -1;\n            var node = new jm.node(nodeid, node_index, topic, data, false, parent_node, parent_node.direction, expanded);\n            if (parent_node.isroot) {\n                node.direction = direction || jm.direction.right;\n            }\n            if (this._put_node(node)) {\n                parent_node.children.push(node);\n                this._reindex(parent_node);\n            } else {\n                logger.error('fail, the nodeid \\'' + node.id + '\\' has been already exist.');\n                node = null;\n            }\n            return node;\n        },\n\n        insert_node_before: function (node_before, nodeid, topic, data, direction) {\n            if (!jm.util.is_node(node_before)) {\n                logger.error('the node_before ' + node_before + ' is not a node.');\n                return null;\n            }\n            var node_index = node_before.index - 0.5;\n            return this.add_node(node_before.parent, nodeid, topic, data, direction, true, node_index);\n        },\n\n        get_node_before: function (node) {\n            if (!jm.util.is_node(node)) {\n                var the_node = this.get_node(node);\n                if (!the_node) {\n                    logger.error('the node[id=' + node + '] can not be found.');\n                    return null;\n                } else {\n                    return this.get_node_before(the_node);\n                }\n            }\n            if (node.isroot) { return null; }\n            var idx = node.index - 2;\n            if (idx >= 0) {\n                return node.parent.children[idx];\n            } else {\n                return null;\n            }\n        },\n\n        insert_node_after: function (node_after, nodeid, topic, data, direction) {\n            if (!jm.util.is_node(node_after)) {\n                logger.error('the node_after ' + node_after + ' is not a node.');\n                return null;\n            }\n            var node_index = node_after.index + 0.5;\n            return this.add_node(node_after.parent, nodeid, topic, data, direction, true, node_index);\n        },\n\n        get_node_after: function (node) {\n            if (!jm.util.is_node(node)) {\n                var the_node = this.get_node(node);\n                if (!the_node) {\n                    logger.error('the node[id=' + node + '] can not be found.');\n                    return null;\n                } else {\n                    return this.get_node_after(the_node);\n                }\n            }\n            if (node.isroot) { return null; }\n            var idx = node.index;\n            var brothers = node.parent.children;\n            if (brothers.length > idx) {\n                return node.parent.children[idx];\n            } else {\n                return null;\n            }\n        },\n\n        move_node: function (node, before_id, parent_id, direction) {\n            if (!jm.util.is_node(node)) {\n                logger.error('the parameter node ' + node + ' is not a node.');\n                return null;\n            }\n            if (!parent_id) {\n                parent_id = node.parent.id;\n            }\n            return this._move_node(node, before_id, parent_id, direction);\n        },\n\n        _flow_node_direction: function (node, direction) {\n            if (typeof direction === 'undefined') {\n                direction = node.direction;\n            } else {\n                node.direction = direction;\n            }\n            var len = node.children.length;\n            while (len--) {\n                this._flow_node_direction(node.children[len], direction);\n            }\n        },\n\n        _move_node_internal: function (node, beforeid) {\n            if (!!node && !!beforeid) {\n                if (beforeid == '_last_') {\n                    node.index = -1;\n                    this._reindex(node.parent);\n                } else if (beforeid == '_first_') {\n                    node.index = 0;\n                    this._reindex(node.parent);\n                } else {\n                    var node_before = (!!beforeid) ? this.get_node(beforeid) : null;\n                    if (node_before != null && node_before.parent != null && node_before.parent.id == node.parent.id) {\n                        node.index = node_before.index - 0.5;\n                        this._reindex(node.parent);\n                    }\n                }\n            }\n            return node;\n        },\n\n        _move_node: function (node, beforeid, parentid, direction) {\n            if (!!node && !!parentid) {\n                var parent_node = this.get_node(parentid)\n                if (jm.node.inherited(node, parent_node)) {\n                    logger.error('can not move a node to its children');\n                    return null;\n                }\n                if (node.parent.id != parentid) {\n                    // remove from parent's children\n                    var sibling = node.parent.children;\n                    var si = sibling.length;\n                    while (si--) {\n                        if (sibling[si].id == node.id) {\n                            sibling.splice(si, 1);\n                            break;\n                        }\n                    }\n                    node.parent = parent_node;\n                    parent_node.children.push(node);\n                }\n\n                if (node.parent.isroot) {\n                    if (direction == jm.direction.left) {\n                        node.direction = direction;\n                    } else {\n                        node.direction = jm.direction.right;\n                    }\n                } else {\n                    node.direction = node.parent.direction;\n                }\n                this._move_node_internal(node, beforeid);\n                this._flow_node_direction(node);\n            }\n            return node;\n        },\n\n        remove_node: function (node) {\n            if (!jm.util.is_node(node)) {\n                logger.error('the parameter node ' + node + ' is not a node.');\n                return false;\n            }\n            if (node.isroot) {\n                logger.error('fail, can not remove root node');\n                return false;\n            }\n            if (this.selected != null && this.selected.id == node.id) {\n                this.selected = null;\n            }\n            // clean all subordinate nodes\n            var children = node.children;\n            var ci = children.length;\n            while (ci--) {\n                this.remove_node(children[ci]);\n            }\n            // clean all children\n            children.length = 0;\n            // remove from parent's children\n            var sibling = node.parent.children;\n            var si = sibling.length;\n            while (si--) {\n                if (sibling[si].id == node.id) {\n                    sibling.splice(si, 1);\n                    break;\n                }\n            }\n            // remove from global nodes\n            delete this.nodes[node.id];\n            // clean all properties\n            for (var k in node) {\n                delete node[k];\n            }\n            // remove it's self\n            node = null;\n            //delete node;\n            return true;\n        },\n\n        _put_node: function (node) {\n            if (node.id in this.nodes) {\n                logger.warn('the nodeid \\'' + node.id + '\\' has been already exist.');\n                return false;\n            } else {\n                this.nodes[node.id] = node;\n                return true;\n            }\n        },\n\n        _reindex: function (node) {\n            if (node instanceof jm.node) {\n                node.children.sort(jm.node.compare);\n                for (var i = 0; i < node.children.length; i++) {\n                    node.children[i].index = i + 1;\n                }\n            }\n        },\n    };\n\n    jm.format = {\n        node_tree: {\n            example: {\n                \"meta\": {\n                    \"name\": __name__,\n                    \"author\": __author__,\n                    \"version\": __version__\n                },\n                \"format\": \"node_tree\",\n                \"data\": { \"id\": \"root\", \"topic\": \"jsMind Example\" }\n            },\n            get_mind: function (source) {\n                var df = jm.format.node_tree;\n                var mind = new jm.mind();\n                mind.name = source.meta.name;\n                mind.author = source.meta.author;\n                mind.version = source.meta.version;\n                df._parse(mind, source.data);\n                return mind;\n            },\n            get_data: function (mind) {\n                var df = jm.format.node_tree;\n                var json = {};\n                json.meta = {\n                    name: mind.name,\n                    author: mind.author,\n                    version: mind.version\n                };\n                json.format = 'node_tree';\n                json.data = df._buildnode(mind.root);\n                return json;\n            },\n\n            _parse: function (mind, node_root) {\n                var df = jm.format.node_tree;\n                var data = df._extract_data(node_root);\n                mind.set_root(node_root.id, node_root.topic, data);\n                if ('children' in node_root) {\n                    var children = node_root.children;\n                    for (var i = 0; i < children.length; i++) {\n                        df._extract_subnode(mind, mind.root, children[i]);\n                    }\n                }\n            },\n\n            _extract_data: function (node_json) {\n                var data = {};\n                for (var k in node_json) {\n                    if (k == 'id' || k == 'topic' || k == 'children' || k == 'direction' || k == 'expanded') {\n                        continue;\n                    }\n                    data[k] = node_json[k];\n                }\n                return data;\n            },\n\n            _extract_subnode: function (mind, node_parent, node_json) {\n                var df = jm.format.node_tree;\n                var data = df._extract_data(node_json);\n                var d = null;\n                if (node_parent.isroot) {\n                    d = node_json.direction == 'left' ? jm.direction.left : jm.direction.right;\n                }\n                var node = mind.add_node(node_parent, node_json.id, node_json.topic, data, d, node_json.expanded);\n                if (!!node_json['children']) {\n                    var children = node_json.children;\n                    for (var i = 0; i < children.length; i++) {\n                        df._extract_subnode(mind, node, children[i]);\n                    }\n                }\n            },\n\n            _buildnode: function (node) {\n                var df = jm.format.node_tree;\n                if (!(node instanceof jm.node)) { return; }\n                var o = {\n                    id: node.id,\n                    topic: node.topic,\n                    expanded: node.expanded\n                };\n                if (!!node.parent && node.parent.isroot) {\n                    o.direction = node.direction == jm.direction.left ? 'left' : 'right';\n                }\n                if (node.data != null) {\n                    var node_data = node.data;\n                    for (var k in node_data) {\n                        o[k] = node_data[k];\n                    }\n                }\n                var children = node.children;\n                if (children.length > 0) {\n                    o.children = [];\n                    for (var i = 0; i < children.length; i++) {\n                        o.children.push(df._buildnode(children[i]));\n                    }\n                }\n                return o;\n            }\n        },\n\n        node_array: {\n            example: {\n                \"meta\": {\n                    \"name\": __name__,\n                    \"author\": __author__,\n                    \"version\": __version__\n                },\n                \"format\": \"node_array\",\n                \"data\": [\n                    { \"id\": \"root\", \"topic\": \"jsMind Example\", \"isroot\": true }\n                ]\n            },\n\n            get_mind: function (source) {\n                var df = jm.format.node_array;\n                var mind = new jm.mind();\n                mind.name = source.meta.name;\n                mind.author = source.meta.author;\n                mind.version = source.meta.version;\n                df._parse(mind, source.data);\n                return mind;\n            },\n\n            get_data: function (mind) {\n                var df = jm.format.node_array;\n                var json = {};\n                json.meta = {\n                    name: mind.name,\n                    author: mind.author,\n                    version: mind.version\n                };\n                json.format = 'node_array';\n                json.data = [];\n                df._array(mind, json.data);\n                return json;\n            },\n\n            _parse: function (mind, node_array) {\n                var df = jm.format.node_array;\n                var narray = node_array.slice(0);\n                // reverse array for improving looping performance\n                narray.reverse();\n                var root_node = df._extract_root(mind, narray);\n                if (!!root_node) {\n                    df._extract_subnode(mind, root_node, narray);\n                } else {\n                    logger.error('root node can not be found');\n                }\n            },\n\n            _extract_root: function (mind, node_array) {\n                var df = jm.format.node_array;\n                var i = node_array.length;\n                while (i--) {\n                    if ('isroot' in node_array[i] && node_array[i].isroot) {\n                        var root_json = node_array[i];\n                        var data = df._extract_data(root_json);\n                        var node = mind.set_root(root_json.id, root_json.topic, data);\n                        node_array.splice(i, 1);\n                        return node;\n                    }\n                }\n                return null;\n            },\n\n            _extract_subnode: function (mind, parent_node, node_array) {\n                var df = jm.format.node_array;\n                var i = node_array.length;\n                var node_json = null;\n                var data = null;\n                var extract_count = 0;\n                while (i--) {\n                    node_json = node_array[i];\n                    if (node_json.parentid == parent_node.id) {\n                        data = df._extract_data(node_json);\n                        var d = null;\n                        var node_direction = node_json.direction;\n                        if (!!node_direction) {\n                            d = node_direction == 'left' ? jm.direction.left : jm.direction.right;\n                        }\n                        var node = mind.add_node(parent_node, node_json.id, node_json.topic, data, d, node_json.expanded);\n                        node_array.splice(i, 1);\n                        extract_count++;\n                        var sub_extract_count = df._extract_subnode(mind, node, node_array);\n                        if (sub_extract_count > 0) {\n                            // reset loop index after extract subordinate node\n                            i = node_array.length;\n                            extract_count += sub_extract_count;\n                        }\n                    }\n                }\n                return extract_count;\n            },\n\n            _extract_data: function (node_json) {\n                var data = {};\n                for (var k in node_json) {\n                    if (k == 'id' || k == 'topic' || k == 'parentid' || k == 'isroot' || k == 'direction' || k == 'expanded') {\n                        continue;\n                    }\n                    data[k] = node_json[k];\n                }\n                return data;\n            },\n\n            _array: function (mind, node_array) {\n                var df = jm.format.node_array;\n                df._array_node(mind.root, node_array);\n            },\n\n            _array_node: function (node, node_array) {\n                var df = jm.format.node_array;\n                if (!(node instanceof jm.node)) { return; }\n                var o = {\n                    id: node.id,\n                    topic: node.topic,\n                    expanded: node.expanded\n                };\n                if (!!node.parent) {\n                    o.parentid = node.parent.id;\n                }\n                if (node.isroot) {\n                    o.isroot = true;\n                }\n                if (!!node.parent && node.parent.isroot) {\n                    o.direction = node.direction == jm.direction.left ? 'left' : 'right';\n                }\n                if (node.data != null) {\n                    var node_data = node.data;\n                    for (var k in node_data) {\n                        o[k] = node_data[k];\n                    }\n                }\n                node_array.push(o);\n                var ci = node.children.length;\n                for (var i = 0; i < ci; i++) {\n                    df._array_node(node.children[i], node_array);\n                }\n            },\n        },\n\n        freemind: {\n            example: {\n                \"meta\": {\n                    \"name\": __name__,\n                    \"author\": __author__,\n                    \"version\": __version__\n                },\n                \"format\": \"freemind\",\n                \"data\": \"<map version=\\\"1.0.1\\\"><node ID=\\\"root\\\" TEXT=\\\"freemind Example\\\"/></map>\"\n            },\n            get_mind: function (source) {\n                var df = jm.format.freemind;\n                var mind = new jm.mind();\n                mind.name = source.meta.name;\n                mind.author = source.meta.author;\n                mind.version = source.meta.version;\n                var xml = source.data;\n                var xml_doc = df._parse_xml(xml);\n                var xml_root = df._find_root(xml_doc);\n                df._load_node(mind, null, xml_root);\n                return mind;\n            },\n\n            get_data: function (mind) {\n                var df = jm.format.freemind;\n                var json = {};\n                json.meta = {\n                    name: mind.name,\n                    author: mind.author,\n                    version: mind.version\n                };\n                json.format = 'freemind';\n                var xmllines = [];\n                xmllines.push('<map version=\\\"1.0.1\\\">');\n                df._buildmap(mind.root, xmllines);\n                xmllines.push('</map>');\n                json.data = xmllines.join(' ');\n                return json;\n            },\n\n            _parse_xml: function (xml) {\n                var xml_doc = null;\n                if (window.DOMParser) {\n                    var parser = new DOMParser();\n                    xml_doc = parser.parseFromString(xml, 'text/xml');\n                } else { // Internet Explorer\n                    xml_doc = new ActiveXObject('Microsoft.XMLDOM');\n                    xml_doc.async = false;\n                    xml_doc.loadXML(xml);\n                }\n                return xml_doc;\n            },\n\n            _find_root: function (xml_doc) {\n                var nodes = xml_doc.childNodes;\n                var node = null;\n                var root = null;\n                var n = null;\n                for (var i = 0; i < nodes.length; i++) {\n                    n = nodes[i];\n                    if (n.nodeType == 1 && n.tagName == 'map') {\n                        node = n;\n                        break;\n                    }\n                }\n                if (!!node) {\n                    var ns = node.childNodes;\n                    node = null;\n                    for (var i = 0; i < ns.length; i++) {\n                        n = ns[i];\n                        if (n.nodeType == 1 && n.tagName == 'node') {\n                            node = n;\n                            break;\n                        }\n                    }\n                }\n                return node;\n            },\n\n            _load_node: function (mind, parent_node, xml_node) {\n                var df = jm.format.freemind;\n                var node_id = xml_node.getAttribute('ID');\n                var node_topic = xml_node.getAttribute('TEXT');\n                // look for richcontent\n                if (node_topic == null) {\n                    var topic_children = xml_node.childNodes;\n                    var topic_child = null;\n                    for (var i = 0; i < topic_children.length; i++) {\n                        topic_child = topic_children[i];\n                        //logger.debug(topic_child.tagName);\n                        if (topic_child.nodeType == 1 && topic_child.tagName === 'richcontent') {\n                            node_topic = topic_child.textContent;\n                            break;\n                        }\n                    }\n                }\n                var node_data = df._load_attributes(xml_node);\n                var node_expanded = ('expanded' in node_data) ? (node_data.expanded == 'true') : true;\n                delete node_data.expanded;\n\n                var node_position = xml_node.getAttribute('POSITION');\n                var node_direction = null;\n                if (!!node_position) {\n                    node_direction = node_position == 'left' ? jm.direction.left : jm.direction.right;\n                }\n                //logger.debug(node_position +':'+ node_direction);\n                var node = null;\n                if (!!parent_node) {\n                    node = mind.add_node(parent_node, node_id, node_topic, node_data, node_direction, node_expanded);\n                } else {\n                    node = mind.set_root(node_id, node_topic, node_data);\n                }\n                var children = xml_node.childNodes;\n                var child = null;\n                for (var i = 0; i < children.length; i++) {\n                    child = children[i];\n                    if (child.nodeType == 1 && child.tagName == 'node') {\n                        df._load_node(mind, node, child);\n                    }\n                }\n            },\n\n            _load_attributes: function (xml_node) {\n                var children = xml_node.childNodes;\n                var attr = null;\n                var attr_data = {};\n                for (var i = 0; i < children.length; i++) {\n                    attr = children[i];\n                    if (attr.nodeType == 1 && attr.tagName === 'attribute') {\n                        attr_data[attr.getAttribute('NAME')] = attr.getAttribute('VALUE');\n                    }\n                }\n                return attr_data;\n            },\n\n            _buildmap: function (node, xmllines) {\n                var df = jm.format.freemind;\n                var pos = null;\n                if (!!node.parent && node.parent.isroot) {\n                    pos = node.direction === jm.direction.left ? 'left' : 'right';\n                }\n                xmllines.push('<node');\n                xmllines.push('ID=\\\"' + node.id + '\\\"');\n                if (!!pos) {\n                    xmllines.push('POSITION=\\\"' + pos + '\\\"');\n                }\n                xmllines.push('TEXT=\\\"' + node.topic + '\\\">');\n\n                // store expanded status as an attribute\n                xmllines.push('<attribute NAME=\\\"expanded\\\" VALUE=\\\"' + node.expanded + '\\\"/>');\n\n                // for attributes\n                var node_data = node.data;\n                if (node_data != null) {\n                    for (var k in node_data) {\n                        xmllines.push('<attribute NAME=\\\"' + k + '\\\" VALUE=\\\"' + node_data[k] + '\\\"/>');\n                    }\n                }\n\n                // for children\n                var children = node.children;\n                for (var i = 0; i < children.length; i++) {\n                    df._buildmap(children[i], xmllines);\n                }\n\n                xmllines.push('</node>');\n            },\n        },\n    };\n\n    // ============= utility object =============================================\n\n    jm.util = {\n        is_node: function (node) {\n            return !!node && node instanceof jm.node;\n        },\n        ajax: {\n            request: function (url, param, method, callback, fail_callback) {\n                var a = jm.util.ajax;\n                var p = null;\n                var tmp_param = [];\n                for (var k in param) {\n                    tmp_param.push(encodeURIComponent(k) + '=' + encodeURIComponent(param[k]));\n                }\n                if (tmp_param.length > 0) {\n                    p = tmp_param.join('&');\n                }\n                var xhr = new XMLHttpRequest();\n                if (!xhr) { return; }\n                xhr.onreadystatechange = function () {\n                    if (xhr.readyState == 4) {\n                        if (xhr.status == 200 || xhr.status == 0) {\n                            if (typeof callback === 'function') {\n                                var data = jm.util.json.string2json(xhr.responseText);\n                                if (data != null) {\n                                    callback(data);\n                                } else {\n                                    callback(xhr.responseText);\n                                }\n                            }\n                        } else {\n                            if (typeof fail_callback === 'function') {\n                                fail_callback(xhr);\n                            } else {\n                                logger.error('xhr request failed.', xhr);\n                            }\n                        }\n                    }\n                }\n                method = method || 'GET';\n                xhr.open(method, url, true);\n                xhr.setRequestHeader('If-Modified-Since', '0');\n                if (method == 'POST') {\n                    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');\n                    xhr.send(p);\n                } else {\n                    xhr.send();\n                }\n            },\n            get: function (url, callback) {\n                return jm.util.ajax.request(url, {}, 'GET', callback);\n            },\n            post: function (url, param, callback) {\n                return jm.util.ajax.request(url, param, 'POST', callback);\n            }\n        },\n\n        dom: {\n            //target,eventType,handler\n            add_event: function (t, e, h) {\n                if (!!t.addEventListener) {\n                    t.addEventListener(e, h, false);\n                } else {\n                    t.attachEvent('on' + e, h);\n                }\n            }\n        },\n\n        file: {\n            read: function (file_data, fn_callback) {\n                var reader = new FileReader();\n                reader.onload = function () {\n                    if (typeof fn_callback === 'function') {\n                        fn_callback(this.result, file_data.name);\n                    }\n                };\n                reader.readAsText(file_data);\n            },\n\n            save: function (file_data, type, name) {\n                var blob;\n                if (typeof $w.Blob === 'function') {\n                    blob = new Blob([file_data], { type: type });\n                } else {\n                    var BlobBuilder = $w.BlobBuilder || $w.MozBlobBuilder || $w.WebKitBlobBuilder || $w.MSBlobBuilder;\n                    var bb = new BlobBuilder();\n                    bb.append(file_data);\n                    blob = bb.getBlob(type);\n                }\n                if (navigator.msSaveBlob) {\n                    navigator.msSaveBlob(blob, name);\n                } else {\n                    var URL = $w.URL || $w.webkitURL;\n                    var bloburl = URL.createObjectURL(blob);\n                    var anchor = $c('a');\n                    if ('download' in anchor) {\n                        anchor.style.visibility = 'hidden';\n                        anchor.href = bloburl;\n                        anchor.download = name;\n                        $d.body.appendChild(anchor);\n                        var evt = $d.createEvent('MouseEvents');\n                        evt.initEvent('click', true, true);\n                        anchor.dispatchEvent(evt);\n                        $d.body.removeChild(anchor);\n                    } else {\n                        location.href = bloburl;\n                    }\n                }\n            }\n        },\n\n        json: {\n            json2string: function (json) {\n                return JSON.stringify(json);\n            },\n            string2json: function (json_str) {\n                return JSON.parse(json_str);\n            },\n            merge: function (b, a) {\n                for (var o in a) {\n                    if (o in b) {\n                        if (typeof b[o] === 'object' &&\n                            Object.prototype.toString.call(b[o]).toLowerCase() == '[object object]' &&\n                            !b[o].length) {\n                            jm.util.json.merge(b[o], a[o]);\n                        } else {\n                            b[o] = a[o];\n                        }\n                    } else {\n                        b[o] = a[o];\n                    }\n                }\n                return b;\n            }\n        },\n\n        uuid: {\n            newid: function () {\n                return (new Date().getTime().toString(16) + Math.random().toString(16).substring(2)).substring(2, 18);\n            }\n        },\n\n        text: {\n            is_empty: function (s) {\n                if (!s) { return true; }\n                return s.replace(/\\s*/, '').length == 0;\n            }\n        }\n    };\n\n    jm.prototype = {\n        init: function () {\n            if (this.initialized) { return; }\n            this.initialized = true;\n\n            var opts = this.options;\n\n            var opts_layout = {\n                mode: opts.mode,\n                hspace: opts.layout.hspace,\n                vspace: opts.layout.vspace,\n                pspace: opts.layout.pspace\n            }\n            var opts_view = {\n                container: opts.container,\n                support_html: opts.support_html,\n                engine: opts.view.engine,\n                hmargin: opts.view.hmargin,\n                vmargin: opts.view.vmargin,\n                line_width: opts.view.line_width,\n                line_color: opts.view.line_color,\n                draggable: opts.view.draggable,\n                hide_scrollbars_when_draggable: opts.view.hide_scrollbars_when_draggable,\n                node_overflow: opts.view.node_overflow\n            };\n            // create instance of function provider\n            this.data = new jm.data_provider(this);\n            this.layout = new jm.layout_provider(this, opts_layout);\n            this.view = new jm.view_provider(this, opts_view);\n            this.shortcut = new jm.shortcut_provider(this, opts.shortcut);\n\n            this.data.init();\n            this.layout.init();\n            this.view.init();\n            this.shortcut.init();\n\n            this._event_bind();\n\n            jm.init_plugins(this);\n        },\n\n        enable_edit: function () {\n            this.options.editable = true;\n        },\n\n        disable_edit: function () {\n            this.options.editable = false;\n        },\n\n        // call enable_event_handle('dblclick')\n        // options are 'mousedown', 'click', 'dblclick'\n        enable_event_handle: function (event_handle) {\n            this.options.default_event_handle['enable_' + event_handle + '_handle'] = true;\n        },\n\n        // call disable_event_handle('dblclick')\n        // options are 'mousedown', 'click', 'dblclick'\n        disable_event_handle: function (event_handle) {\n            this.options.default_event_handle['enable_' + event_handle + '_handle'] = false;\n        },\n\n        get_editable: function () {\n            return this.options.editable;\n        },\n\n        set_theme: function (theme) {\n            var theme_old = this.options.theme;\n            this.options.theme = (!!theme) ? theme : null;\n            if (theme_old != this.options.theme) {\n                this.view.reset_theme();\n                this.view.reset_custom_style();\n            }\n        },\n        _event_bind: function () {\n            this.view.add_event(this, 'mousedown', this.mousedown_handle);\n            this.view.add_event(this, 'click', this.click_handle);\n            this.view.add_event(this, 'dblclick', this.dblclick_handle);\n            this.view.add_event(this, \"mousewheel\", this.mousewheel_handle)\n        },\n\n        mousedown_handle: function (e) {\n            if (!this.options.default_event_handle['enable_mousedown_handle']) {\n                return;\n            }\n            var element = e.target || event.srcElement;\n            var nodeid = this.view.get_binded_nodeid(element);\n            if (!!nodeid) {\n                if (element.tagName.toLowerCase() == 'jmnode') {\n                    this.select_node(nodeid);\n                }\n            } else {\n                this.select_clear();\n            }\n        },\n\n        click_handle: function (e) {\n            if (!this.options.default_event_handle['enable_click_handle']) {\n                return;\n            }\n            var element = e.target || event.srcElement;\n            var isexpander = this.view.is_expander(element);\n            if (isexpander) {\n                var nodeid = this.view.get_binded_nodeid(element);\n                if (!!nodeid) {\n                    this.toggle_node(nodeid);\n                }\n            }\n        },\n\n        dblclick_handle: function (e) {\n            if (!this.options.default_event_handle['enable_dblclick_handle']) {\n                return;\n            }\n            if (this.get_editable()) {\n                var element = e.target || event.srcElement;\n                var nodeid = this.view.get_binded_nodeid(element);\n                if (!!nodeid) {\n                    this.begin_edit(nodeid);\n                }\n            }\n        },\n\n        // Use [Ctrl] + Mousewheel, to zoom in/out.\n        mousewheel_handle: function (event) {\n            // Test if mousewheel option is enabled and Ctrl key is pressed.\n            if (!this.options.default_event_handle[\"enable_mousewheel_handle\"] || !window.event.ctrlKey) {\n                return\n            }\n            // Avoid default page scrolling behavior.\n            event.preventDefault()\n\n            if (event.deltaY < 0) {\n                this.view.zoomIn()\n            } else {\n                this.view.zoomOut()\n            }\n        },\n\n        begin_edit: function (node) {\n            if (!jm.util.is_node(node)) {\n                var the_node = this.get_node(node);\n                if (!the_node) {\n                    logger.error('the node[id=' + node + '] can not be found.');\n                    return false;\n                } else {\n                    return this.begin_edit(the_node);\n                }\n            }\n            if (this.get_editable()) {\n                this.view.edit_node_begin(node);\n            } else {\n                logger.error('fail, this mind map is not editable.');\n                return;\n            }\n        },\n\n        end_edit: function () {\n            this.view.edit_node_end();\n        },\n\n        toggle_node: function (node) {\n            if (!jm.util.is_node(node)) {\n                var the_node = this.get_node(node);\n                if (!the_node) {\n                    logger.error('the node[id=' + node + '] can not be found.');\n                    return;\n                } else {\n                    return this.toggle_node(the_node);\n                }\n            }\n            if (node.isroot) { return; }\n            this.view.save_location(node);\n            this.layout.toggle_node(node);\n            this.view.relayout();\n            this.view.restore_location(node);\n        },\n\n        expand_node: function (node) {\n            if (!jm.util.is_node(node)) {\n                var the_node = this.get_node(node);\n                if (!the_node) {\n                    logger.error('the node[id=' + node + '] can not be found.');\n                    return;\n                } else {\n                    return this.expand_node(the_node);\n                }\n            }\n            if (node.isroot) { return; }\n            this.view.save_location(node);\n            this.layout.expand_node(node);\n            this.view.relayout();\n            this.view.restore_location(node);\n        },\n\n        collapse_node: function (node) {\n            if (!jm.util.is_node(node)) {\n                var the_node = this.get_node(node);\n                if (!the_node) {\n                    logger.error('the node[id=' + node + '] can not be found.');\n                    return;\n                } else {\n                    return this.collapse_node(the_node);\n                }\n            }\n            if (node.isroot) { return; }\n            this.view.save_location(node);\n            this.layout.collapse_node(node);\n            this.view.relayout();\n            this.view.restore_location(node);\n        },\n\n        expand_all: function () {\n            this.layout.expand_all();\n            this.view.relayout();\n        },\n\n        collapse_all: function () {\n            this.layout.collapse_all();\n            this.view.relayout();\n        },\n\n        expand_to_depth: function (depth) {\n            this.layout.expand_to_depth(depth);\n            this.view.relayout();\n        },\n\n        _reset: function () {\n            this.view.reset();\n            this.layout.reset();\n            this.data.reset();\n        },\n\n        _show: function (mind) {\n            var m = mind || jm.format.node_array.example;\n\n            this.mind = this.data.load(m);\n            if (!this.mind) {\n                logger.error('data.load error');\n                return;\n            } else {\n                logger.debug('data.load ok');\n            }\n\n            this.view.load();\n            logger.debug('view.load ok');\n\n            this.layout.layout();\n            logger.debug('layout.layout ok');\n\n            this.view.show(true);\n            logger.debug('view.show ok');\n\n            this.invoke_event_handle(jm.event_type.show, { data: [mind] });\n        },\n\n        show: function (mind) {\n            this._reset();\n            this._show(mind);\n        },\n\n        get_meta: function () {\n            return {\n                name: this.mind.name,\n                author: this.mind.author,\n                version: this.mind.version\n            };\n        },\n\n        get_data: function (data_format) {\n            var df = data_format || 'node_tree';\n            return this.data.get_data(df);\n        },\n\n        get_root: function () {\n            return this.mind.root;\n        },\n\n        get_node: function (node) {\n            if (jm.util.is_node(node)) {\n                return node;\n            }\n            return this.mind.get_node(node);\n        },\n\n        add_node: function (parent_node, nodeid, topic, data, direction) {\n            if (this.get_editable()) {\n                var the_parent_node = this.get_node(parent_node);\n                var dir = jm.direction.of(direction)\n                if (dir === undefined) {\n                    dir = this.layout.calculate_next_child_direction(the_parent_node);\n                }\n                var node = this.mind.add_node(the_parent_node, nodeid, topic, data, dir);\n                if (!!node) {\n                    this.view.add_node(node);\n                    this.layout.layout();\n                    this.view.show(false);\n                    this.view.reset_node_custom_style(node);\n                    this.expand_node(the_parent_node);\n                    this.invoke_event_handle(jm.event_type.edit, { evt: 'add_node', data: [the_parent_node.id, nodeid, topic, data, dir], node: nodeid });\n                }\n                return node;\n            } else {\n                logger.error('fail, this mind map is not editable');\n                return null;\n            }\n        },\n\n        insert_node_before: function (node_before, nodeid, topic, data, direction) {\n            if (this.get_editable()) {\n                var the_node_before = this.get_node(node_before);\n                var dir = jm.direction.of(direction)\n                if (dir === undefined) {\n                    dir = this.layout.calculate_next_child_direction(the_node_before.parent);\n                }\n                var node = this.mind.insert_node_before(the_node_before, nodeid, topic, data, dir);\n                if (!!node) {\n                    this.view.add_node(node);\n                    this.layout.layout();\n                    this.view.show(false);\n                    this.invoke_event_handle(jm.event_type.edit, { evt: 'insert_node_before', data: [the_node_before.id, nodeid, topic, data, dir], node: nodeid });\n                }\n                return node;\n            } else {\n                logger.error('fail, this mind map is not editable');\n                return null;\n            }\n        },\n\n        insert_node_after: function (node_after, nodeid, topic, data, direction) {\n            if (this.get_editable()) {\n                var the_node_after = this.get_node(node_after);\n                var dir = jm.direction.of(direction)\n                if (dir === undefined) {\n                    dir = this.layout.calculate_next_child_direction(the_node_after.parent);\n                }\n                var node = this.mind.insert_node_after(the_node_after, nodeid, topic, data, dir);\n                if (!!node) {\n                    this.view.add_node(node);\n                    this.layout.layout();\n                    this.view.show(false);\n                    this.invoke_event_handle(jm.event_type.edit, { evt: 'insert_node_after', data: [the_node_after.id, nodeid, topic, data, dir], node: nodeid });\n                }\n                return node;\n            } else {\n                logger.error('fail, this mind map is not editable');\n                return null;\n            }\n        },\n\n        remove_node: function (node) {\n            if (!jm.util.is_node(node)) {\n                var the_node = this.get_node(node);\n                if (!the_node) {\n                    logger.error('the node[id=' + node + '] can not be found.');\n                    return false;\n                } else {\n                    return this.remove_node(the_node);\n                }\n            }\n            if (this.get_editable()) {\n                if (node.isroot) {\n                    logger.error('fail, can not remove root node');\n                    return false;\n                }\n                var nodeid = node.id;\n                var parentid = node.parent.id;\n                var parent_node = this.get_node(parentid);\n                this.view.save_location(parent_node);\n                this.view.remove_node(node);\n                this.mind.remove_node(node);\n                this.layout.layout();\n                this.view.show(false);\n                this.view.restore_location(parent_node);\n                this.invoke_event_handle(jm.event_type.edit, { evt: 'remove_node', data: [nodeid], node: parentid });\n                return true;\n            } else {\n                logger.error('fail, this mind map is not editable');\n                return false;\n            }\n        },\n\n        update_node: function (nodeid, topic) {\n            if (this.get_editable()) {\n                if (jm.util.text.is_empty(topic)) {\n                    logger.warn('fail, topic can not be empty');\n                    return;\n                }\n                var node = this.get_node(nodeid);\n                if (!!node) {\n                    if (node.topic === topic) {\n                        logger.info('nothing changed');\n                        this.view.update_node(node);\n                        return;\n                    }\n                    node.topic = topic;\n                    this.view.update_node(node);\n                    this.layout.layout();\n                    this.view.show(false);\n                    this.invoke_event_handle(jm.event_type.edit, { evt: 'update_node', data: [nodeid, topic], node: nodeid });\n                }\n            } else {\n                logger.error('fail, this mind map is not editable');\n                return;\n            }\n        },\n\n        move_node: function (nodeid, beforeid, parentid, direction) {\n            if (this.get_editable()) {\n                var node = this.get_node(nodeid);\n                var updated_node = this.mind.move_node(node, beforeid, parentid, direction);\n                if (!!updated_node) {\n                    this.view.update_node(updated_node);\n                    this.layout.layout();\n                    this.view.show(false);\n                    this.invoke_event_handle(jm.event_type.edit, { evt: 'move_node', data: [nodeid, beforeid, parentid, direction], node: nodeid });\n                }\n            } else {\n                logger.error('fail, this mind map is not editable');\n                return;\n            }\n        },\n\n        select_node: function (node) {\n            if (!jm.util.is_node(node)) {\n                var the_node = this.get_node(node);\n                if (!the_node) {\n                    logger.error('the node[id=' + node + '] can not be found.');\n                    return;\n                } else {\n                    return this.select_node(the_node);\n                }\n            }\n            if (!this.layout.is_visible(node)) {\n                return;\n            }\n            this.mind.selected = node;\n            this.view.select_node(node);\n            this.invoke_event_handle(jm.event_type.select, { evt: 'select_node', data: [], node: node.id });\n        },\n\n        get_selected_node: function () {\n            if (!!this.mind) {\n                return this.mind.selected;\n            } else {\n                return null;\n            }\n        },\n\n        select_clear: function () {\n            if (!!this.mind) {\n                this.mind.selected = null;\n                this.view.select_clear();\n            }\n        },\n\n        is_node_visible: function (node) {\n            return this.layout.is_visible(node);\n        },\n\n        find_node_before: function (node) {\n            if (!jm.util.is_node(node)) {\n                var the_node = this.get_node(node);\n                if (!the_node) {\n                    logger.error('the node[id=' + node + '] can not be found.');\n                    return;\n                } else {\n                    return this.find_node_before(the_node);\n                }\n            }\n            if (node.isroot) { return null; }\n            var n = null;\n            if (node.parent.isroot) {\n                var c = node.parent.children;\n                var prev = null;\n                var ni = null;\n                for (var i = 0; i < c.length; i++) {\n                    ni = c[i];\n                    if (node.direction === ni.direction) {\n                        if (node.id === ni.id) {\n                            n = prev;\n                        }\n                        prev = ni;\n                    }\n                }\n            } else {\n                n = this.mind.get_node_before(node);\n            }\n            return n;\n        },\n\n        find_node_after: function (node) {\n            if (!jm.util.is_node(node)) {\n                var the_node = this.get_node(node);\n                if (!the_node) {\n                    logger.error('the node[id=' + node + '] can not be found.');\n                    return;\n                } else {\n                    return this.find_node_after(the_node);\n                }\n            }\n            if (node.isroot) { return null; }\n            var n = null;\n            if (node.parent.isroot) {\n                var c = node.parent.children;\n                var getthis = false;\n                var ni = null;\n                for (var i = 0; i < c.length; i++) {\n                    ni = c[i];\n                    if (node.direction === ni.direction) {\n                        if (getthis) {\n                            n = ni;\n                            break;\n                        }\n                        if (node.id === ni.id) {\n                            getthis = true;\n                        }\n                    }\n                }\n            } else {\n                n = this.mind.get_node_after(node);\n            }\n            return n;\n        },\n\n        set_node_color: function (nodeid, bgcolor, fgcolor) {\n            if (this.get_editable()) {\n                var node = this.mind.get_node(nodeid);\n                if (!!node) {\n                    if (!!bgcolor) {\n                        node.data['background-color'] = bgcolor;\n                    }\n                    if (!!fgcolor) {\n                        node.data['foreground-color'] = fgcolor;\n                    }\n                    this.view.reset_node_custom_style(node);\n                }\n            } else {\n                logger.error('fail, this mind map is not editable');\n                return null;\n            }\n        },\n\n        set_node_font_style: function (nodeid, size, weight, style) {\n            if (this.get_editable()) {\n                var node = this.mind.get_node(nodeid);\n                if (!!node) {\n                    if (!!size) {\n                        node.data['font-size'] = size;\n                    }\n                    if (!!weight) {\n                        node.data['font-weight'] = weight;\n                    }\n                    if (!!style) {\n                        node.data['font-style'] = style;\n                    }\n                    this.view.reset_node_custom_style(node);\n                    this.view.update_node(node);\n                    this.layout.layout();\n                    this.view.show(false);\n                }\n            } else {\n                logger.error('fail, this mind map is not editable');\n                return null;\n            }\n        },\n\n        set_node_background_image: function (nodeid, image, width, height, rotation) {\n            if (this.get_editable()) {\n                var node = this.mind.get_node(nodeid);\n                if (!!node) {\n                    if (!!image) {\n                        node.data['background-image'] = image;\n                    }\n                    if (!!width) {\n                        node.data['width'] = width;\n                    }\n                    if (!!height) {\n                        node.data['height'] = height;\n                    }\n                    if (!!rotation) {\n                        node.data['background-rotation'] = rotation;\n                    }\n                    this.view.reset_node_custom_style(node);\n                    this.view.update_node(node);\n                    this.layout.layout();\n                    this.view.show(false);\n                }\n            } else {\n                logger.error('fail, this mind map is not editable');\n                return null;\n            }\n        },\n\n        set_node_background_rotation: function (nodeid, rotation) {\n            if (this.get_editable()) {\n                var node = this.mind.get_node(nodeid);\n                if (!!node) {\n                    if (!node.data['background-image']) {\n                        logger.error('fail, only can change rotation angle of node with background image');\n                        return null;\n                    }\n                    node.data['background-rotation'] = rotation;\n                    this.view.reset_node_custom_style(node);\n                    this.view.update_node(node);\n                    this.layout.layout();\n                    this.view.show(false);\n                }\n            } else {\n                logger.error('fail, this mind map is not editable');\n                return null;\n            }\n        },\n\n        resize: function () {\n            this.view.resize();\n        },\n\n        // callback(type ,data)\n        add_event_listener: function (callback) {\n            if (typeof callback === 'function') {\n                this.event_handles.push(callback);\n            }\n        },\n\n        clear_event_listener: function () {\n            this.event_handles = [];\n        },\n\n        invoke_event_handle: function (type, data) {\n            var j = this;\n            $w.setTimeout(function () {\n                j._invoke_event_handle(type, data);\n            }, 0);\n        },\n\n        _invoke_event_handle: function (type, data) {\n            var l = this.event_handles.length;\n            for (var i = 0; i < l; i++) {\n                this.event_handles[i](type, data);\n            }\n        },\n\n    };\n\n    // ============= data provider =============================================\n\n    jm.data_provider = function (jm) {\n        this.jm = jm;\n    };\n\n    jm.data_provider.prototype = {\n        init: function () {\n            logger.debug('data.init');\n        },\n\n        reset: function () {\n            logger.debug('data.reset');\n        },\n\n        load: function (mind_data) {\n            var df = null;\n            var mind = null;\n            if (typeof mind_data === 'object') {\n                if (!!mind_data.format) {\n                    df = mind_data.format;\n                } else {\n                    df = 'node_tree';\n                }\n            } else {\n                df = 'freemind';\n            }\n\n            if (df == 'node_array') {\n                mind = jm.format.node_array.get_mind(mind_data);\n            } else if (df == 'node_tree') {\n                mind = jm.format.node_tree.get_mind(mind_data);\n            } else if (df == 'freemind') {\n                mind = jm.format.freemind.get_mind(mind_data);\n            } else {\n                logger.warn('unsupported format');\n            }\n            return mind;\n        },\n\n        get_data: function (data_format) {\n            var data = null;\n            if (data_format == 'node_array') {\n                data = jm.format.node_array.get_data(this.jm.mind);\n            } else if (data_format == 'node_tree') {\n                data = jm.format.node_tree.get_data(this.jm.mind);\n            } else if (data_format == 'freemind') {\n                data = jm.format.freemind.get_data(this.jm.mind);\n            } else {\n                logger.error('unsupported ' + data_format + ' format');\n            }\n            return data;\n        },\n    };\n\n    // ============= layout provider ===========================================\n\n    jm.layout_provider = function (jm, options) {\n        this.opts = options;\n        this.jm = jm;\n        this.isside = (this.opts.mode == 'side');\n        this.bounds = null;\n\n        this.cache_valid = false;\n    };\n\n    jm.layout_provider.prototype = {\n        init: function () {\n            logger.debug('layout.init');\n        },\n\n        reset: function () {\n            logger.debug('layout.reset');\n            this.bounds = { n: 0, s: 0, w: 0, e: 0 };\n        },\n\n        calculate_next_child_direction: function (node) {\n            if (this.isside) {\n                return jm.direction.right;\n            }\n            var children = node.children || [];\n            var children_len = children.length;\n            var r = 0;\n            for (var i = 0; i < children_len; i++) { if (children[i].direction === jm.direction.left) { r--; } else { r++; } }\n            return (children_len > 1 && r > 0) ? jm.direction.left : jm.direction.right;\n        },\n\n        layout: function () {\n            logger.debug('layout.layout');\n            this.layout_direction();\n            this.layout_offset();\n        },\n\n        layout_direction: function () {\n            this._layout_direction_root();\n        },\n\n        _layout_direction_root: function () {\n            var node = this.jm.mind.root;\n            // logger.debug(node);\n            var layout_data = null;\n            if ('layout' in node._data) {\n                layout_data = node._data.layout;\n            } else {\n                layout_data = {};\n                node._data.layout = layout_data;\n            }\n            var children = node.children;\n            var children_count = children.length;\n            layout_data.direction = jm.direction.center;\n            layout_data.side_index = 0;\n            if (this.isside) {\n                var i = children_count;\n                while (i--) {\n                    this._layout_direction_side(children[i], jm.direction.right, i);\n                }\n            } else {\n                var i = children_count;\n                var subnode = null;\n                while (i--) {\n                    subnode = children[i];\n                    if (subnode.direction == jm.direction.left) {\n                        this._layout_direction_side(subnode, jm.direction.left, i);\n                    } else {\n                        this._layout_direction_side(subnode, jm.direction.right, i);\n                    }\n                }\n                /*\n                var boundary = Math.ceil(children_count/2);\n                var i = children_count;\n                while(i--){\n                    if(i>=boundary){\n                        this._layout_direction_side(children[i],jm.direction.left, children_count-i-1);\n                    }else{\n                        this._layout_direction_side(children[i],jm.direction.right, i);\n                    }\n                }*/\n\n            }\n        },\n\n        _layout_direction_side: function (node, direction, side_index) {\n            var layout_data = null;\n            if ('layout' in node._data) {\n                layout_data = node._data.layout;\n            } else {\n                layout_data = {};\n                node._data.layout = layout_data;\n            }\n            var children = node.children;\n            var children_count = children.length;\n\n            layout_data.direction = direction;\n            layout_data.side_index = side_index;\n            var i = children_count;\n            while (i--) {\n                this._layout_direction_side(children[i], direction, i);\n            }\n        },\n\n        layout_offset: function () {\n            var node = this.jm.mind.root;\n            var layout_data = node._data.layout;\n            layout_data.offset_x = 0;\n            layout_data.offset_y = 0;\n            layout_data.outer_height = 0;\n            var children = node.children;\n            var i = children.length;\n            var left_nodes = [];\n            var right_nodes = [];\n            var subnode = null;\n            while (i--) {\n                subnode = children[i];\n                if (subnode._data.layout.direction == jm.direction.right) {\n                    right_nodes.unshift(subnode);\n                } else {\n                    left_nodes.unshift(subnode);\n                }\n            }\n            layout_data.left_nodes = left_nodes;\n            layout_data.right_nodes = right_nodes;\n            layout_data.outer_height_left = this._layout_offset_subnodes(left_nodes);\n            layout_data.outer_height_right = this._layout_offset_subnodes(right_nodes);\n            this.bounds.e = node._data.view.width / 2;\n            this.bounds.w = 0 - this.bounds.e;\n            //logger.debug(this.bounds.w);\n            this.bounds.n = 0;\n            this.bounds.s = Math.max(layout_data.outer_height_left, layout_data.outer_height_right);\n        },\n\n        // layout both the x and y axis\n        _layout_offset_subnodes: function (nodes) {\n            var total_height = 0;\n            var nodes_count = nodes.length;\n            var i = nodes_count;\n            var node = null;\n            var node_outer_height = 0;\n            var layout_data = null;\n            var base_y = 0;\n            var pd = null; // parent._data\n            while (i--) {\n                node = nodes[i];\n                layout_data = node._data.layout;\n                if (pd == null) {\n                    pd = node.parent._data;\n                }\n\n                node_outer_height = this._layout_offset_subnodes(node.children);\n                if (!node.expanded) {\n                    node_outer_height = 0;\n                    this.set_visible(node.children, false);\n                }\n                node_outer_height = Math.max(node._data.view.height, node_outer_height);\n\n                layout_data.outer_height = node_outer_height;\n                layout_data.offset_y = base_y - node_outer_height / 2;\n                layout_data.offset_x = this.opts.hspace * layout_data.direction + pd.view.width * (pd.layout.direction + layout_data.direction) / 2;\n                if (!node.parent.isroot) {\n                    layout_data.offset_x += this.opts.pspace * layout_data.direction;\n                }\n\n                base_y = base_y - node_outer_height - this.opts.vspace;\n                total_height += node_outer_height;\n            }\n            if (nodes_count > 1) {\n                total_height += this.opts.vspace * (nodes_count - 1);\n            }\n            i = nodes_count;\n            var middle_height = total_height / 2;\n            while (i--) {\n                node = nodes[i];\n                node._data.layout.offset_y += middle_height;\n            }\n            return total_height;\n        },\n\n        // layout the y axis only, for collapse/expand a node\n        _layout_offset_subnodes_height: function (nodes) {\n            var total_height = 0;\n            var nodes_count = nodes.length;\n            var i = nodes_count;\n            var node = null;\n            var node_outer_height = 0;\n            var layout_data = null;\n            var base_y = 0;\n            var pd = null; // parent._data\n            while (i--) {\n                node = nodes[i];\n                layout_data = node._data.layout;\n                if (pd == null) {\n                    pd = node.parent._data;\n                }\n\n                node_outer_height = this._layout_offset_subnodes_height(node.children);\n                if (!node.expanded) {\n                    node_outer_height = 0;\n                }\n                node_outer_height = Math.max(node._data.view.height, node_outer_height);\n\n                layout_data.outer_height = node_outer_height;\n                layout_data.offset_y = base_y - node_outer_height / 2;\n                base_y = base_y - node_outer_height - this.opts.vspace;\n                total_height += node_outer_height;\n            }\n            if (nodes_count > 1) {\n                total_height += this.opts.vspace * (nodes_count - 1);\n            }\n            i = nodes_count;\n            var middle_height = total_height / 2;\n            while (i--) {\n                node = nodes[i];\n                node._data.layout.offset_y += middle_height;\n                //logger.debug(node.topic);\n                //logger.debug(node._data.layout.offset_y);\n            }\n            return total_height;\n        },\n\n        get_node_offset: function (node) {\n            var layout_data = node._data.layout;\n            var offset_cache = null;\n            if (('_offset_' in layout_data) && this.cache_valid) {\n                offset_cache = layout_data._offset_;\n            } else {\n                offset_cache = { x: -1, y: -1 };\n                layout_data._offset_ = offset_cache;\n            }\n            if (offset_cache.x == -1 || offset_cache.y == -1) {\n                var x = layout_data.offset_x;\n                var y = layout_data.offset_y;\n                if (!node.isroot) {\n                    var offset_p = this.get_node_offset(node.parent);\n                    x += offset_p.x;\n                    y += offset_p.y;\n                }\n                offset_cache.x = x;\n                offset_cache.y = y;\n            }\n            return offset_cache;\n        },\n\n        get_node_point: function (node) {\n            var view_data = node._data.view;\n            var offset_p = this.get_node_offset(node);\n            //logger.debug(offset_p);\n            var p = {};\n            p.x = offset_p.x + view_data.width * (node._data.layout.direction - 1) / 2;\n            p.y = offset_p.y - view_data.height / 2;\n            //logger.debug(p);\n            return p;\n        },\n\n        get_node_point_in: function (node) {\n            var p = this.get_node_offset(node);\n            return p;\n        },\n\n        get_node_point_out: function (node) {\n            var layout_data = node._data.layout;\n            var pout_cache = null;\n            if (('_pout_' in layout_data) && this.cache_valid) {\n                pout_cache = layout_data._pout_;\n            } else {\n                pout_cache = { x: -1, y: -1 };\n                layout_data._pout_ = pout_cache;\n            }\n            if (pout_cache.x == -1 || pout_cache.y == -1) {\n                if (node.isroot) {\n                    pout_cache.x = 0;\n                    pout_cache.y = 0;\n                } else {\n                    var view_data = node._data.view;\n                    var offset_p = this.get_node_offset(node);\n                    pout_cache.x = offset_p.x + (view_data.width + this.opts.pspace) * node._data.layout.direction;\n                    pout_cache.y = offset_p.y;\n                    //logger.debug('pout');\n                    //logger.debug(pout_cache);\n                }\n            }\n            return pout_cache;\n        },\n\n        get_expander_point: function (node) {\n            var p = this.get_node_point_out(node);\n            var ex_p = {};\n            if (node._data.layout.direction == jm.direction.right) {\n                ex_p.x = p.x - this.opts.pspace;\n            } else {\n                ex_p.x = p.x;\n            }\n            ex_p.y = p.y - Math.ceil(this.opts.pspace / 2);\n            return ex_p;\n        },\n\n        get_min_size: function () {\n            var nodes = this.jm.mind.nodes;\n            var node = null;\n            var pout = null;\n            for (var nodeid in nodes) {\n                node = nodes[nodeid];\n                pout = this.get_node_point_out(node);\n                if (pout.x > this.bounds.e) { this.bounds.e = pout.x; }\n                if (pout.x < this.bounds.w) { this.bounds.w = pout.x; }\n            }\n            return {\n                w: this.bounds.e - this.bounds.w,\n                h: this.bounds.s - this.bounds.n\n            }\n        },\n\n        toggle_node: function (node) {\n            if (node.isroot) {\n                return;\n            }\n            if (node.expanded) {\n                this.collapse_node(node);\n            } else {\n                this.expand_node(node);\n            }\n        },\n\n        expand_node: function (node) {\n            node.expanded = true;\n            this.part_layout(node);\n            this.set_visible(node.children, true);\n            this.jm.invoke_event_handle(jm.event_type.show, { evt: 'expand_node', data: [], node: node.id });\n        },\n\n        collapse_node: function (node) {\n            node.expanded = false;\n            this.part_layout(node);\n            this.set_visible(node.children, false);\n            this.jm.invoke_event_handle(jm.event_type.show, { evt: 'collapse_node', data: [], node: node.id });\n        },\n\n        expand_all: function () {\n            var nodes = this.jm.mind.nodes;\n            var c = 0;\n            var node;\n            for (var nodeid in nodes) {\n                node = nodes[nodeid];\n                if (!node.expanded) {\n                    node.expanded = true;\n                    c++;\n                }\n            }\n            if (c > 0) {\n                var root = this.jm.mind.root;\n                this.part_layout(root);\n                this.set_visible(root.children, true);\n            }\n        },\n\n        collapse_all: function () {\n            var nodes = this.jm.mind.nodes;\n            var c = 0;\n            var node;\n            for (var nodeid in nodes) {\n                node = nodes[nodeid];\n                if (node.expanded && !node.isroot) {\n                    node.expanded = false;\n                    c++;\n                }\n            }\n            if (c > 0) {\n                var root = this.jm.mind.root;\n                this.part_layout(root);\n                this.set_visible(root.children, true);\n            }\n        },\n\n        expand_to_depth: function (target_depth, curr_nodes, curr_depth) {\n            if (target_depth < 1) { return; }\n            var nodes = curr_nodes || this.jm.mind.root.children;\n            var depth = curr_depth || 1;\n            var i = nodes.length;\n            var node = null;\n            while (i--) {\n                node = nodes[i];\n                if (depth < target_depth) {\n                    if (!node.expanded) {\n                        this.expand_node(node);\n                    }\n                    this.expand_to_depth(target_depth, node.children, depth + 1);\n                }\n                if (depth == target_depth) {\n                    if (node.expanded) {\n                        this.collapse_node(node);\n                    }\n                }\n            }\n        },\n\n        part_layout: function (node) {\n            var root = this.jm.mind.root;\n            if (!!root) {\n                var root_layout_data = root._data.layout;\n                if (node.isroot) {\n                    root_layout_data.outer_height_right = this._layout_offset_subnodes_height(root_layout_data.right_nodes);\n                    root_layout_data.outer_height_left = this._layout_offset_subnodes_height(root_layout_data.left_nodes);\n                } else {\n                    if (node._data.layout.direction == jm.direction.right) {\n                        root_layout_data.outer_height_right = this._layout_offset_subnodes_height(root_layout_data.right_nodes);\n                    } else {\n                        root_layout_data.outer_height_left = this._layout_offset_subnodes_height(root_layout_data.left_nodes);\n                    }\n                }\n                this.bounds.s = Math.max(root_layout_data.outer_height_left, root_layout_data.outer_height_right);\n                this.cache_valid = false;\n            } else {\n                logger.warn('can not found root node');\n            }\n        },\n\n        set_visible: function (nodes, visible) {\n            var i = nodes.length;\n            var node = null;\n            var layout_data = null;\n            while (i--) {\n                node = nodes[i];\n                layout_data = node._data.layout;\n                if (node.expanded) {\n                    this.set_visible(node.children, visible);\n                } else {\n                    this.set_visible(node.children, false);\n                }\n                if (!node.isroot) {\n                    node._data.layout.visible = visible;\n                }\n            }\n        },\n\n        is_expand: function (node) {\n            return node.expanded;\n        },\n\n        is_visible: function (node) {\n            var layout_data = node._data.layout;\n            if (('visible' in layout_data) && !layout_data.visible) {\n                return false;\n            } else {\n                return true;\n            }\n        }\n    };\n\n    jm.graph_canvas = function (view) {\n        this.opts = view.opts;\n        this.e_canvas = $c('canvas');\n        this.e_canvas.className = 'jsmind';\n        this.canvas_ctx = this.e_canvas.getContext('2d');\n        this.size = { w: 0, h: 0 };\n    };\n\n    jm.graph_canvas.prototype = {\n        element: function () {\n            return this.e_canvas;\n        },\n\n        set_size: function (w, h) {\n            this.size.w = w;\n            this.size.h = h;\n            this.e_canvas.width = w;\n            this.e_canvas.height = h;\n        },\n\n        clear: function () {\n            this.canvas_ctx.clearRect(0, 0, this.size.w, this.size.h);\n        },\n\n        draw_line: function (pout, pin, offset) {\n            var ctx = this.canvas_ctx;\n            ctx.strokeStyle = this.opts.line_color;\n            ctx.lineWidth = this.opts.line_width;\n            ctx.lineCap = 'round';\n\n            this._bezier_to(ctx,\n                pin.x + offset.x,\n                pin.y + offset.y,\n                pout.x + offset.x,\n                pout.y + offset.y);\n        },\n\n        copy_to: function (dest_canvas_ctx, callback) {\n            dest_canvas_ctx.drawImage(this.e_canvas, 0, 0);\n            !!callback && callback();\n        },\n\n        _bezier_to: function (ctx, x1, y1, x2, y2) {\n            ctx.beginPath();\n            ctx.moveTo(x1, y1);\n            ctx.bezierCurveTo(x1 + (x2 - x1) * 2 / 3, y1, x1, y2, x2, y2);\n            ctx.stroke();\n        },\n\n        _line_to: function (ctx, x1, y1, x2, y2) {\n            ctx.beginPath();\n            ctx.moveTo(x1, y1);\n            ctx.lineTo(x2, y2);\n            ctx.stroke();\n        }\n    };\n\n    jm.graph_svg = function (view) {\n        this.view = view;\n        this.opts = view.opts;\n        this.e_svg = jm.graph_svg.c('svg');\n        this.e_svg.setAttribute('class', 'jsmind');\n        this.size = { w: 0, h: 0 };\n        this.lines = [];\n    };\n\n    jm.graph_svg.c = function (tag) {\n        return $d.createElementNS('http://www.w3.org/2000/svg', tag);\n    };\n\n    jm.graph_svg.prototype = {\n        element: function () {\n            return this.e_svg;\n        },\n\n        set_size: function (w, h) {\n            this.size.w = w;\n            this.size.h = h;\n            this.e_svg.setAttribute('width', w);\n            this.e_svg.setAttribute('height', h);\n        },\n\n        clear: function () {\n            var len = this.lines.length;\n            while (len--) {\n                this.e_svg.removeChild(this.lines[len]);\n            }\n            this.lines.length = 0;\n        },\n\n        draw_line: function (pout, pin, offset) {\n            var line = jm.graph_svg.c('path');\n            line.setAttribute('stroke', this.opts.line_color);\n            line.setAttribute('stroke-width', this.opts.line_width);\n            line.setAttribute('fill', 'transparent');\n            this.lines.push(line);\n            this.e_svg.appendChild(line);\n            this._bezier_to(line, pin.x + offset.x, pin.y + offset.y, pout.x + offset.x, pout.y + offset.y);\n        },\n\n        copy_to: function (dest_canvas_ctx, callback) {\n            var img = new Image();\n            img.onload = function () {\n                dest_canvas_ctx.drawImage(img, 0, 0);\n                !!callback && callback();\n            }\n            img.src = 'data:image/svg+xml;base64,' + btoa(new XMLSerializer().serializeToString(this.e_svg));\n        },\n\n        _bezier_to: function (path, x1, y1, x2, y2) {\n            path.setAttribute('d', 'M' + x1 + ' ' + y1 + ' C ' + (x1 + (x2 - x1) * 2 / 3) + ' ' + y1 + ', ' + x1 + ' ' + y2 + ', ' + x2 + ' ' + y2);\n        },\n\n        _line_to: function (path, x1, y1, x2, y2) {\n            path.setAttribute('d', 'M ' + x1 + ' ' + y1 + ' L ' + x2 + ' ' + y2);\n        }\n    };\n\n    // view provider\n    jm.view_provider = function (jm, options) {\n        this.opts = options;\n        this.jm = jm;\n        this.layout = jm.layout;\n\n        this.container = null;\n        this.e_panel = null;\n        this.e_nodes = null;\n\n        this.size = { w: 0, h: 0 };\n\n        this.selected_node = null;\n        this.editing_node = null;\n\n        this.graph = null;\n    };\n\n    jm.view_provider.prototype = {\n        init: function () {\n            logger.debug('view.init');\n\n            this.container = $i(this.opts.container) ? this.opts.container : $g(this.opts.container);\n            if (!this.container) {\n                logger.error('the options.view.container was not be found in dom');\n                return;\n            }\n            this.e_panel = $c('div');\n            this.e_nodes = $c('jmnodes');\n            this.e_editor = $c('input');\n\n            this.graph = this.opts.engine.toLowerCase() === 'svg' ? new jm.graph_svg(this) : new jm.graph_canvas(this);\n            this.e_panel.className = 'jsmind-inner jmnode-overflow-' + this.opts.node_overflow;\n            this.e_panel.tabIndex = 1;\n            this.e_panel.appendChild(this.graph.element());\n            this.e_panel.appendChild(this.e_nodes);\n\n            this.e_editor.className = 'jsmind-editor';\n            this.e_editor.type = 'text';\n\n            this.actualZoom = 1;\n            this.zoomStep = 0.1;\n            this.minZoom = 0.5;\n            this.maxZoom = 2;\n\n            var v = this;\n            jm.util.dom.add_event(this.e_editor, 'keydown', function (e) {\n                var evt = e || event;\n                if (evt.keyCode == 13) { v.edit_node_end(); evt.stopPropagation(); }\n            });\n            jm.util.dom.add_event(this.e_editor, 'blur', function (e) {\n                v.edit_node_end();\n            });\n\n            this.container.appendChild(this.e_panel);\n\n            // Used to avoid dragging, while editing node.\n            this.dragging_enabled = true\n\n            this.draggable_canvas()\n        },\n\n        add_event: function (obj, event_name, event_handle) {\n            jm.util.dom.add_event(this.e_nodes, event_name, function (e) {\n                var evt = e || event;\n                event_handle.call(obj, evt);\n            });\n        },\n\n        get_binded_nodeid: function (element) {\n            if (element == null) {\n                return null;\n            }\n            var tagName = element.tagName.toLowerCase();\n            if (tagName == 'jmnodes' || tagName == 'body' || tagName == 'html') {\n                return null;\n            }\n            if (tagName == 'jmnode' || tagName == 'jmexpander') {\n                return element.getAttribute('nodeid');\n            } else {\n                return this.get_binded_nodeid(element.parentElement);\n            }\n        },\n\n        is_expander: function (element) {\n            return (element.tagName.toLowerCase() == 'jmexpander');\n        },\n\n        reset: function () {\n            logger.debug('view.reset');\n            this.selected_node = null;\n            this.clear_lines();\n            this.clear_nodes();\n            this.reset_theme();\n        },\n\n        reset_theme: function () {\n            var theme_name = this.jm.options.theme;\n            if (!!theme_name) {\n                this.e_nodes.className = 'theme-' + theme_name;\n            } else {\n                this.e_nodes.className = '';\n            }\n        },\n\n        reset_custom_style: function () {\n            var nodes = this.jm.mind.nodes;\n            for (var nodeid in nodes) {\n                this.reset_node_custom_style(nodes[nodeid]);\n            }\n        },\n\n        load: function () {\n            logger.debug('view.load');\n            this.init_nodes();\n        },\n\n        expand_size: function () {\n            var min_size = this.layout.get_min_size();\n            var min_width = min_size.w + this.opts.hmargin * 2;\n            var min_height = min_size.h + this.opts.vmargin * 2;\n            var client_w = this.e_panel.clientWidth;\n            var client_h = this.e_panel.clientHeight;\n            if (client_w < min_width) { client_w = min_width; }\n            if (client_h < min_height) { client_h = min_height; }\n            this.size.w = client_w;\n            this.size.h = client_h;\n        },\n\n        init_nodes_size: function (node) {\n            var view_data = node._data.view;\n            view_data.width = view_data.element.clientWidth;\n            view_data.height = view_data.element.clientHeight;\n        },\n\n        init_nodes: function () {\n            var nodes = this.jm.mind.nodes;\n            var doc_frag = $d.createDocumentFragment();\n            for (var nodeid in nodes) {\n                this.create_node_element(nodes[nodeid], doc_frag);\n            }\n            this.e_nodes.appendChild(doc_frag);\n            for (var nodeid in nodes) {\n                this.init_nodes_size(nodes[nodeid]);\n            }\n        },\n\n        add_node: function (node) {\n            this.create_node_element(node, this.e_nodes);\n            this.init_nodes_size(node);\n        },\n\n        create_node_element: function (node, parent_node) {\n            var view_data = null;\n            if ('view' in node._data) {\n                view_data = node._data.view;\n            } else {\n                view_data = {};\n                node._data.view = view_data;\n            }\n\n            var d = $c('jmnode');\n            if (node.isroot) {\n                d.className = 'root';\n            } else {\n                var d_e = $c('jmexpander');\n                $t(d_e, '-');\n                d_e.setAttribute('nodeid', node.id);\n                d_e.style.visibility = 'hidden';\n                parent_node.appendChild(d_e);\n                view_data.expander = d_e;\n            }\n            if (!!node.topic) {\n                if (this.opts.support_html) {\n                    $h(d, node.topic);\n                } else {\n                    $t(d, node.topic);\n                }\n            }\n            d.setAttribute('nodeid', node.id);\n            d.style.visibility = 'hidden';\n            this._reset_node_custom_style(d, node.data);\n\n            parent_node.appendChild(d);\n            view_data.element = d;\n        },\n\n        remove_node: function (node) {\n            if (this.selected_node != null && this.selected_node.id == node.id) {\n                this.selected_node = null;\n            }\n            if (this.editing_node != null && this.editing_node.id == node.id) {\n                node._data.view.element.removeChild(this.e_editor);\n                this.editing_node = null;\n            }\n            var children = node.children;\n            var i = children.length;\n            while (i--) {\n                this.remove_node(children[i]);\n            }\n            if (node._data.view) {\n                var element = node._data.view.element;\n                var expander = node._data.view.expander;\n                this.e_nodes.removeChild(element);\n                this.e_nodes.removeChild(expander);\n                node._data.view.element = null;\n                node._data.view.expander = null;\n            }\n        },\n\n        update_node: function (node) {\n            var view_data = node._data.view;\n            var element = view_data.element;\n            if (!!node.topic) {\n                if (this.opts.support_html) {\n                    $h(element, node.topic);\n                } else {\n                    $t(element, node.topic);\n                }\n            }\n            if (this.layout.is_visible(node)) {\n                view_data.width = element.clientWidth;\n                view_data.height = element.clientHeight;\n            } else {\n                let origin_style = element.getAttribute('style');\n                element.style = 'visibility: visible; left:0; top:0;';\n                view_data.width = element.clientWidth;\n                view_data.height = element.clientHeight;\n                element.style = origin_style;\n            }\n        },\n\n        select_node: function (node) {\n            if (!!this.selected_node) {\n                this.selected_node._data.view.element.className =\n                    this.selected_node._data.view.element.className.replace(/\\s*selected\\b/i, '');\n                this.reset_node_custom_style(this.selected_node);\n            }\n            if (!!node) {\n                this.selected_node = node;\n                node._data.view.element.className += ' selected';\n                this.clear_node_custom_style(node);\n            }\n        },\n\n        select_clear: function () {\n            this.select_node(null);\n        },\n\n        get_editing_node: function () {\n            return this.editing_node;\n        },\n\n        is_editing: function () {\n            return (!!this.editing_node);\n        },\n\n        edit_node_begin: function (node) {\n            if (!node.topic) {\n                logger.warn(\"don't edit image nodes\");\n                return;\n            }\n            if (this.editing_node != null) {\n                this.edit_node_end();\n            }\n            this.editing_node = node;\n            var view_data = node._data.view;\n            var element = view_data.element;\n            var topic = node.topic;\n            var ncs = getComputedStyle(element);\n            this.e_editor.value = topic;\n            this.e_editor.style.width = (element.clientWidth - parseInt(ncs.getPropertyValue('padding-left')) - parseInt(ncs.getPropertyValue('padding-right'))) + 'px';\n            element.innerHTML = '';\n            element.appendChild(this.e_editor);\n            element.style.zIndex = 5;\n            this.e_editor.focus();\n            this.e_editor.select();\n        },\n\n        edit_node_end: function () {\n            if (this.editing_node != null) {\n                var node = this.editing_node;\n                this.editing_node = null;\n                var view_data = node._data.view;\n                var element = view_data.element;\n                var topic = this.e_editor.value;\n                element.style.zIndex = 'auto';\n                element.removeChild(this.e_editor);\n                if (jm.util.text.is_empty(topic) || node.topic === topic) {\n                    if (this.opts.support_html) {\n                        $h(element, node.topic);\n                    } else {\n                        $t(element, node.topic);\n                    }\n                } else {\n                    this.jm.update_node(node.id, topic);\n                }\n            }\n            this.e_panel.focus();\n        },\n\n        get_view_offset: function () {\n            var bounds = this.layout.bounds;\n            var _x = (this.size.w - bounds.e - bounds.w) / 2;\n            var _y = this.size.h / 2;\n            return { x: _x, y: _y };\n        },\n\n        resize: function () {\n            this.graph.set_size(1, 1);\n            this.e_nodes.style.width = '1px';\n            this.e_nodes.style.height = '1px';\n\n            this.expand_size();\n            this._show();\n        },\n\n        _show: function () {\n            this.graph.set_size(this.size.w, this.size.h);\n            this.e_nodes.style.width = this.size.w + 'px';\n            this.e_nodes.style.height = this.size.h + 'px';\n            this.show_nodes();\n            this.show_lines();\n            //this.layout.cache_valid = true;\n            this.jm.invoke_event_handle(jm.event_type.resize, { data: [] });\n        },\n\n        zoomIn: function () {\n            return this.setZoom(this.actualZoom + this.zoomStep);\n        },\n\n        zoomOut: function () {\n            return this.setZoom(this.actualZoom - this.zoomStep);\n        },\n\n        setZoom: function (zoom) {\n            if ((zoom < this.minZoom) || (zoom > this.maxZoom)) {\n                return false;\n            }\n            this.actualZoom = zoom;\n            for (var i = 0; i < this.e_panel.children.length; i++) {\n                this.e_panel.children[i].style.zoom = zoom;\n            };\n            this.show(true);\n            return true;\n\n        },\n\n        _center_root: function () {\n            // center root node\n            var outer_w = this.e_panel.clientWidth;\n            var outer_h = this.e_panel.clientHeight;\n            if (this.size.w > outer_w) {\n                var _offset = this.get_view_offset();\n                this.e_panel.scrollLeft = _offset.x * this.actualZoom - outer_w / 2;\n            }\n            if (this.size.h > outer_h) {\n                this.e_panel.scrollTop = (this.size.h * this.actualZoom - outer_h) / 2;\n            }\n        },\n\n        show: function (keep_center) {\n            logger.debug('view.show');\n            this.expand_size();\n            this._show();\n            if (!!keep_center) {\n                this._center_root();\n            }\n        },\n\n        relayout: function () {\n            this.expand_size();\n            this._show();\n        },\n\n        save_location: function (node) {\n            var vd = node._data.view;\n            vd._saved_location = {\n                x: parseInt(vd.element.style.left) - this.e_panel.scrollLeft,\n                y: parseInt(vd.element.style.top) - this.e_panel.scrollTop,\n            };\n        },\n\n        restore_location: function (node) {\n            var vd = node._data.view;\n            this.e_panel.scrollLeft = parseInt(vd.element.style.left) - vd._saved_location.x;\n            this.e_panel.scrollTop = parseInt(vd.element.style.top) - vd._saved_location.y;\n        },\n\n        clear_nodes: function () {\n            var mind = this.jm.mind;\n            if (mind == null) {\n                return;\n            }\n            var nodes = mind.nodes;\n            var node = null;\n            for (var nodeid in nodes) {\n                node = nodes[nodeid];\n                node._data.view.element = null;\n                node._data.view.expander = null;\n            }\n            this.e_nodes.innerHTML = '';\n        },\n\n        show_nodes: function () {\n            var nodes = this.jm.mind.nodes;\n            var node = null;\n            var node_element = null;\n            var expander = null;\n            var p = null;\n            var p_expander = null;\n            var expander_text = '-';\n            var view_data = null;\n            var _offset = this.get_view_offset();\n            for (var nodeid in nodes) {\n                node = nodes[nodeid];\n                view_data = node._data.view;\n                node_element = view_data.element;\n                expander = view_data.expander;\n                if (!this.layout.is_visible(node)) {\n                    node_element.style.display = 'none';\n                    expander.style.display = 'none';\n                    continue;\n                }\n                this.reset_node_custom_style(node);\n                p = this.layout.get_node_point(node);\n                view_data.abs_x = _offset.x + p.x;\n                view_data.abs_y = _offset.y + p.y;\n                node_element.style.left = (_offset.x + p.x) + 'px';\n                node_element.style.top = (_offset.y + p.y) + 'px';\n                node_element.style.display = '';\n                node_element.style.visibility = 'visible';\n                if (!node.isroot && node.children.length > 0) {\n                    expander_text = node.expanded ? '-' : '+';\n                    p_expander = this.layout.get_expander_point(node);\n                    expander.style.left = (_offset.x + p_expander.x) + 'px';\n                    expander.style.top = (_offset.y + p_expander.y) + 'px';\n                    expander.style.display = '';\n                    expander.style.visibility = 'visible';\n                    $t(expander, expander_text);\n                }\n                // hide expander while all children have been removed\n                if (!node.isroot && node.children.length == 0) {\n                    expander.style.display = 'none';\n                    expander.style.visibility = 'hidden';\n                }\n            }\n        },\n\n        reset_node_custom_style: function (node) {\n            this._reset_node_custom_style(node._data.view.element, node.data);\n        },\n\n        _reset_node_custom_style: function (node_element, node_data) {\n            if ('background-color' in node_data) {\n                node_element.style.backgroundColor = node_data['background-color'];\n            }\n            if ('foreground-color' in node_data) {\n                node_element.style.color = node_data['foreground-color'];\n            }\n            if ('width' in node_data) {\n                node_element.style.width = node_data['width'] + 'px';\n            }\n            if ('height' in node_data) {\n                node_element.style.height = node_data['height'] + 'px';\n            }\n            if ('font-size' in node_data) {\n                node_element.style.fontSize = node_data['font-size'] + 'px';\n            }\n            if ('font-weight' in node_data) {\n                node_element.style.fontWeight = node_data['font-weight'];\n            }\n            if ('font-style' in node_data) {\n                node_element.style.fontStyle = node_data['font-style'];\n            }\n            if ('background-image' in node_data) {\n                var backgroundImage = node_data['background-image'];\n                if (backgroundImage.startsWith('data') && node_data['width'] && node_data['height']) {\n                    var img = new Image();\n\n                    img.onload = function () {\n                        var c = $c('canvas');\n                        c.width = node_element.clientWidth;\n                        c.height = node_element.clientHeight;\n                        var img = this;\n                        if (c.getContext) {\n                            var ctx = c.getContext('2d');\n                            ctx.drawImage(img, 2, 2, node_element.clientWidth, node_element.clientHeight);\n                            var scaledImageData = c.toDataURL();\n                            node_element.style.backgroundImage = 'url(' + scaledImageData + ')';\n                        }\n                    };\n                    img.src = backgroundImage;\n\n                } else {\n                    node_element.style.backgroundImage = 'url(' + backgroundImage + ')';\n                }\n                node_element.style.backgroundSize = '99%';\n\n                if ('background-rotation' in node_data) {\n                    node_element.style.transform = 'rotate(' + node_data['background-rotation'] + 'deg)';\n                }\n            }\n        },\n\n        clear_node_custom_style: function (node) {\n            var node_element = node._data.view.element;\n            node_element.style.backgroundColor = \"\";\n            node_element.style.color = \"\";\n        },\n\n        clear_lines: function () {\n            this.graph.clear();\n        },\n\n        show_lines: function () {\n            this.clear_lines();\n            var nodes = this.jm.mind.nodes;\n            var node = null;\n            var pin = null;\n            var pout = null;\n            var _offset = this.get_view_offset();\n            for (var nodeid in nodes) {\n                node = nodes[nodeid];\n                if (!!node.isroot) { continue; }\n                if (('visible' in node._data.layout) && !node._data.layout.visible) { continue; }\n                pin = this.layout.get_node_point_in(node);\n                pout = this.layout.get_node_point_out(node.parent);\n                this.graph.draw_line(pout, pin, _offset);\n            }\n        },\n\n        // Drag the whole mind map with your mouse (usefull when it's larger that the container).\n        draggable_canvas: function () {\n            // If draggable option is true.\n            if (this.opts.draggable) {\n                // Dragging disabled by default.\n                let dragging = false\n                let x, y\n                if (this.opts.hide_scrollbars_when_draggable) {\n                    // Avoid scrollbars when mind map is larger than the container (e_panel = id jsmind-inner)\n                    this.e_panel.style = 'overflow: hidden'\n                }\n                // Move the whole mind map with mouse moves, while button is down.\n                jm.util.dom.add_event(this.container, 'mousedown', (eventDown) => {\n                    dragging = true\n                    // Record current mouse position.\n                    x = eventDown.clientX\n                    y = eventDown.clientY\n                })\n                // Stop moving mind map once mouse button is released.\n                jm.util.dom.add_event(this.container, 'mouseup', () => {\n                    dragging = false\n                })\n                // Follow current mouse position and move mind map accordingly.\n                jm.util.dom.add_event(this.container, 'mousemove', (eventMove) => {\n                    if (this.dragging_enabled && dragging) {\n                        this.e_panel.scrollBy(x - eventMove.clientX, y - eventMove.clientY)\n                        // Record new current position.\n                        x = eventMove.clientX\n                        y = eventMove.clientY\n                    }\n                })\n            }\n        },\n\n        get_draggable_canvas: function () {\n            return this.opts.draggable\n        },\n\n        enable_draggable_canvas: function () {\n            this.dragging_enabled = true\n        },\n\n        disable_draggable_canvas: function () {\n            this.dragging_enabled = false\n        },\n\n    };\n\n    // shortcut provider\n    jm.shortcut_provider = function (jm, options) {\n        this.jm = jm;\n        this.opts = options;\n        this.mapping = options.mapping;\n        this.handles = options.handles;\n        this._newid = null;\n        this._mapping = {};\n    };\n\n    jm.shortcut_provider.prototype = {\n        init: function () {\n            jm.util.dom.add_event(this.jm.view.e_panel, 'keydown', this.handler.bind(this));\n\n            this.handles['addchild'] = this.handle_addchild;\n            this.handles['addbrother'] = this.handle_addbrother;\n            this.handles['editnode'] = this.handle_editnode;\n            this.handles['delnode'] = this.handle_delnode;\n            this.handles['toggle'] = this.handle_toggle;\n            this.handles['up'] = this.handle_up;\n            this.handles['down'] = this.handle_down;\n            this.handles['left'] = this.handle_left;\n            this.handles['right'] = this.handle_right;\n\n            for (var handle in this.mapping) {\n                if (!!this.mapping[handle] && (handle in this.handles)) {\n                    var keys = this.mapping[handle];\n                    if(!Array.isArray(keys)){\n                        keys = [keys]\n                    }\n                    for(let key of keys){\n                        this._mapping[key] = this.handles[handle];\n                    }\n                }\n            }\n\n            if (typeof this.opts.id_generator === 'function') {\n                this._newid = this.opts.id_generator;\n            } else {\n                this._newid = jm.util.uuid.newid;\n            }\n        },\n\n        enable_shortcut: function () {\n            this.opts.enable = true;\n        },\n\n        disable_shortcut: function () {\n            this.opts.enable = false;\n        },\n\n        handler: function (e) {\n            if (e.which == 9) { e.preventDefault(); } //prevent tab to change focus in browser\n            if (this.jm.view.is_editing()) { return; }\n            var evt = e || event;\n            if (!this.opts.enable) { return true; }\n            var kc = evt.keyCode + (evt.metaKey << 13) + (evt.ctrlKey << 12) + (evt.altKey << 11) + (evt.shiftKey << 10);\n            if (kc in this._mapping) {\n                this._mapping[kc].call(this, this.jm, e);\n            }\n        },\n\n        handle_addchild: function (_jm, e) {\n            var selected_node = _jm.get_selected_node();\n            if (!!selected_node) {\n                var nodeid = this._newid();\n                var node = _jm.add_node(selected_node, nodeid, 'New Node');\n                if (!!node) {\n                    _jm.select_node(nodeid);\n                    _jm.begin_edit(nodeid);\n                }\n            }\n        },\n        handle_addbrother: function (_jm, e) {\n            var selected_node = _jm.get_selected_node();\n            if (!!selected_node && !selected_node.isroot) {\n                var nodeid = this._newid();\n                var node = _jm.insert_node_after(selected_node, nodeid, 'New Node');\n                if (!!node) {\n                    _jm.select_node(nodeid);\n                    _jm.begin_edit(nodeid);\n                }\n            }\n        },\n        handle_editnode: function (_jm, e) {\n            var selected_node = _jm.get_selected_node();\n            if (!!selected_node) {\n                _jm.begin_edit(selected_node);\n            }\n        },\n        handle_delnode: function (_jm, e) {\n            var selected_node = _jm.get_selected_node();\n            if (!!selected_node && !selected_node.isroot) {\n                _jm.select_node(selected_node.parent);\n                _jm.remove_node(selected_node);\n            }\n        },\n        handle_toggle: function (_jm, e) {\n            var evt = e || event;\n            var selected_node = _jm.get_selected_node();\n            if (!!selected_node) {\n                _jm.toggle_node(selected_node.id);\n                evt.stopPropagation();\n                evt.preventDefault();\n            }\n        },\n        handle_up: function (_jm, e) {\n            var evt = e || event;\n            var selected_node = _jm.get_selected_node();\n            if (!!selected_node) {\n                var up_node = _jm.find_node_before(selected_node);\n                if (!up_node) {\n                    var np = _jm.find_node_before(selected_node.parent);\n                    if (!!np && np.children.length > 0) {\n                        up_node = np.children[np.children.length - 1];\n                    }\n                }\n                if (!!up_node) {\n                    _jm.select_node(up_node);\n                }\n                evt.stopPropagation();\n                evt.preventDefault();\n            }\n        },\n\n        handle_down: function (_jm, e) {\n            var evt = e || event;\n            var selected_node = _jm.get_selected_node();\n            if (!!selected_node) {\n                var down_node = _jm.find_node_after(selected_node);\n                if (!down_node) {\n                    var np = _jm.find_node_after(selected_node.parent);\n                    if (!!np && np.children.length > 0) {\n                        down_node = np.children[0];\n                    }\n                }\n                if (!!down_node) {\n                    _jm.select_node(down_node);\n                }\n                evt.stopPropagation();\n                evt.preventDefault();\n            }\n        },\n\n        handle_left: function (_jm, e) {\n            this._handle_direction(_jm, e, jm.direction.left);\n        },\n        handle_right: function (_jm, e) {\n            this._handle_direction(_jm, e, jm.direction.right);\n        },\n        _handle_direction: function (_jm, e, d) {\n            var evt = e || event;\n            var selected_node = _jm.get_selected_node();\n            var node = null;\n            if (!!selected_node) {\n                if (selected_node.isroot) {\n                    var c = selected_node.children;\n                    var children = [];\n                    for (var i = 0; i < c.length; i++) {\n                        if (c[i].direction === d) {\n                            children.push(i);\n                        }\n                    }\n                    node = c[children[Math.floor((children.length - 1) / 2)]];\n                }\n                else if (selected_node.direction === d) {\n                    var children = selected_node.children;\n                    var childrencount = children.length;\n                    if (childrencount > 0) {\n                        node = children[Math.floor((childrencount - 1) / 2)];\n                    }\n                } else {\n                    node = selected_node.parent;\n                }\n                if (!!node) {\n                    _jm.select_node(node);\n                }\n                evt.stopPropagation();\n                evt.preventDefault();\n            }\n        },\n    };\n\n\n    // plugin\n    jm.plugin = function (name, init) {\n        this.name = name;\n        this.init = init;\n    };\n\n    jm.plugins = [];\n\n    jm.register_plugin = function (plugin) {\n        if (plugin instanceof jm.plugin) {\n            jm.plugins.push(plugin);\n        }\n    };\n\n    jm.init_plugins = function (sender) {\n        $w.setTimeout(function () {\n            jm._init_plugins(sender);\n        }, 0);\n    };\n\n    jm._init_plugins = function (sender) {\n        var l = jm.plugins.length;\n        var fn_init = null;\n        for (var i = 0; i < l; i++) {\n            fn_init = jm.plugins[i].init;\n            if (typeof fn_init === 'function') {\n                fn_init(sender);\n            }\n        }\n    };\n\n    // quick way\n    jm.show = function (options, mind) {\n        var _jm = new jm(options);\n        _jm.show(mind);\n        return _jm;\n    };\n\n    // export jsmind\n    if (typeof module !== 'undefined' && typeof exports === 'object') {\n        module.exports = jm;\n    } else if (typeof define === 'function' && (define.amd || define.cmd)) {\n        define(function () { return jm; });\n    } else {\n        $w[__name__] = jm;\n    }\n})(typeof window !== 'undefined' ? window : global);\n"]}