{ "version": 3, "sources": ["../ui/app/mn.wizard.service.js"], "sourcesContent": ["/*\nCopyright 2020-Present Couchbase, Inc.\n\nUse of this software is governed by the Business Source License included in\nthe file licenses/BSL-Couchbase.txt. As of the Change Date specified in that\nfile, in accordance with the Business Source License, use of this software will\nbe governed by the Apache License, Version 2.0, included in the file\nlicenses/APL2.txt.\n*/\n\n\nimport {FormGroup, FormControl, Validators, FormArray} from '@angular/forms';\nimport {Injectable} from '@angular/core';\nimport {HttpClient, HttpParams} from '@angular/common/http';\nimport _ from 'lodash';\nimport {BehaviorSubject, combineLatest} from 'rxjs';\nimport {switchMap, shareReplay, map, pluck} from 'rxjs/operators';\n\nimport {MnHelperService} from './mn.helper.service.js';\nimport {MnAdminService} from './mn.admin.service.js';\nimport {MnPoolsService} from './mn.pools.service.js';\nimport {MnHttpRequest} from './mn.http.request.js';\n\nimport {singletonGuard} from './mn.core.js';\n\nexport {MnWizardService};\n\nfunction ipvOnlyValidator() {\n return (control) => {\n let value = control.value;\n delete control.warnings;\n if (value && value.includes(\"Only\")) {\n let mnLocation = MnHelperService.mnLocation();\n let isValueV6 = value.includes(\"inet6\");\n if (mnLocation.kind) {\n let isKindV6 = mnLocation.kind.includes(\"ipv6\");\n return (isKindV6 && isValueV6) || (!isKindV6 && !isValueV6) ? null : getIpvOnlyError(isKindV6, isValueV6);\n } else {\n control.warnings = getIpvOnlyError(null, isValueV6);\n return null;\n }\n } else {\n return null;\n }\n };\n}\n\nfunction getIpvOnlyError(isKindV6, isValueV6) {\n return {\n ipvOnly: {\n kind: isKindV6 ? 6 : 4,\n value: isValueV6 ? 6 : 4\n }\n };\n}\n\n\n\nvar clusterStorage = new FormGroup({\n hostname: new FormControl(null, [Validators.required]),\n hostConfig: new FormGroup({\n addressFamilyUI: new FormControl(null, [ipvOnlyValidator()]),\n nodeEncryption: new FormControl()\n }),\n storage: new FormGroup({\n path: new FormControl(null),\n index_path: new FormControl(null),\n eventing_path: new FormControl(null),\n java_home: new FormControl(null),\n cbas_path: new FormArray([new FormControl()])\n })\n});\n\nvar wizardForm = {\n newCluster: new FormGroup({\n clusterName: new FormControl(null, [Validators.required]),\n user: new FormGroup({\n username: new FormControl(\"Administrator\", [Validators.required]),\n password: new FormControl(null, [Validators.required, Validators.minLength(6)]),\n passwordVerify: new FormControl()\n })\n }),\n newClusterConfig: new FormGroup({\n clusterStorage: clusterStorage,\n services: new FormGroup({\n // flag\n // field\n }),\n javaPath: new FormControl(),\n storageMode: new FormControl(null)\n }),\n termsAndConditions: new FormGroup({\n agree: new FormControl(false, [Validators.required]),\n enableStats: new FormControl(true)\n }),\n joinCluster: new FormGroup({\n clusterAdmin: new FormGroup({\n hostname: new FormControl(null, [Validators.required]),\n user: new FormControl(\"Administrator\", [Validators.required]),\n password: new FormControl('', [Validators.required])\n }),\n services: new FormGroup({\n // flag\n }),\n clusterStorage: clusterStorage\n })\n};\n\nclass MnWizardService {\n static get annotations() { return [\n new Injectable()\n ]}\n\n static get parameters() { return [\n HttpClient,\n MnAdminService,\n MnHelperService,\n MnPoolsService\n ]}\n\n constructor(http, mnAdminService, mnHelperService, mnPoolsService) {\n singletonGuard(MnWizardService);\n this.http = http;\n this.wizardForm = wizardForm;\n this.IEC = mnHelperService.IEC;\n\n this.stream = {};\n this.initialValues = {\n hostname: null,\n storageMode: null,\n clusterStorage: null,\n implementationVersion: null\n };\n\n this.stream.joinClusterHttp =\n new MnHttpRequest(this.postJoinCluster.bind(this))\n .addSuccess()\n .addLoading()\n .addError();\n\n this.stream.postNodeInitHttp =\n new MnHttpRequest(this.postNodeInit.bind(this))\n .addSuccess()\n .addError();\n\n this.stream.postClusterInitHttp =\n new MnHttpRequest(this.postClusterInit.bind(this))\n .addSuccess()\n .addError();\n\n this.stream.diskStorageHttp =\n new MnHttpRequest(this.postDiskStorage.bind(this))\n .addSuccess()\n .addError();\n\n this.stream.enableExternalListenerHttp =\n new MnHttpRequest(this.postEnableExternalListener.bind(this))\n .addSuccess()\n .addError();\n\n this.stream.setupNetConfigHttp =\n new MnHttpRequest(this.postSetupNetConfig.bind(this))\n .addSuccess()\n .addError();\n\n this.stream.disableUnusedExternalListenersHttp =\n new MnHttpRequest(this.postDisableUnusedExternalListeners.bind(this))\n .addSuccess()\n .addError();\n\n this.stream.hostnameHttp =\n new MnHttpRequest(this.postHostname.bind(this))\n .addSuccess()\n .addError();\n\n this.stream.postSettingsWebHttp =\n new MnHttpRequest(this.postSettingsWeb.bind(this))\n .addSuccess()\n .addError();\n\n this.stream.querySettingsHttp =\n new MnHttpRequest(this.postQuerySettings.bind(this))\n .addSuccess()\n .addError();\n\n this.stream.indexesHttp =\n new MnHttpRequest(this.postIndexes.bind(this))\n .addSuccess()\n .addError();\n\n this.stream.servicesHttp =\n new MnHttpRequest(this.postServices.bind(this))\n .addSuccess()\n .addError();\n\n this.stream.statsHttp =\n new MnHttpRequest(this.postStats.bind(this))\n .addSuccess()\n .addError();\n\n this.stream.getSelfConfig =\n (new BehaviorSubject()).pipe(switchMap(this.getSelfConfig.bind(this)),\n shareReplay({refCount: true, bufferSize: 1}));\n\n\n this.stream.memoryQuotasFirst =\n combineLatest(\n this.stream.getSelfConfig,\n mnPoolsService.stream.quotaServices\n )\n .pipe(map(mnPoolsService.pluckMemoryQuotas.bind(mnPoolsService)));\n\n this.stream.getIndexes =\n (new BehaviorSubject()).pipe(switchMap(this.getIndexes.bind(this)),\n shareReplay({refCount: true, bufferSize: 1}));\n\n this.stream.preprocessPath =\n this.stream.getSelfConfig.pipe(map(this.chooseOSPathPreprocessor.bind(this)));\n\n this.stream.availableHddStorage =\n this.stream.getSelfConfig.pipe(\n pluck(\"availableStorage\", \"hdd\"),\n map((hdd) => hdd.sort((a, b) => b.path.length - a.path.length)));\n\n this.stream.initHddStorage =\n this.stream.getSelfConfig.pipe(\n pluck(\"storage\", \"hdd\", 0),\n map(function (rv) {\n rv.cbas_path = rv.cbas_dirs;\n delete rv.cbas_dirs;\n return rv;\n })\n );\n\n this.stream.totalRAMMegs =\n this.stream.getSelfConfig.pipe(\n map((nodeConfig) => Math.floor(nodeConfig.storageTotals.ram.total / this.IEC.Mi)));\n\n this.stream.maxRAMMegs =\n this.stream.totalRAMMegs.pipe(map(mnHelperService.calculateMaxMemorySize));\n }\n\n getServicesValues(servicesGroup) {\n return Object\n .keys(servicesGroup.controls)\n .filter((serviceName) => Boolean(servicesGroup.get(serviceName).value));\n // reduce(function (result, serviceName) {\n // var service = servicesGroup.get(serviceName);\n // if (service && service.value) {\n // result.push(serviceName);\n // }\n // return result;\n // }, []);\n }\n\n getAddressFamilyUI(config) {\n return config.addressFamily + (config.addressFamilyOnly ? \"Only\" : \"\");\n }\n\n setSelfConfig(selfConfig) {\n var hostname = selfConfig.configuredHostname;\n\n if (!hostname) {\n let maybeCbLocal = selfConfig['otpNode'].split('@')[1];\n if (!maybeCbLocal || (maybeCbLocal == \"cb.local\")) {\n hostname = selfConfig.addressFamily == \"inet6\" ? \"::1\" : \"127.0.0.1\";\n } else {\n hostname = maybeCbLocal;\n }\n } else {\n //remove port from host\n let parsed = new URL(\"http://\" + selfConfig.configuredHostname);\n //remove ipv6 brackets\n hostname = parsed.hostname.replace(/[[\\]']+/g, '');\n }\n\n wizardForm.newClusterConfig.get(\"clusterStorage.hostname\").setValue(hostname);\n wizardForm.joinCluster.get(\"clusterStorage.hostname\").setValue(hostname);\n wizardForm.newClusterConfig.get(\"clusterStorage.hostConfig\").patchValue({\n addressFamilyUI: this.getAddressFamilyUI(selfConfig),\n nodeEncryption: selfConfig.nodeEncryption\n });\n this.initialValues.hostname = hostname;\n }\n\n getUserCreds() {\n var data = _.clone(this.wizardForm.newCluster.value.user);\n data.user = data.username\n delete data.passwordVerify;\n delete data.username;\n return data;\n }\n\n createLookUpStream(subject) {\n return combineLatest(\n this.stream.availableHddStorage,\n this.stream.preprocessPath,\n subject\n ).pipe(\n map(this.lookupPathResource.bind(this)),\n map(this.updateTotal.bind(this)));\n }\n\n updateTotal(pathResource) {\n return Math.floor(\n pathResource.sizeKBytes * (100 - pathResource.usagePercent) / 100 / this.IEC.Mi\n ) + ' GiB';\n }\n\n lookupPathResource(rv) {\n var notFound = {path: \"/\", sizeKBytes: 0, usagePercent: 0};\n if (!rv[2]) {\n return notFound;\n } else {\n return _.detect(rv[0], function (info) {\n var preproc = rv[1](info.path);\n return rv[1](rv[2]).substring(0, preproc.length) == preproc;\n }) || notFound;\n }\n }\n\n chooseOSPathPreprocessor(config) {\n return (\n (config.os === 'windows') ||\n (config.os === 'win64') ||\n (config.os === 'win32')\n ) ? this.preprocessPathForWindows.bind(this) : this.preprocessPathStandard.bind(this);\n }\n\n preprocessPathStandard(p) {\n if (p.charAt(p.length-1) != '/') {\n p += '/';\n }\n return p;\n }\n\n preprocessPathForWindows(p) {\n p = p.replace(/\\\\/g, '/');\n if ((/^[A-Z]:\\//).exec(p)) { // if we're using uppercase drive letter downcase it\n p = String.fromCharCode(p.charCodeAt(0) + 0x20) + p.slice(1);\n }\n return this.preprocessPathStandard(p);\n }\n\n getQuerySettings() {\n return this.http.get(\"/settings/querySettings\");\n }\n\n getCELicense() {\n return this.http.get(\"CE_license_agreement.txt\", {responseType: 'text'});\n }\n\n getEELicense() {\n return this.http.get(\"EE_subscription_license_agreement.txt\", {responseType: 'text'});\n }\n\n getSelfConfig() {\n return this.http.get('/nodes/self');\n }\n\n postStats(sendStats) {\n return this.http.post('/settings/stats', {sendStats: sendStats});\n }\n\n postServices(data) {\n return this.http.post('/node/controller/setupServices', data);\n }\n\n\n\n postNodeInit(data) {\n return this.http.post('/nodeInit', data);\n }\n\n postClusterInit(data) {\n return this.http.post('/clusterInit', data);\n }\n\n postDiskStorage(config) {\n return this.http.post('/nodes/self/controller/settings', config);\n }\n\n postEnableExternalListener(data) {\n return this.http.post('/node/controller/enableExternalListener', data);\n }\n\n postSetupNetConfig(data) {\n return this.http.post('/node/controller/setupNetConfig', data);\n }\n\n postDisableUnusedExternalListeners() {\n return this.http.post(\"/node/controller/disableUnusedExternalListeners\");\n }\n\n postHostname(hostname) {\n return this.http.post('/node/controller/rename', {hostname: hostname});\n }\n\n\n\n postQuerySettings(data) {\n return this.http.post(\"/settings/querySettings\", data);\n }\n\n postIndexes(data) {\n return this.http.post('/settings/indexes', data);\n }\n\n getIndexes() {\n return this.http.get('/settings/indexes');\n }\n\n postSettingsWeb(user) {\n var data = _.clone(user[0]);\n delete data.passwordVerify;\n data.port = \"SAME\";\n return this.http.post('/settings/web', data, {\n params: new HttpParams().set(\"just_validate\", user[1] ? 1 : 0)\n });\n }\n\n postJoinCluster(clusterMember) {\n return this.http.post('/node/controller/doJoinCluster', clusterMember)\n }\n\n}\n"], "mappings": "ohBA2BA,2BAA4B,CAC1B,MAAO,AAAC,UAAY,CAClB,GAAI,OAAQ,QAAQ,MAEpB,GADA,MAAO,SAAQ,SACX,OAAS,MAAM,SAAS,QAAS,CACnC,GAAI,YAAa,gBAAgB,aAC7B,UAAY,MAAM,SAAS,SAC/B,GAAI,WAAW,KAAM,CACnB,GAAI,UAAW,WAAW,KAAK,SAAS,QACxC,MAAQ,WAAY,WAAe,CAAC,UAAY,CAAC,UAAa,KAAO,gBAAgB,SAAU,eAE/F,gBAAQ,SAAW,gBAAgB,KAAM,WAClC,SAGT,OAAO,OAfJ,4CAoBT,yBAAyB,SAAU,UAAW,CAC5C,MAAO,CACL,QAAS,CACP,KAAM,SAAW,EAAI,EACrB,MAAO,UAAY,EAAI,IAJpB,0CAWT,GAAI,gBAAiB,GAAI,WAAU,CACjC,SAAU,GAAI,aAAY,KAAM,CAAC,WAAW,WAC5C,WAAY,GAAI,WAAU,CACxB,gBAAiB,GAAI,aAAY,KAAM,CAAC,qBACxC,eAAgB,GAAI,eAEtB,QAAS,GAAI,WAAU,CACrB,KAAM,GAAI,aAAY,MACtB,WAAY,GAAI,aAAY,MAC5B,cAAe,GAAI,aAAY,MAC/B,UAAW,GAAI,aAAY,MAC3B,UAAW,GAAI,WAAU,CAAC,GAAI,mBAI9B,WAAa,CACf,WAAY,GAAI,WAAU,CACxB,YAAa,GAAI,aAAY,KAAM,CAAC,WAAW,WAC/C,KAAM,GAAI,WAAU,CAClB,SAAU,GAAI,aAAY,gBAAiB,CAAC,WAAW,WACvD,SAAU,GAAI,aAAY,KAAM,CAAC,WAAW,SAAU,WAAW,UAAU,KAC3E,eAAgB,GAAI,iBAGxB,iBAAkB,GAAI,WAAU,CAC9B,eACA,SAAU,GAAI,WAAU,IAIxB,SAAU,GAAI,aACd,YAAa,GAAI,aAAY,QAE/B,mBAAoB,GAAI,WAAU,CAChC,MAAO,GAAI,aAAY,GAAO,CAAC,WAAW,WAC1C,YAAa,GAAI,aAAY,MAE/B,YAAa,GAAI,WAAU,CACzB,aAAc,GAAI,WAAU,CAC1B,SAAU,GAAI,aAAY,KAAM,CAAC,WAAW,WAC5C,KAAM,GAAI,aAAY,gBAAiB,CAAC,WAAW,WACnD,SAAU,GAAI,aAAY,GAAI,CAAC,WAAW,aAE5C,SAAU,GAAI,WAAU,IAGxB,kBAIJ,qBAAsB,WACT,cAAc,CAAE,MAAO,CAChC,GAAI,uBAGK,aAAa,CAAE,MAAO,CAC/B,WACA,eACA,gBACA,gBAGF,YAAY,KAAM,eAAgB,gBAAiB,eAAgB,CACjE,eAAe,iBACf,KAAK,KAAO,KACZ,KAAK,WAAa,WAClB,KAAK,IAAM,gBAAgB,IAE3B,KAAK,OAAS,GACd,KAAK,cAAgB,CACnB,SAAU,KACV,YAAa,KACb,eAAgB,KAChB,sBAAuB,MAGzB,KAAK,OAAO,gBACV,GAAI,eAAc,KAAK,gBAAgB,KAAK,OAC3C,aACA,aACA,WAEH,KAAK,OAAO,iBACV,GAAI,eAAc,KAAK,aAAa,KAAK,OACxC,aACA,WAEH,KAAK,OAAO,oBACV,GAAI,eAAc,KAAK,gBAAgB,KAAK,OAC3C,aACA,WAEH,KAAK,OAAO,gBACV,GAAI,eAAc,KAAK,gBAAgB,KAAK,OAC3C,aACA,WAEH,KAAK,OAAO,2BACV,GAAI,eAAc,KAAK,2BAA2B,KAAK,OACtD,aACA,WAEH,KAAK,OAAO,mBACV,GAAI,eAAc,KAAK,mBAAmB,KAAK,OAC9C,aACA,WAEH,KAAK,OAAO,mCACV,GAAI,eAAc,KAAK,mCAAmC,KAAK,OAC9D,aACA,WAEH,KAAK,OAAO,aACV,GAAI,eAAc,KAAK,aAAa,KAAK,OACxC,aACA,WAEH,KAAK,OAAO,oBACV,GAAI,eAAc,KAAK,gBAAgB,KAAK,OAC3C,aACA,WAEH,KAAK,OAAO,kBACV,GAAI,eAAc,KAAK,kBAAkB,KAAK,OAC7C,aACA,WAEH,KAAK,OAAO,YACV,GAAI,eAAc,KAAK,YAAY,KAAK,OACvC,aACA,WAEH,KAAK,OAAO,aACV,GAAI,eAAc,KAAK,aAAa,KAAK,OACxC,aACA,WAEH,KAAK,OAAO,UACV,GAAI,eAAc,KAAK,UAAU,KAAK,OACrC,aACA,WAEH,KAAK,OAAO,cACT,GAAI,mBAAmB,KAAK,UAAU,KAAK,cAAc,KAAK,OAClC,YAAY,CAAC,SAAU,GAAM,WAAY,KAGxE,KAAK,OAAO,kBACV,cACE,KAAK,OAAO,cACZ,eAAe,OAAO,eAEvB,KAAK,IAAI,eAAe,kBAAkB,KAAK,kBAElD,KAAK,OAAO,WACT,GAAI,mBAAmB,KAAK,UAAU,KAAK,WAAW,KAAK,OAC/B,YAAY,CAAC,SAAU,GAAM,WAAY,KAExE,KAAK,OAAO,eACV,KAAK,OAAO,cAAc,KAAK,IAAI,KAAK,yBAAyB,KAAK,QAExE,KAAK,OAAO,oBACV,KAAK,OAAO,cAAc,KACxB,MAAM,mBAAoB,OAC1B,IAAI,AAAC,KAAQ,IAAI,KAAK,CAAC,EAAG,IAAM,EAAE,KAAK,OAAS,EAAE,KAAK,UAE3D,KAAK,OAAO,eACV,KAAK,OAAO,cAAc,KACxB,MAAM,UAAW,MAAO,GACxB,IAAI,SAAU,GAAI,CAChB,UAAG,UAAY,GAAG,UAClB,MAAO,IAAG,UACH,MAIb,KAAK,OAAO,aACV,KAAK,OAAO,cAAc,KACxB,IAAI,AAAC,YAAe,KAAK,MAAM,WAAW,cAAc,IAAI,MAAQ,KAAK,IAAI,MAEjF,KAAK,OAAO,WACV,KAAK,OAAO,aAAa,KAAK,IAAI,gBAAgB,yBAGtD,kBAAkB,cAAe,CAC/B,MAAO,QACJ,KAAK,cAAc,UACnB,OAAO,AAAC,aAAgB,QAAQ,cAAc,IAAI,aAAa,QAUpE,mBAAmB,OAAQ,CACzB,MAAO,QAAO,cAAiB,QAAO,kBAAoB,OAAS,IAGrE,cAAc,WAAY,CACxB,GAAI,UAAW,WAAW,mBAE1B,GAAK,SAWH,SAAW,AAFE,GAAI,KAAI,UAAY,WAAW,oBAE1B,SAAS,QAAQ,WAAY,QAXlC,CACb,GAAI,cAAe,WAAW,QAAW,MAAM,KAAK,GACpD,AAAI,CAAC,cAAiB,cAAgB,WACpC,SAAW,WAAW,eAAiB,QAAU,MAAQ,YAEzD,SAAW,aASf,WAAW,iBAAiB,IAAI,2BAA2B,SAAS,UACpE,WAAW,YAAY,IAAI,2BAA2B,SAAS,UAC/D,WAAW,iBAAiB,IAAI,6BAA6B,WAAW,CACtE,gBAAiB,KAAK,mBAAmB,YACzC,eAAgB,WAAW,iBAE7B,KAAK,cAAc,SAAW,SAGhC,cAAe,CACb,GAAI,MAAO,eAAE,MAAM,KAAK,WAAW,WAAW,MAAM,MACpD,YAAK,KAAO,KAAK,SACjB,MAAO,MAAK,eACZ,MAAO,MAAK,SACL,KAGT,mBAAmB,QAAS,CAC1B,MAAO,eACL,KAAK,OAAO,oBACZ,KAAK,OAAO,eACZ,SACA,KACA,IAAI,KAAK,mBAAmB,KAAK,OACjC,IAAI,KAAK,YAAY,KAAK,QAG9B,YAAY,aAAc,CACxB,MAAO,MAAK,MACV,aAAa,WAAc,KAAM,aAAa,cAAgB,IAAM,KAAK,IAAI,IAC3E,OAGN,mBAAmB,GAAI,CACrB,GAAI,UAAW,CAAC,KAAM,IAAK,WAAY,EAAG,aAAc,GACxD,MAAK,IAAG,IAGC,eAAE,OAAO,GAAG,GAAI,SAAU,KAAM,CACrC,GAAI,SAAU,GAAG,GAAG,KAAK,MACzB,MAAO,IAAG,GAAG,GAAG,IAAI,UAAU,EAAG,QAAQ,SAAW,WAChD,SAIV,yBAAyB,OAAQ,CAC/B,MACG,QAAO,KAAO,WACZ,OAAO,KAAO,SACd,OAAO,KAAO,QACf,KAAK,yBAAyB,KAAK,MAAQ,KAAK,uBAAuB,KAAK,MAGlF,uBAAuB,EAAG,CACxB,MAAI,GAAE,OAAO,EAAE,OAAO,IAAM,KAC1B,IAAK,KAEA,EAGT,yBAAyB,EAAG,CAC1B,SAAI,EAAE,QAAQ,MAAO,KAChB,YAAa,KAAK,IACrB,GAAI,OAAO,aAAa,EAAE,WAAW,GAAK,IAAQ,EAAE,MAAM,IAErD,KAAK,uBAAuB,GAGrC,kBAAmB,CACjB,MAAO,MAAK,KAAK,IAAI,2BAGvB,cAAe,CACb,MAAO,MAAK,KAAK,IAAI,2BAA4B,CAAC,aAAc,SAGlE,cAAe,CACb,MAAO,MAAK,KAAK,IAAI,wCAAyC,CAAC,aAAc,SAG/E,eAAgB,CACd,MAAO,MAAK,KAAK,IAAI,eAGvB,UAAU,UAAW,CACnB,MAAO,MAAK,KAAK,KAAK,kBAAmB,CAAC,YAG5C,aAAa,KAAM,CACjB,MAAO,MAAK,KAAK,KAAK,iCAAkC,MAK1D,aAAa,KAAM,CACjB,MAAO,MAAK,KAAK,KAAK,YAAa,MAGrC,gBAAgB,KAAM,CACpB,MAAO,MAAK,KAAK,KAAK,eAAgB,MAGxC,gBAAgB,OAAQ,CACtB,MAAO,MAAK,KAAK,KAAK,kCAAmC,QAG3D,2BAA2B,KAAM,CAC/B,MAAO,MAAK,KAAK,KAAK,0CAA4C,MAGpE,mBAAmB,KAAM,CACvB,MAAO,MAAK,KAAK,KAAK,kCAAmC,MAG3D,oCAAqC,CACnC,MAAO,MAAK,KAAK,KAAK,mDAGxB,aAAa,SAAU,CACrB,MAAO,MAAK,KAAK,KAAK,0BAA2B,CAAC,WAKpD,kBAAkB,KAAM,CACtB,MAAO,MAAK,KAAK,KAAK,0BAA2B,MAGnD,YAAY,KAAM,CAChB,MAAO,MAAK,KAAK,KAAK,oBAAqB,MAG7C,YAAa,CACX,MAAO,MAAK,KAAK,IAAI,qBAGvB,gBAAgB,KAAM,CACpB,GAAI,MAAO,eAAE,MAAM,KAAK,IACxB,aAAO,MAAK,eACZ,KAAK,KAAO,OACL,KAAK,KAAK,KAAK,gBAAiB,KAAM,CAC3C,OAAQ,GAAI,cAAa,IAAI,gBAAiB,KAAK,GAAK,EAAI,KAIhE,gBAAgB,cAAe,CAC7B,MAAO,MAAK,KAAK,KAAK,iCAAkC,iBA1T5D", "names": [] }