iobroker.eusec 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -47,6 +47,11 @@ Best is to set the adapter to Debug log mode (see [here](https://bropat.github.i
47
47
 
48
48
  ## Changelog
49
49
 
50
+ ### 1.3.1 (2024-09-08)
51
+
52
+ * (bropat) Fixed issue #436
53
+ * (bropat) Fixed issue #439
54
+
50
55
  ### 1.3.0 (2024-08-27)
51
56
 
52
57
  * (bropat) Requires ioBroker.admin version >= 7.0.12
package/build/main.js CHANGED
@@ -1405,7 +1405,7 @@ class euSec extends utils.Adapter {
1405
1405
  await this.setStateAsync("info.mqtt_connection", { val: false, ack: true });
1406
1406
  }
1407
1407
  async onStationCommandResult(station, result) {
1408
- if (result.return_code !== 0 && result.command_type !== import_eufy_security_client.CommandType.P2P_QUERY_STATUS_IN_LOCK) {
1408
+ if (result.return_code !== 0 && result.command_type !== import_eufy_security_client.CommandType.P2P_QUERY_STATUS_IN_LOCK && result.command_type !== import_eufy_security_client.CommandType.CMD_STORAGE_INFO_HB3 || result.return_code !== import_eufy_security_client.ErrorCode.ERROR_DEV_BUSY && result.command_type === import_eufy_security_client.CommandType.CMD_STORAGE_INFO_HB3) {
1409
1409
  this.logger.error(`Station: ${station.getSerial()} command ${import_eufy_security_client.CommandType[result.command_type]} failed with error: ${import_eufy_security_client.ErrorCode[result.return_code]} (${result.return_code})`);
1410
1410
  }
1411
1411
  }
package/build/main.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/main.ts"],
4
- "sourcesContent": ["/*\r\n * Created with @iobroker/create-adapter v2.5.0\r\n */\r\n\r\n// The adapter-core module gives you access to the core ioBroker functions\r\n// you need to create an adapter\r\nimport * as utils from \"@iobroker/adapter-core\";\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nimport { strict } from \"assert\";\r\nimport * as path from \"path\";\r\nimport { Camera, Device, Station, PushMessage, P2PConnectionType, EufySecurity, EufySecurityConfig, CommandResult, CommandType, ErrorCode, PropertyValue, PropertyName, StreamMetadata, PropertyMetadataNumeric, PropertyMetadataAny, CommandName, PanTiltDirection, DeviceNotFoundError, LoginOptions, Picture, StationNotFoundError, ensureError, LogLevel } from \"eufy-security-client\";\r\nimport { getAlpha2Code as getCountryCode } from \"i18n-iso-countries\"\r\nimport { isValid as isValidLanguageCode } from \"@cospired/i18n-iso-languages\"\r\nimport { Readable } from \"stream\";\r\nimport util from \"util\";\r\nimport childProcess from \"child_process\";\r\nimport pathToGo2rtc from \"go2rtc-static\";\r\nimport pathToFfmpeg from \"ffmpeg-for-homebridge\";\r\n\r\nimport { DeviceStateID, DataLocation, RoleMapping, StationStateID } from \"./lib/types\";\r\nimport { convertCamelCaseToSnakeCase, getImageAsHTML, handleUpdate, removeFiles, removeLastChar, setStateChangedAsync } from \"./lib/utils\";\r\nimport { PersistentData } from \"./lib/interfaces\";\r\nimport { ioBrokerLogger } from \"./lib/log\";\r\nimport { streamToGo2rtc } from \"./lib/video\";\r\n\r\nexport class euSec extends utils.Adapter {\r\n\r\n private eufy!: EufySecurity;\r\n /*private downloadEvent: {\r\n [index: string]: NodeJS.Timeout;\r\n } = {};*/\r\n\r\n private persistentFile: string = \"adapter.json\";\r\n private persistentDriverFile: string = \"driver.json\";\r\n private logger!: ioBrokerLogger;\r\n private persistentData: PersistentData = {\r\n version: \"\"\r\n };\r\n private captchaId: string | null = null;\r\n private verify_code = false;\r\n private skipInit = false;\r\n\r\n public constructor(options: Partial<utils.AdapterOptions> = {}) {\r\n super({\r\n ...options,\r\n name: \"eusec\",\r\n });\r\n\r\n this.on(\"ready\", this.onReady.bind(this));\r\n this.on(\"stateChange\", this.onStateChange.bind(this));\r\n // this.on(\"objectChange\", this.onObjectChange.bind(this));\r\n this.on(\"message\", this.onMessage.bind(this));\r\n this.on(\"unload\", this.onUnload.bind(this));\r\n }\r\n\r\n public restartAdapter(): void {\r\n this.skipInit = true;\r\n this.restart();\r\n }\r\n\r\n /**\r\n * Is called when databases are connected and adapter received configuration.\r\n */\r\n private async onReady(): Promise<void> {\r\n\r\n this.logger = new ioBrokerLogger(this.log as ioBroker.Logger);\r\n\r\n await this.setObjectNotExistsAsync(\"verify_code\", {\r\n type: \"state\",\r\n common: {\r\n name: \"2FA verification code\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"received_captcha_html\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Received captcha image HTML\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"captcha\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Enter captcha\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Global connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: false, ack: true });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: false, ack: true });\r\n\r\n try {\r\n const connection = await this.getStatesAsync(\"*.connection\");\r\n if (connection)\r\n Object.keys(connection).forEach(async id => {\r\n await this.setStateAsync(id, { val: false, ack: true });\r\n });\r\n } catch (error) {\r\n this.logger.error(\"Reset connection states - Error\", error);\r\n }\r\n\r\n try {\r\n const sensorList = [\r\n PropertyName.DeviceMotionDetected,\r\n PropertyName.DevicePersonDetected,\r\n PropertyName.DeviceSoundDetected,\r\n PropertyName.DeviceCryingDetected,\r\n PropertyName.DevicePetDetected,\r\n PropertyName.DeviceRinging\r\n ];\r\n for(const sensorName of sensorList) {\r\n const sensors = await this.getStatesAsync(`*.${convertCamelCaseToSnakeCase(sensorName)}`);\r\n if (sensors)\r\n Object.keys(sensors).forEach(async id => {\r\n await this.setStateAsync(id, { val: false, ack: true });\r\n });\r\n }\r\n } catch (error) {\r\n this.logger.error(\"Reset sensor states - Error\", error);\r\n }\r\n\r\n try {\r\n if (await this.fileExistsAsync(this.namespace, this.persistentFile)) {\r\n const fileContent = await this.readFileAsync(this.namespace, this.persistentFile);\r\n this.persistentData = JSON.parse(fileContent.file.toString(\"utf8\")) as PersistentData;\r\n }\r\n } catch (error) {\r\n this.logger.debug(\"No adapter stored data from last exit found.\", error);\r\n }\r\n\r\n let persistentDriverData: string = \"{}\";\r\n try {\r\n if (await this.fileExistsAsync(this.namespace, this.persistentDriverFile)) {\r\n const fileContent = await this.readFileAsync(this.namespace, this.persistentDriverFile);\r\n persistentDriverData = fileContent.file.toString(\"utf8\");\r\n }\r\n } catch (error) {\r\n this.logger.debug(\"No driver stored data from last exit found.\", error);\r\n }\r\n\r\n this.subscribeStates(\"verify_code\");\r\n this.subscribeStates(\"captcha\");\r\n\r\n const hosts = await this.getForeignObjectsAsync(\"system.host.*\", \"host\");\r\n if (hosts !== undefined && hosts !== null && Object.values(hosts).length !== 0) {\r\n if (this.config.hostname === \"\") {\r\n this.config.hostname = Object.values(hosts)[0].native.os.hostname;\r\n }\r\n\r\n const nodeVersion = Object.values(hosts)[0].native.process.versions.node;\r\n const nodeMajorVersion = nodeVersion.split(\".\")[0];\r\n\r\n let fixNeeded;\r\n switch (parseInt(nodeMajorVersion)) {\r\n case 18:\r\n fixNeeded = nodeVersion.localeCompare(\"18.19.1\", undefined, { numeric: true, sensitivity: \"base\" });\r\n break;\r\n case 20:\r\n fixNeeded = nodeVersion.localeCompare(\"20.11.1\", undefined, { numeric: true, sensitivity: \"base\" });\r\n break;\r\n default:\r\n fixNeeded = nodeVersion.localeCompare(\"21.6.2\", undefined, { numeric: true, sensitivity: \"base\" });\r\n break;\r\n }\r\n if (fixNeeded >= 0) {\r\n const adapter = await this.getForeignObjectAsync(`system.adapter.${this.namespace}`);\r\n if (adapter !== undefined && adapter !== null) {\r\n if (!adapter.common.nodeProcessParams?.includes(\"--security-revert=CVE-2023-46809\")) {\r\n adapter.common.nodeProcessParams = [\"--security-revert=CVE-2023-46809\"]\r\n await this.setForeignObjectAsync(`system.adapter.${this.namespace}`, adapter);\r\n this.log.warn(\"Required fix to use livestreaming with this version of Node.js (CVE-2023-46809) applied. Restart of the adapter initiated to activate the fix.\");\r\n this.restartAdapter();\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (!this.skipInit) {\r\n const systemConfig = await this.getForeignObjectAsync(\"system.config\");\r\n let countryCode = undefined;\r\n let languageCode = undefined;\r\n if (systemConfig) {\r\n countryCode = getCountryCode(systemConfig.common.country!, \"en\");\r\n if (isValidLanguageCode(systemConfig.common.language))\r\n languageCode = systemConfig.common.language;\r\n }\r\n if (this.config.country !== \"iobroker\") {\r\n countryCode = this.config.country;\r\n }\r\n\r\n // Handling adapter version update\r\n try {\r\n if (this.persistentData.version !== this.version) {\r\n const currentVersion = Number.parseFloat(removeLastChar(this.version!, \".\"));\r\n const previousVersion = this.persistentData.version !== \"\" && this.persistentData.version !== undefined ? Number.parseFloat(removeLastChar(this.persistentData.version, \".\")) : 0;\r\n this.logger.debug(`Handling of adapter update - currentVersion: ${currentVersion} previousVersion: ${previousVersion}`);\r\n\r\n if (previousVersion < currentVersion) {\r\n await handleUpdate(this, this.logger, previousVersion, currentVersion);\r\n this.persistentData.version = this.version!;\r\n await this.writePersistentData();\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`Handling of adapter update - Error:`, error);\r\n }\r\n\r\n let connectionType = P2PConnectionType.QUICKEST;\r\n if (this.config.p2pConnectionType === \"only_local\") {\r\n connectionType = P2PConnectionType.ONLY_LOCAL;\r\n }\r\n\r\n if (this.config.username !== \"\" && this.config.password !== \"\") {\r\n const config: EufySecurityConfig = {\r\n username: this.config.username,\r\n password: this.config.password,\r\n country: countryCode,\r\n language: languageCode,\r\n persistentData: persistentDriverData,\r\n eventDurationSeconds: this.config.eventDuration,\r\n p2pConnectionSetup: connectionType,\r\n pollingIntervalMinutes: this.config.pollingInterval,\r\n acceptInvitations: this.config.acceptInvitations,\r\n logging: {\r\n level: this.log.level === \"silly\" ? LogLevel.Trace : this.log.level === \"debug\" ? LogLevel.Debug : this.log.level === \"info\" ? LogLevel.Info : this.log.level === \"warn\" ? LogLevel.Warn : this.log.level === \"error\" ? LogLevel.Error : LogLevel.Info\r\n }\r\n };\r\n\r\n this.eufy = await EufySecurity.initialize(config, this.logger);\r\n this.eufy.on(\"persistent data\", (data: string) => this.onPersistentData(data))\r\n this.eufy.on(\"station added\", (station: Station) => this.onStationAdded(station));\r\n this.eufy.on(\"device added\", (device: Device) => this.onDeviceAdded(device));\r\n this.eufy.on(\"station removed\", (station: Station) => this.onStationRemoved(station));\r\n this.eufy.on(\"device removed\", (device: Device) => this.onDeviceRemoved(device));\r\n this.eufy.on(\"push message\", (messages) => this.handlePushNotification(messages));\r\n this.eufy.on(\"push connect\", () => this.onPushConnect());\r\n this.eufy.on(\"push close\", () => this.onPushClose());\r\n this.eufy.on(\"mqtt connect\", () => this.onMQTTConnect());\r\n this.eufy.on(\"mqtt close\", () => this.onMQTTClose());\r\n this.eufy.on(\"connect\", () => this.onConnect());\r\n this.eufy.on(\"close\", () => this.onClose());\r\n\r\n this.eufy.on(\"device property changed\", (device: Device, name: string, value: PropertyValue) => this.onDevicePropertyChanged(device, name, value));\r\n\r\n this.eufy.on(\"station command result\", (station: Station, result: CommandResult) => this.onStationCommandResult(station, result));\r\n //this.eufy.on(\"station download start\", (station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable) => this.onStationDownloadStart(station, device, metadata, videostream, audiostream));\r\n //this.eufy.on(\"station download finish\", (station: Station, device: Device) => this.onStationDownloadFinish(station, device));\r\n this.eufy.on(\"station livestream start\", (station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable) => this.onStationLivestreamStart(station, device, metadata, videostream, audiostream));\r\n this.eufy.on(\"station livestream stop\", (station: Station, device: Device) => this.onStationLivestreamStop(station, device));\r\n this.eufy.on(\"station rtsp url\", (station: Station, device: Device, value: string) => this.onStationRTSPUrl(station, device, value));\r\n this.eufy.on(\"station property changed\", (station: Station, name: string, value: PropertyValue) => this.onStationPropertyChanged(station, name, value));\r\n this.eufy.on(\"station connect\", (station: Station) => this.onStationConnect(station));\r\n this.eufy.on(\"station close\", (station: Station) => this.onStationClose(station));\r\n this.eufy.on(\"tfa request\", () => this.onTFARequest());\r\n this.eufy.on(\"captcha request\", (captchaId: string, captcha: string) => this.onCaptchaRequest(captchaId, captcha));\r\n this.eufy.setCameraMaxLivestreamDuration(this.config.maxLivestreamDuration);\r\n\r\n await this.eufy.connect();\r\n\r\n if (pathToGo2rtc) {\r\n const go2rtcConfig: {\r\n [index: string]: {\r\n [index: string]: string | number | null\r\n }\r\n } = {\r\n \"api\": {\r\n \"listen\": `:${this.config.go2rtc_api_port}`\r\n },\r\n \"rtsp\": {\r\n \"listen\": `:${this.config.go2rtc_rtsp_port}`\r\n },\r\n \"srtp\": {\r\n \"listen\": `:${this.config.go2rtc_srtp_port}`\r\n },\r\n \"webrtc\": {\r\n \"listen\": `:${this.config.go2rtc_webrtc_port}`\r\n },\r\n \"ffmpeg\": {\r\n \"bin\": pathToFfmpeg !== \"\" && pathToFfmpeg !== undefined ? pathToFfmpeg : \"ffmpeg\",\r\n },\r\n \"streams\": {},\r\n /*\"log\": {\r\n \"level\": \"debug\", // default level\r\n \"api\": \"debug\",\r\n \"exec\": \"debug\",\r\n \"ngrok\": \"debug\",\r\n \"rtsp\": \"debug\",\r\n \"streams\": \"debug\",\r\n \"webrtc\": \"debug\",\r\n }*/\r\n };\r\n if (this.config.go2rtc_rtsp_username !== \"\" && this.config.go2rtc_rtsp_password !== \"\") {\r\n go2rtcConfig.rtsp.username = this.config.go2rtc_rtsp_username;\r\n go2rtcConfig.rtsp.password = this.config.go2rtc_rtsp_password;\r\n }\r\n for (const device of await this.eufy.getDevices()) {\r\n go2rtcConfig.streams[device.getSerial()] = null;\r\n }\r\n const go2rtc = childProcess.spawn(pathToGo2rtc, [\"-config\", JSON.stringify(go2rtcConfig)], { shell: false, detached: false, windowsHide: true });\r\n go2rtc.on(\"error\", (error) => {\r\n this.log.error(`go2rtc error: ${error}`);\r\n });\r\n go2rtc.stdout.setEncoding(\"utf8\");\r\n go2rtc.stdout.on(\"data\", (data) => {\r\n this.log.info(`go2rtc started: ${data}`);\r\n });\r\n go2rtc.stderr.setEncoding(\"utf8\");\r\n go2rtc.stderr.on(\"data\", (data) => {\r\n this.log.error(`go2rtc error: ${data}`);\r\n });\r\n go2rtc.on(\"close\", (exitcode) => {\r\n this.log.info(`go2rtc terminated with exitcode ${exitcode}`);\r\n });\r\n process.on(\"exit\", () => {\r\n go2rtc.kill();\r\n });\r\n }\r\n }\r\n // Delete cunknown channels without childs\r\n const channels = await this.getChannelsAsync();\r\n for (const channel of channels) {\r\n if (channel.common.name === \"unknown\") {\r\n const states = await this.getStatesAsync(`${channel._id}.*`);\r\n if (Object.keys(states).length === 0) {\r\n await this.delObjectAsync(channel._id);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n public async writePersistentData(): Promise<void> {\r\n try {\r\n await this.writeFileAsync(this.namespace, this.persistentFile, JSON.stringify(this.persistentData));\r\n } catch(error) {\r\n this.logger.error(`writePersistentData() - Error: ${error}`);\r\n }\r\n }\r\n\r\n private onPersistentData(data: string): void {\r\n this.writeFileAsync(this.namespace, this.persistentDriverFile, data).catch((error) => {\r\n this.logger.error(`writePersistentDriverData() - Error: ${error}`);\r\n });\r\n }\r\n\r\n /**\r\n * Is called when adapter shuts down - callback has to be called under any circumstances!\r\n */\r\n private async onUnload(callback: () => void): Promise<void> {\r\n try {\r\n\r\n await this.writePersistentData();\r\n\r\n if (this.eufy) {\r\n if (this.eufy.isConnected())\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true }).catch();\r\n this.eufy.removeAllListeners();\r\n this.eufy.close();\r\n }\r\n\r\n callback();\r\n } catch (e) {\r\n callback();\r\n }\r\n }\r\n\r\n // If you need to react to object changes, uncomment the following block and the corresponding line in the constructor.\r\n // You also need to subscribe to the objects with `this.subscribeObjects`, similar to `this.subscribeStates`.\r\n // /**\r\n // * Is called if a subscribed object changes\r\n // */\r\n // private onObjectChange(id: string, obj: ioBroker.Object | null | undefined): void {\r\n // if (obj) {\r\n // // The object was changed\r\n // this.log.info(`object ${id} changed: ${JSON.stringify(obj)}`);\r\n // } else {\r\n // // The object was deleted\r\n // this.log.info(`object ${id} deleted`);\r\n // }\r\n // }\r\n\r\n /**\r\n * Is called if a subscribed state changes\r\n */\r\n private async onStateChange(id: string, state: ioBroker.State | null | undefined): Promise<void> {\r\n if (state) {\r\n\r\n // don't do anything if the state is acked\r\n if (!id || state.ack) {\r\n this.logger.debug(`state ${id} changed: ${state.val} (ack = ${state.ack}) was already acknowledged, ignore it...`);\r\n return;\r\n }\r\n this.logger.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`);\r\n\r\n const values = id.split(\".\");\r\n const station_sn = values[2];\r\n const device_type = values[3];\r\n\r\n if (station_sn == \"verify_code\") {\r\n if (this.eufy && this.verify_code) {\r\n this.logger.info(`Verification code received, send it. (verify_code: ${state.val})`);\r\n await this.eufy.connect({ verifyCode: state.val as string } as LoginOptions);\r\n this.verify_code = false;\r\n await this.delStateAsync(id);\r\n }\r\n } else if (station_sn == \"captcha\") {\r\n if (this.eufy && this.captchaId) {\r\n this.logger.info(`Captcha received, send it. (captcha: ${state.val})`);\r\n await this.eufy.connect({\r\n captcha: {\r\n captchaCode: state.val as string,\r\n captchaId: this.captchaId\r\n }\r\n } as LoginOptions);\r\n this.captchaId = null;\r\n await this.delStateAsync(id);\r\n await this.delStateAsync(\"received_captcha_html\");\r\n }\r\n } else if (device_type == \"station\") {\r\n try {\r\n const station_state_name = values[4];\r\n if (this.eufy) {\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n if (obj.native.name !== undefined) {\r\n await this.eufy.setStationProperty(station_sn, obj.native.name, state.val);\r\n return;\r\n }\r\n }\r\n\r\n const station = await this.eufy.getStation(station_sn);\r\n switch(station_state_name) {\r\n case StationStateID.REBOOT:\r\n await station.rebootHUB();\r\n break;\r\n case StationStateID.TRIGGER_ALARM_SOUND:\r\n await station.triggerStationAlarmSound(this.config.alarmSoundDuration);\r\n break;\r\n case StationStateID.RESET_ALARM_SOUND:\r\n await station.resetStationAlarmSound();\r\n break;\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`station - Error:`, error);\r\n }\r\n } else {\r\n try {\r\n const device_sn = values[4];\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n if (obj.native.name !== undefined) {\r\n try {\r\n await this.eufy.setDeviceProperty(device_sn, obj.native.name, obj.common.type === \"object\" ? JSON.parse(state.val as string) : state.val);\r\n } catch (error) {\r\n this.logger.error(`Error in setting property value (property: ${obj.native.name} value: ${state.val})`, error);\r\n }\r\n return;\r\n }\r\n }\r\n\r\n const device_state_name = values[5];\r\n const station = await this.eufy.getStation(station_sn);\r\n const device = await this.eufy.getDevice(device_sn);\r\n\r\n switch(device_state_name) {\r\n case DeviceStateID.START_STREAM:\r\n await this.startLivestream(device_sn);\r\n break;\r\n case DeviceStateID.STOP_STREAM:\r\n await this.stopLivestream(device_sn);\r\n break;\r\n case DeviceStateID.TRIGGER_ALARM_SOUND:\r\n await station.triggerDeviceAlarmSound(device, this.config.alarmSoundDuration);\r\n break;\r\n case DeviceStateID.RESET_ALARM_SOUND:\r\n await station.resetDeviceAlarmSound(device);\r\n break;\r\n case DeviceStateID.ROTATE_360:\r\n await station.panAndTilt(device, PanTiltDirection.ROTATE360);\r\n break;\r\n case DeviceStateID.PAN_LEFT:\r\n await station.panAndTilt(device, PanTiltDirection.LEFT);\r\n break;\r\n case DeviceStateID.PAN_RIGHT:\r\n await station.panAndTilt(device, PanTiltDirection.RIGHT);\r\n break;\r\n case DeviceStateID.TILT_UP:\r\n await station.panAndTilt(device, PanTiltDirection.UP);\r\n break;\r\n case DeviceStateID.TILT_DOWN:\r\n await station.panAndTilt(device, PanTiltDirection.DOWN);\r\n break;\r\n case DeviceStateID.CALIBRATE:\r\n if (device.isLock()) {\r\n await station.calibrateLock(device);\r\n } else {\r\n await station.calibrate(device);\r\n }\r\n break;\r\n case DeviceStateID.UNLOCK:\r\n await station.unlock(device);\r\n break;\r\n case DeviceStateID.SET_DEFAULT_ANGLE:\r\n await station.setDefaultAngle(device);\r\n break;\r\n case DeviceStateID.SET_PRIVACY_ANGLE:\r\n await station.setPrivacyAngle(device);\r\n break;\r\n case DeviceStateID.OPEN_BOX:\r\n await station.open(device);\r\n break;\r\n }\r\n } catch (error) {\r\n this.logger.error(`cameras - Error:`, error);\r\n }\r\n }\r\n } else {\r\n // The state was deleted\r\n this.logger.debug(`state ${id} deleted`);\r\n }\r\n }\r\n\r\n /**\r\n * Some message was sent to this instance over message box. Used by email, pushover, text2speech, ...\r\n * Using this method requires \"common.message\" property to be set to true in io-package.json\r\n */\r\n private async onMessage(obj: ioBroker.Message): Promise<void> {\r\n if (typeof obj === \"object\" && obj.message) {\r\n try {\r\n if (obj.command === \"quickResponse\") {\r\n this.log.debug(`quickResponse command - message: ${JSON.stringify(obj.message)}`);\r\n if (typeof obj.message === \"object\" &&\r\n typeof obj.message.station_sn === \"string\" && obj.message.station_sn !== \"\" &&\r\n typeof obj.message.device_sn === \"string\" && obj.message.device_sn !== \"\" &&\r\n typeof obj.message.voice_id === \"number\") {\r\n try {\r\n const station = await this.eufy.getStation(obj.message.station_sn);\r\n const device = await this.eufy.getDevice(obj.message.device_sn);\r\n\r\n if (device.hasCommand(CommandName.DeviceQuickResponse)) {\r\n await station.quickResponse(device, obj.message.voice_id);\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: true,\r\n result: \"quickResponse command sended\"\r\n }, obj.callback);\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"quickResponse command not supported by specified device\"\r\n }, obj.callback);\r\n }\r\n } catch (error) {\r\n if (error instanceof StationNotFoundError) {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"quickResponse command not sended because specified station doesn't exists\"\r\n }, obj.callback);\r\n } else if (error instanceof DeviceNotFoundError) {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"quickResponse command not sended because specified device doesn't exists\"\r\n }, obj.callback);\r\n } else {\r\n throw error;\r\n }\r\n }\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"quickResponse command not sended because some required parameters are missing\"\r\n }, obj.callback);\r\n }\r\n } else if (obj.command === \"getQuickResponseVoices\") {\r\n this.log.debug(`getQuickResponseVoices command - message: ${JSON.stringify(obj.message)}`);\r\n if (typeof obj.message === \"object\" &&\r\n typeof obj.message.device_sn === \"string\" && obj.message.device_sn !== \"\") {\r\n const voices = await this.eufy.getApi().getVoices(obj.message.device_sn);\r\n\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: true,\r\n result: voices\r\n }, obj.callback);\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"getQuickResponseVoices command not sended because some required parameters are missing\"\r\n }, obj.callback);\r\n }\r\n } else if (obj.command === \"snooze\") {\r\n this.log.debug(`snooze command - message: ${JSON.stringify(obj.message)}`);\r\n if (typeof obj.message === \"object\" &&\r\n typeof obj.message.station_sn === \"string\" && obj.message.station_sn !== \"\" &&\r\n typeof obj.message.device_sn === \"string\" && obj.message.device_sn !== \"\" &&\r\n typeof obj.message.snooze_time === \"number\" &&\r\n (obj.message.snooze_chime === undefined || typeof obj.message.snooze_chime === \"boolean\") &&\r\n (obj.message.snooze_homebase === undefined || typeof obj.message.snooze_homebase === \"boolean\") &&\r\n (obj.message.snooze_motion === undefined || typeof obj.message.snooze_motion === \"boolean\")) {\r\n try {\r\n const station = await this.eufy.getStation(obj.message.station_sn);\r\n const device = await this.eufy.getDevice(obj.message.device_sn);\r\n\r\n if (device.hasCommand(CommandName.DeviceSnooze)) {\r\n await station.snooze(device, {\r\n snooze_time: obj.message.snooze_time,\r\n snooze_chime: obj.message.snooze_chime,\r\n snooze_homebase: obj.message.snooze_homebase,\r\n snooze_motion: obj.message.snooze_motion,\r\n });\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: true,\r\n result: \"snooze command sended\"\r\n }, obj.callback);\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"snooze command not supported by specified device\"\r\n }, obj.callback);\r\n }\r\n } catch (error) {\r\n if (error instanceof StationNotFoundError) {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"snooze command not sended because specified station doesn't exists\"\r\n }, obj.callback);\r\n } else if (error instanceof DeviceNotFoundError) {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"snooze command not sended because specified device doesn't exists\"\r\n }, obj.callback);\r\n } else {\r\n throw error;\r\n }\r\n }\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"snooze command not sended because some required parameters are missing\"\r\n }, obj.callback);\r\n }\r\n } else if (obj.command === \"chime\") {\r\n this.log.debug(`snooze command - message: ${JSON.stringify(obj.message)}`);\r\n if (typeof obj.message === \"object\" &&\r\n typeof obj.message.station_sn === \"string\" && obj.message.station_sn !== \"\" &&\r\n (obj.message.ringtone === undefined || typeof obj.message.ringtone === \"number\")) {\r\n try {\r\n const station = await this.eufy.getStation(obj.message.station_sn);\r\n\r\n if (station.hasCommand(CommandName.StationChime)) {\r\n await station.chimeHomebase(obj.message.ringtone !== undefined && typeof obj.message.ringtone === \"number\" ? obj.message.ringtone : 0);\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: true,\r\n result: \"chime command sended\"\r\n }, obj.callback);\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"chime command not supported by specified station\"\r\n }, obj.callback);\r\n }\r\n\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, \"chime command sended\", obj.callback);\r\n } catch (error) {\r\n if (error instanceof StationNotFoundError) {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"snooze command not sended because specified station doesn't exists\"\r\n }, obj.callback);\r\n } else {\r\n throw error;\r\n }\r\n }\r\n }\r\n } else if (obj.command === \"pollRefresh\") {\r\n this.log.debug(`pollRefresh command`);\r\n await this.eufy.refreshCloudData();\r\n\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: true,\r\n result: \"pollRefresh command sended\"\r\n }, obj.callback);\r\n } else {\r\n const errorMessage = `Received unknown message: ${JSON.stringify(obj.message)}`;\r\n this.log.warn(errorMessage);\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: errorMessage\r\n }, obj.callback);\r\n }\r\n } catch (error) {\r\n const errorMessage = `Error during processing of received message: ${error instanceof Error ? `${error.name} - ${error.message}` : error }`;\r\n this.log.error(errorMessage);\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: errorMessage\r\n }, obj.callback);\r\n }\r\n }\r\n }\r\n\r\n private getStateCommon(property: PropertyMetadataAny): ioBroker.StateCommon {\r\n const state: ioBroker.StateCommon = {\r\n name: property.label!,\r\n type: property.type,\r\n role: \"state\",\r\n read: property.readable,\r\n write: property.writeable,\r\n def: property.type === \"object\" && typeof property.default === \"object\" ? JSON.stringify(property.default) : property.default\r\n };\r\n switch (property.type) {\r\n case \"number\": {\r\n const numberProperty = property as PropertyMetadataNumeric;\r\n state.min = numberProperty.min;\r\n state.max = numberProperty.max;\r\n state.states = numberProperty.states;\r\n state.unit = numberProperty.unit;\r\n state.step = numberProperty.steps;\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : \"value\";\r\n break;\r\n }\r\n case \"string\": {\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : \"text\";\r\n break;\r\n }\r\n case \"boolean\": {\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : (property.writeable ? \"switch.enable\" : \"state\");\r\n break;\r\n }\r\n }\r\n return state;\r\n }\r\n\r\n private async createAndSetState(device: Device | Station, property: PropertyMetadataAny): Promise<void> {\r\n if (property.name !== PropertyName.Type && property.name !== PropertyName.DeviceStationSN) {\r\n const state = this.getStateCommon(property);\r\n const id: string = device.getStateID(convertCamelCaseToSnakeCase(property.name));\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n let changed = false;\r\n if (obj.native.name !== undefined && obj.native.name !== property.name) {\r\n obj.native.name = property.name;\r\n changed = true;\r\n }\r\n if (obj.native.key !== undefined && obj.native.key !== property.key) {\r\n obj.native.key = property.key;\r\n changed = true;\r\n }\r\n if (obj.native.commandId !== undefined && obj.native.commandId !== property.commandId) {\r\n obj.native.commandId = property.commandId;\r\n changed = true;\r\n }\r\n if (obj.common !== undefined && !util.isDeepStrictEqual(obj.common, state)) {\r\n changed = true;\r\n }\r\n if (changed) {\r\n const propertyMetadata = device.getPropertiesMetadata()[property.name];\r\n if (propertyMetadata !== undefined) {\r\n const newState = this.getStateCommon(propertyMetadata);\r\n obj.common = newState;\r\n }\r\n await this.setObjectAsync(id, obj);\r\n }\r\n } else {\r\n await this.setObjectNotExistsAsync(id, {\r\n type: \"state\",\r\n common: state,\r\n native: {\r\n key: property.key,\r\n commandId: property.commandId,\r\n name: property.name,\r\n },\r\n });\r\n }\r\n const value = device.getPropertyValue(property.name);\r\n if (value !== undefined)\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, id, (property.type === \"string\" || property.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n }\r\n }\r\n\r\n private async onDeviceAdded(device: Device): Promise<void> {\r\n this.logger.debug(`onDeviceAdded - device: ${device.getSerial()}`);\r\n\r\n await this.setObjectNotExistsAsync(device.getStateID(\"\", 0), {\r\n type: \"channel\",\r\n common: {\r\n name: device.getStateChannel()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(device.getStateID(\"\", 1), {\r\n type: \"device\",\r\n common: {\r\n name: device.getName()\r\n },\r\n native: {},\r\n });\r\n\r\n const metadata = device.getPropertiesMetadata();\r\n for(const property of Object.values(metadata)) {\r\n if (property.name !== PropertyName.DevicePicture)\r\n this.createAndSetState(device, property);\r\n }\r\n\r\n if (device.hasProperty(PropertyName.DevicePicture)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PICTURE_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Picture URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PICTURE_HTML), {\r\n type: \"state\",\r\n common: {\r\n name: \"Picture HTML image\",\r\n type: \"string\",\r\n role: \"html\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n if (device.hasCommand(CommandName.DeviceTriggerAlarmSound)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TRIGGER_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Trigger Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.RESET_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reset Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DevicePanAndTilt)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PAN_LEFT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Pan Left\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PAN_RIGHT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Pan Right\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.ROTATE_360), {\r\n type: \"state\",\r\n common: {\r\n name: \"Rotate 360\u00B0\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TILT_UP), {\r\n type: \"state\",\r\n common: {\r\n name: \"Tilt Up\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TILT_DOWN), {\r\n type: \"state\",\r\n common: {\r\n name: \"Tilt Down\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceLockCalibration)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.CALIBRATE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Calibrate Lock\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceUnlock)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.UNLOCK), {\r\n type: \"state\",\r\n common: {\r\n name: \"Unlock\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceSetDefaultAngle)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.SET_DEFAULT_ANGLE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Set Default Angle\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceSetPrivacyAngle)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.SET_PRIVACY_ANGLE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Set Default Angle\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceCalibrate)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.CALIBRATE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Calibrate\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceOpen)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.OPEN_BOX), {\r\n type: \"state\",\r\n common: {\r\n name: \"Open Box\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceStartLivestream)) {\r\n // Start Stream\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.START_STREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Start stream\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n\r\n // Stop Stream\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.STOP_STREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Stop stream\",\r\n type: \"boolean\",\r\n role: \"button.stop\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n\r\n // Livestream URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LIVESTREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Livestream URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n\r\n // Livestream RTSP URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP), {\r\n type: \"state\",\r\n common: {\r\n name: \"Livestream RTSP URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n if (device.hasProperty(PropertyName.DeviceRTSPStream)) {\r\n // RTSP Stream URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.RTSP_STREAM_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"RTSP stream URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n /*if (device.hasCommand(CommandName.DeviceStartDownload)) {\r\n // Last event video URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_VIDEO_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event video URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n\r\n // Last event picture URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_PIC_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event picture URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n\r\n // Last event picture HTML image\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_PIC_HTML), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event picture HTML image\",\r\n type: \"string\",\r\n role: \"html\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n }*/\r\n }\r\n\r\n private async onDeviceRemoved(device: Device): Promise<void> {\r\n this.delObjectAsync(device.getStateID(\"\", 0), { recursive: true }).catch((error) => {\r\n this.logger.error(`Error deleting states of removed device`, error);\r\n });\r\n removeFiles(this as unknown as ioBroker.Adapter, device.getStationSerial(), DataLocation.LAST_EVENT, device.getSerial()).catch((error) => {\r\n this.logger.error(`Error deleting fs contents of removed device`, error);\r\n });\r\n }\r\n\r\n private async onStationAdded(station: Station): Promise<void> {\r\n this.subscribeStates(`${station.getStateID(\"\", 0)}.*`);\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(\"\", 0), {\r\n type: \"device\",\r\n common: {\r\n name: station.getName()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(\"\", 1), {\r\n type: \"channel\",\r\n common: {\r\n name: station.getStateChannel()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: false, ack: true });\r\n\r\n const metadata = station.getPropertiesMetadata();\r\n for(const property of Object.values(metadata)) {\r\n this.createAndSetState(station, property);\r\n }\r\n\r\n // Reboot station\r\n if (station.hasCommand(CommandName.StationReboot)) {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.REBOOT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reboot station\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n // Alarm Sound\r\n if (station.hasCommand(CommandName.StationTriggerAlarmSound)) {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.TRIGGER_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Trigger Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.RESET_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reset Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n }\r\n\r\n private async onStationRemoved(station: Station): Promise<void> {\r\n this.delObjectAsync(station.getStateID(\"\", 0), { recursive: true }).catch((error) => {\r\n this.logger.error(`Error deleting states of removed station`, error);\r\n });\r\n this.delFileAsync(this.namespace, station.getSerial()).catch((error) => {\r\n this.logger.error(`Error deleting fs contents of removed station`, error);\r\n });\r\n }\r\n\r\n /*private async downloadEventVideo(device: Device, event_time: number, full_path: string | undefined, cipher_id: number | undefined): Promise<void> {\r\n this.logger.debug(`Device: ${device.getSerial()} full_path: ${full_path} cipher_id: ${cipher_id}`);\r\n try {\r\n if (!isEmpty(full_path) && cipher_id !== undefined) {\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n\r\n if (station !== undefined) {\r\n if (this.downloadEvent[device.getSerial()])\r\n clearTimeout(this.downloadEvent[device.getSerial()]);\r\n\r\n let videoLength = getVideoClipLength(device);\r\n const time_passed = (new Date().getTime() - new Date(event_time).getTime()) / 1000;\r\n\r\n if (time_passed >= videoLength)\r\n videoLength = 1;\r\n else\r\n videoLength = videoLength - time_passed;\r\n\r\n this.logger.info(`Downloading video event for device ${device.getSerial()} in ${videoLength} seconds...`);\r\n this.downloadEvent[device.getSerial()] = setTimeout(async () => {\r\n station.startDownload(device, full_path!, cipher_id);\r\n }, videoLength * 1000);\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`Device: ${device.getSerial()} - Error`, error);\r\n }\r\n }*/\r\n\r\n private async handlePushNotification(message: PushMessage): Promise<void> {\r\n try {\r\n if (message.device_sn !== undefined) {\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n /*const device: Device = await this.eufy.getDevice(message.device_sn);\r\n if ((message.push_count === 1 || message.push_count === undefined) && (message.file_path !== undefined && message.file_path !== \"\" && message.cipher !== undefined))\r\n if (this.config.autoDownloadVideo)\r\n await this.downloadEventVideo(device, message.event_time, message.file_path, message.cipher);*/\r\n }\r\n } catch (error) {\r\n if (error instanceof DeviceNotFoundError) {\r\n //Do nothing\r\n } else {\r\n this.logger.error(\"Handling push notification - Error\", error);\r\n }\r\n }\r\n }\r\n\r\n private async onConnect(): Promise<void> {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Global connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.connection\", { val: true, ack: true });\r\n\r\n const stations = await this.eufy.getStations();\r\n const stationSerials: string[] = [];\r\n for(const station of stations) {\r\n stationSerials.push(station.getSerial());\r\n }\r\n const devices = await this.eufy.getDevices();\r\n const deviceSerials: string[] = [];\r\n for(const device of devices) {\r\n deviceSerials.push(device.getSerial());\r\n }\r\n\r\n // Delete obsolete stations\r\n try {\r\n const allDevices = await this.getDevicesAsync();\r\n const reg = new RegExp(`^${this.namespace}\\.[0-9A-Z]+$`);\r\n for (const id of allDevices) {\r\n if (id._id.match(reg)) {\r\n const serial = id._id.replace(`${this.namespace}.`, \"\");\r\n if (!stationSerials.includes(serial)) {\r\n await this.delObjectAsync(id._id, { recursive: true });\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete stations ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete devices\r\n try {\r\n const allDevices = await this.getDevicesAsync();\r\n const reg = new RegExp(`^${this.namespace}\\.[0-9A-Z]+\\.[a-z]+\\.[0-9A-Z]+$`);\r\n for (const id of allDevices) {\r\n if (id._id.match(reg)) {\r\n const values = id._id.split(\".\");\r\n const stateChannel = values[3];\r\n const serial = values[4];\r\n if (!deviceSerials.includes(serial) ||\r\n (deviceSerials.includes(serial) && devices[deviceSerials.indexOf(serial)].getStateChannel() !== \"unknown\" && stateChannel === \"unknown\")) {\r\n await this.delObjectAsync(id._id, { recursive: true });\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete devices ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete properties\r\n try {\r\n const all = await this.getStatesAsync(\"*\");\r\n if (all) {\r\n Object.keys(all).forEach(async (stateid) => {\r\n const object = await this.getObjectAsync(stateid);\r\n if (object?.native?.name !== undefined) {\r\n const tmp = stateid.split(\".\");\r\n if (tmp.length >= 5) {\r\n const stationSerial = tmp[2];\r\n const deviceSerial = tmp[4];\r\n\r\n if (deviceSerial.match(/^[A-Z0-9]+/)) {\r\n // Device\r\n try {\r\n const device = await this.eufy.getDevice(deviceSerial);\r\n if (!device.hasProperty(object.native.name)) {\r\n this.delObjectAsync(stateid);\r\n }\r\n } catch (error) {\r\n if (error instanceof DeviceNotFoundError) {\r\n } else {\r\n this.log.error(`Delete obsolete properties ERROR - device - ${JSON.stringify(error)}`);\r\n }\r\n }\r\n } else {\r\n // Station\r\n try {\r\n const station = await this.eufy.getStation(stationSerial);\r\n if (!station.hasProperty(object.native.name)) {\r\n this.delObjectAsync(stateid);\r\n }\r\n } catch (error) {\r\n if (error instanceof StationNotFoundError) {\r\n } else {\r\n this.log.error(`Delete obsolete properties ERROR - station - ${JSON.stringify(error)}`);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n });\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete properties ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete directories/files\r\n try {\r\n const contents = await this.readDirAsync(this.namespace, \"\");\r\n for (const content of contents.filter((fn) => fn.file.match(\"^T[0-9A-Z]+$\") !== null && fn.isDir)) {\r\n if (!stationSerials.includes(content.file)) {\r\n await this.delFileAsync(this.namespace, content.file);\r\n } else {\r\n const dirContents = await this.readDirAsync(this.namespace, content.file);\r\n for (const dir of dirContents.filter((fn) => Object.values(DataLocation).includes(fn.file) && fn.isDir)) {\r\n const files = await this.readDirAsync(this.namespace, path.join(content.file, dir.file));\r\n let deletedFiles = 0;\r\n for (const file of files.filter((fn) => !deviceSerials.includes(fn.file.substring(0, 16)) && !fn.isDir)) {\r\n await this.delFileAsync(this.namespace, path.join(content.file, dir.file, file.file));\r\n deletedFiles++;\r\n }\r\n if (deletedFiles === files.length) {\r\n await this.delFileAsync(this.namespace, path.join(content.file, dir.file));\r\n }\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete directories/files ERROR - ${error}`);\r\n }\r\n }\r\n\r\n private async onClose(): Promise<void> {\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true }).catch();\r\n }\r\n\r\n public getPersistentData(): PersistentData {\r\n return this.persistentData;\r\n }\r\n\r\n private async onPushConnect(): Promise<void> {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: true, ack: true });\r\n }\r\n\r\n private async onPushClose(): Promise<void> {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: false, ack: true });\r\n }\r\n\r\n private async onMQTTConnect(): Promise<void> {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: true, ack: true });\r\n }\r\n\r\n private async onMQTTClose(): Promise<void> {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: false, ack: true });\r\n }\r\n\r\n private async onStationCommandResult(station: Station, result: CommandResult): Promise<void> {\r\n if (result.return_code !== 0 && result.command_type !== CommandType.P2P_QUERY_STATUS_IN_LOCK) {\r\n this.logger.error(`Station: ${station.getSerial()} command ${CommandType[result.command_type]} failed with error: ${ErrorCode[result.return_code]} (${result.return_code})`);\r\n }\r\n }\r\n\r\n private async onStationPropertyChanged(station: Station, name: string, value: PropertyValue): Promise<void> {\r\n const states = await this.getStatesAsync(`${station.getStateID(\"\", 1)}.*`);\r\n for (const state in states) {\r\n const obj = await this.getObjectAsync(state);\r\n if (obj) {\r\n if (obj.native.name !== undefined && obj.native.name === name) {\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, state, (obj.common.type === \"string\" || obj.common.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n return;\r\n }\r\n }\r\n }\r\n this.logger.debug(`onStationPropertyChanged(): Property \"${name}\" not implemented in this adapter (station: ${station.getSerial()} value: ${JSON.stringify(value)})`);\r\n }\r\n\r\n private async onDevicePropertyChanged(device: Device, name: string, value: PropertyValue): Promise<void> {\r\n const states = await this.getStatesAsync(`${device.getStateID(\"\", 1)}.*`);\r\n for (const state in states) {\r\n const obj = await this.getObjectAsync(state);\r\n if (obj) {\r\n if (obj.native.name !== undefined && obj.native.name === name) {\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, state, (obj.common.type === \"string\" || obj.common.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n switch(name) {\r\n case PropertyName.DeviceRTSPStream:\r\n if (value as boolean === false) {\r\n this.delStateAsync(device.getStateID(DeviceStateID.RTSP_STREAM_URL));\r\n }\r\n break;\r\n }\r\n return;\r\n }\r\n }\r\n }\r\n if (name === PropertyName.DevicePicture) {\r\n try {\r\n const picture = value as Picture;\r\n const fileName = `${device.getSerial()}.${picture.type.ext}`;\r\n const filePath = path.join(device.getStationSerial(), DataLocation.LAST_EVENT);\r\n if (!await this.fileExistsAsync(this.namespace, filePath)) {\r\n await this.mkdirAsync(this.namespace, filePath);\r\n }\r\n await this.writeFileAsync(this.namespace, path.join(filePath, fileName), picture.data);\r\n\r\n await this.setStateAsync(device.getStateID(DeviceStateID.PICTURE_URL), `/files/${this.namespace}/${device.getStationSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}.${picture.type.ext}`, true);\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, device.getStateID(DeviceStateID.PICTURE_HTML), getImageAsHTML(picture.data, picture.type.mime));\r\n } catch (err) {\r\n const error = ensureError(err);\r\n this.logger.error(\"onDevicePropertyChanged - Property picture - Error\", error);\r\n }\r\n } else {\r\n this.logger.debug(`onDevicePropertyChanged(): Property \"${name}\" not implemented in this adapter (device: ${device.getSerial()} value: ${JSON.stringify(value)})`);\r\n }\r\n }\r\n\r\n private async startLivestream(device_sn: string): Promise<void> {\r\n try {\r\n const device = await this.eufy.getDevice(device_sn);\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n\r\n if (station.isConnected() || station.isEnergySavingDevice()) {\r\n if (!station.isLiveStreaming(device)) {\r\n this.eufy.startStationLivestream(device_sn);\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be started, because it is already streaming!`);\r\n }\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be started, because there is no connection to station ${station.getSerial()}!`);\r\n }\r\n } catch (error) {\r\n this.logger.error(\"Start livestream - Error\", error);\r\n }\r\n }\r\n\r\n private async stopLivestream(device_sn: string): Promise<void> {\r\n try {\r\n const device = await this.eufy.getDevice(device_sn);\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n if (device.isCamera()) {\r\n const camera = device as Camera;\r\n if (await this.eufy.isStationConnected(device.getStationSerial()) && station.isLiveStreaming(camera)) {\r\n await this.eufy.stopStationLivestream(device_sn);\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be stopped, because it isn't streaming!`);\r\n }\r\n }\r\n\r\n } catch (error) {\r\n this.logger.error(\"Stop livestream - Error\", error);\r\n }\r\n }\r\n\r\n private async onStationLivestreamStart(station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable): Promise<void> {\r\n try {\r\n this.setStateAsync(device.getStateID(DeviceStateID.LIVESTREAM), { val: `${this.config.https ? \"https\" : \"http\"}://${this.config.hostname}:${this.config.go2rtc_api_port}/stream.html?src=${device.getSerial()}`, ack: true });\r\n this.setStateAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP), { val: `rtsp://${this.config.hostname}:${this.config.go2rtc_rtsp_port}/${device.getSerial()}`, ack: true });\r\n //await ffmpegStreamToGo2rtc(this.config, this.namespace, device.getSerial(), metadata, videostream, audiostream, this.logger);\r\n await streamToGo2rtc(device.getSerial(), videostream, audiostream, this.logger, this.config, this.namespace, metadata).catch((error) => {\r\n this.logger.debug(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Stopping livestream...`, error);\r\n });\r\n } catch(error) {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Stopping livestream...`, error);\r\n this.eufy.stopStationLivestream(device.getSerial())\r\n .catch(async (error) => {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error during stopping livestream...`, error);\r\n });\r\n }\r\n }\r\n\r\n private onStationLivestreamStop(_station: Station, device: Device): void {\r\n this.delStateAsync(device.getStateID(DeviceStateID.LIVESTREAM));\r\n this.delStateAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP));\r\n }\r\n\r\n /*private async onStationDownloadFinish(_station: Station, _device: Device): Promise<void> {\r\n //this.logger.trace(`Station: ${station.getSerial()} channel: ${channel}`);\r\n }*/\r\n\r\n /*private async onStationDownloadStart(station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable): Promise<void> {\r\n try {\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n await removeFiles(this, station.getSerial(), DataLocation.TEMP, device.getSerial()).catch();\r\n const file_path = getDataFilePath(this, station.getSerial(), DataLocation.TEMP, `${device.getSerial()}${STREAM_FILE_NAME_EXT}`);\r\n\r\n await ffmpegStreamToHls(this.config, this.namespace, metadata, videostream, audiostream, file_path, this.logger)\r\n .then(async () => {\r\n if (fse.pathExistsSync(file_path)) {\r\n await removeFiles(this, station.getSerial(), DataLocation.LAST_EVENT, device.getSerial());\r\n return true;\r\n }\r\n return false;\r\n })\r\n .then(async (result) => {\r\n if (result)\r\n await moveFiles(this, station.getSerial(), device.getSerial(), DataLocation.TEMP, DataLocation.LAST_EVENT);\r\n return result;\r\n })\r\n .then(async (result) => {\r\n if (result) {\r\n const filename_without_ext = getDataFilePath(this, station.getSerial(), DataLocation.LAST_EVENT, device.getSerial());\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_VIDEO_URL), \"Last captured video URL\", `/${this.namespace}/${station.getSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}${STREAM_FILE_NAME_EXT}`, \"url\");\r\n if (fse.pathExistsSync(`${filename_without_ext}${STREAM_FILE_NAME_EXT}`))\r\n await ffmpegPreviewImage(this.config, `${filename_without_ext}${STREAM_FILE_NAME_EXT}`, `${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`, this.logger)\r\n .then(() => {\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_PIC_URL), \"Last event picture URL\", `/${this.namespace}/${station.getSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}${IMAGE_FILE_JPEG_EXT}`, \"url\");\r\n try {\r\n if (fse.existsSync(`${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`)) {\r\n const image_data = getImageAsHTML(fse.readFileSync(`${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`));\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_PIC_HTML), \"Last event picture HTML image\", image_data, \"html\");\r\n }\r\n } catch (error) {\r\n this.logger.error(`Station: ${station.getSerial()} device: ${device.getSerial()} - Error`, error);\r\n }\r\n })\r\n .catch((error) => {\r\n this.logger.error(`ffmpegPreviewImage - station: ${station.getSerial()} device: ${device.getSerial()} - Error`, error);\r\n });\r\n }\r\n })\r\n .catch(async (error) => {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Cancelling download...`, error);\r\n await this.eufy.cancelStationDownload(device.getSerial());\r\n });\r\n } catch(error) {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Cancelling download...`, error);\r\n await this.eufy.cancelStationDownload(device.getSerial());\r\n }\r\n }*/\r\n\r\n private onStationRTSPUrl(station: Station, device: Device, value: string): void {\r\n setStateChangedAsync(this as unknown as ioBroker.Adapter, device.getStateID(DeviceStateID.RTSP_STREAM_URL), value);\r\n }\r\n\r\n private async onStationConnect(station: Station): Promise<void> {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: true, ack: true });\r\n }\r\n\r\n private async onStationClose(station: Station): Promise<void> {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: false, ack: true });\r\n }\r\n\r\n private onTFARequest(): void {\r\n this.logger.warn(`Two factor authentication request received, please enter valid verification code in state ${this.namespace}.verify_code`);\r\n this.verify_code= true;\r\n }\r\n\r\n private onCaptchaRequest(captchaId: string, captcha: string): void {\r\n this.captchaId = captchaId;\r\n this.logger.warn(`Captcha authentication request received, please enter valid captcha in state ${this.namespace}.captcha`);\r\n this.logger.warn(`Captcha: <img src=\"${captcha}\">`);\r\n this.setStateAsync(\"received_captcha_html\", { val: `<img src=\"${captcha}\">`, ack: true });\r\n }\r\n\r\n}\r\n\r\nif (require.main !== module) {\r\n // Export the constructor in compact mode\r\n module.exports = (options: Partial<utils.AdapterOptions> | undefined) => new euSec(options);\r\n} else {\r\n // otherwise start the instance directly\r\n (() => new euSec())();\r\n}"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,YAAuB;AAGvB,WAAsB;AACtB,kCAAoW;AACpW,gCAAgD;AAChD,gCAA+C;AAE/C,kBAAiB;AACjB,2BAAyB;AACzB,2BAAyB;AACzB,mCAAyB;AAEzB,mBAAyE;AACzE,mBAA6H;AAE7H,iBAA+B;AAC/B,mBAA+B;AAExB,MAAM,cAAc,MAAM,QAAQ;AAAA,EAE7B;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAyB;AAAA,EACzB,uBAA+B;AAAA,EAC/B;AAAA,EACA,iBAAiC;AAAA,IACrC,SAAS;AAAA,EACb;AAAA,EACQ,YAA2B;AAAA,EAC3B,cAAc;AAAA,EACd,WAAW;AAAA,EAEZ,YAAY,UAAyC,CAAC,GAAG;AAC5D,UAAM;AAAA,MACF,GAAG;AAAA,MACH,MAAM;AAAA,IACV,CAAC;AAED,SAAK,GAAG,SAAS,KAAK,QAAQ,KAAK,IAAI,CAAC;AACxC,SAAK,GAAG,eAAe,KAAK,cAAc,KAAK,IAAI,CAAC;AAEpD,SAAK,GAAG,WAAW,KAAK,UAAU,KAAK,IAAI,CAAC;AAC5C,SAAK,GAAG,UAAU,KAAK,SAAS,KAAK,IAAI,CAAC;AAAA,EAC9C;AAAA,EAEO,iBAAuB;AAC1B,SAAK,WAAW;AAChB,SAAK,QAAQ;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,UAAyB;AA/D3C;AAiEQ,SAAK,SAAS,IAAI,0BAAe,KAAK,GAAsB;AAE5D,UAAM,KAAK,wBAAwB,eAAe;AAAA,MAC9C,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACX;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,wBAAwB,yBAAyB;AAAA,MACxD,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACX;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,wBAAwB,WAAW;AAAA,MAC1C,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACX;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,wBAAwB,QAAQ;AAAA,MACvC,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,MACV;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,wBAAwB,mBAAmB;AAAA,MAClD,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACX;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,cAAc,mBAAmB,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AACrE,UAAM,KAAK,wBAAwB,wBAAwB;AAAA,MACvD,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACX;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,cAAc,wBAAwB,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AAC1E,UAAM,KAAK,wBAAwB,wBAAwB;AAAA,MACvD,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACX;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,cAAc,wBAAwB,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AAE1E,QAAI;AACA,YAAM,aAAa,MAAM,KAAK,eAAe,cAAc;AAC3D,UAAI;AACA,eAAO,KAAK,UAAU,EAAE,QAAQ,OAAM,OAAM;AACxC,gBAAM,KAAK,cAAc,IAAI,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,QAC1D,CAAC;AAAA,IACT,SAAS,OAAO;AACZ,WAAK,OAAO,MAAM,mCAAmC,KAAK;AAAA,IAC9D;AAEA,QAAI;AACA,YAAM,aAAa;AAAA,QACf,yCAAa;AAAA,QACb,yCAAa;AAAA,QACb,yCAAa;AAAA,QACb,yCAAa;AAAA,QACb,yCAAa;AAAA,QACb,yCAAa;AAAA,MACjB;AACA,iBAAU,cAAc,YAAY;AAChC,cAAM,UAAU,MAAM,KAAK,eAAe,SAAK,0CAA4B,UAAU,CAAC,EAAE;AACxF,YAAI;AACA,iBAAO,KAAK,OAAO,EAAE,QAAQ,OAAM,OAAM;AACrC,kBAAM,KAAK,cAAc,IAAI,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,UAC1D,CAAC;AAAA,MACT;AAAA,IACJ,SAAS,OAAO;AACZ,WAAK,OAAO,MAAM,+BAA+B,KAAK;AAAA,IAC1D;AAEA,QAAI;AACA,UAAI,MAAM,KAAK,gBAAgB,KAAK,WAAW,KAAK,cAAc,GAAG;AACjE,cAAM,cAAc,MAAM,KAAK,cAAc,KAAK,WAAW,KAAK,cAAc;AAChF,aAAK,iBAAiB,KAAK,MAAM,YAAY,KAAK,SAAS,MAAM,CAAC;AAAA,MACtE;AAAA,IACJ,SAAS,OAAO;AACZ,WAAK,OAAO,MAAM,gDAAgD,KAAK;AAAA,IAC3E;AAEA,QAAI,uBAA+B;AACnC,QAAI;AACA,UAAI,MAAM,KAAK,gBAAgB,KAAK,WAAW,KAAK,oBAAoB,GAAG;AACvE,cAAM,cAAc,MAAM,KAAK,cAAc,KAAK,WAAW,KAAK,oBAAoB;AACtF,+BAAuB,YAAY,KAAK,SAAS,MAAM;AAAA,MAC3D;AAAA,IACJ,SAAS,OAAO;AACZ,WAAK,OAAO,MAAM,+CAA+C,KAAK;AAAA,IAC1E;AAEA,SAAK,gBAAgB,aAAa;AAClC,SAAK,gBAAgB,SAAS;AAE9B,UAAM,QAAQ,MAAM,KAAK,uBAAuB,iBAAiB,MAAM;AACvE,QAAI,UAAU,UAAa,UAAU,QAAQ,OAAO,OAAO,KAAK,EAAE,WAAW,GAAG;AAC5E,UAAI,KAAK,OAAO,aAAa,IAAI;AAC7B,aAAK,OAAO,WAAW,OAAO,OAAO,KAAK,EAAE,CAAC,EAAE,OAAO,GAAG;AAAA,MAC7D;AAEA,YAAM,cAAc,OAAO,OAAO,KAAK,EAAE,CAAC,EAAE,OAAO,QAAQ,SAAS;AACpE,YAAM,mBAAmB,YAAY,MAAM,GAAG,EAAE,CAAC;AAEjD,UAAI;AACJ,cAAQ,SAAS,gBAAgB,GAAG;AAAA,QAChC,KAAK;AACD,sBAAY,YAAY,cAAc,WAAW,QAAW,EAAE,SAAS,MAAM,aAAa,OAAO,CAAC;AAClG;AAAA,QACJ,KAAK;AACD,sBAAY,YAAY,cAAc,WAAW,QAAW,EAAE,SAAS,MAAM,aAAa,OAAO,CAAC;AAClG;AAAA,QACJ;AACI,sBAAY,YAAY,cAAc,UAAU,QAAW,EAAE,SAAS,MAAM,aAAa,OAAO,CAAC;AACjG;AAAA,MACR;AACA,UAAI,aAAa,GAAG;AAChB,cAAM,UAAU,MAAM,KAAK,sBAAsB,kBAAkB,KAAK,SAAS,EAAE;AACnF,YAAI,YAAY,UAAa,YAAY,MAAM;AAC3C,cAAI,GAAC,aAAQ,OAAO,sBAAf,mBAAkC,SAAS,sCAAqC;AACjF,oBAAQ,OAAO,oBAAoB,CAAC,kCAAkC;AACtE,kBAAM,KAAK,sBAAsB,kBAAkB,KAAK,SAAS,IAAI,OAAO;AAC5E,iBAAK,IAAI,KAAK,gJAAgJ;AAC9J,iBAAK,eAAe;AAAA,UACxB;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,CAAC,KAAK,UAAU;AAChB,YAAM,eAAe,MAAM,KAAK,sBAAsB,eAAe;AACrE,UAAI,cAAc;AAClB,UAAI,eAAe;AACnB,UAAI,cAAc;AACd,0BAAc,0BAAAA,eAAe,aAAa,OAAO,SAAU,IAAI;AAC/D,gBAAI,0BAAAC,SAAoB,aAAa,OAAO,QAAQ;AAChD,yBAAe,aAAa,OAAO;AAAA,MAC3C;AACA,UAAI,KAAK,OAAO,YAAY,YAAY;AACpC,sBAAc,KAAK,OAAO;AAAA,MAC9B;AAGA,UAAI;AACA,YAAI,KAAK,eAAe,YAAY,KAAK,SAAS;AAC9C,gBAAM,iBAAiB,OAAO,eAAW,6BAAe,KAAK,SAAU,GAAG,CAAC;AAC3E,gBAAM,kBAAkB,KAAK,eAAe,YAAY,MAAM,KAAK,eAAe,YAAY,SAAY,OAAO,eAAW,6BAAe,KAAK,eAAe,SAAS,GAAG,CAAC,IAAI;AAChL,eAAK,OAAO,MAAM,gDAAgD,cAAc,qBAAqB,eAAe,EAAE;AAEtH,cAAI,kBAAkB,gBAAgB;AAClC,sBAAM,2BAAa,MAAM,KAAK,QAAQ,iBAAiB,cAAc;AACrE,iBAAK,eAAe,UAAU,KAAK;AACnC,kBAAM,KAAK,oBAAoB;AAAA,UACnC;AAAA,QACJ;AAAA,MACJ,SAAS,OAAO;AACZ,aAAK,OAAO,MAAM,uCAAuC,KAAK;AAAA,MAClE;AAEA,UAAI,iBAAiB,8CAAkB;AACvC,UAAI,KAAK,OAAO,sBAAsB,cAAc;AAChD,yBAAiB,8CAAkB;AAAA,MACvC;AAEA,UAAI,KAAK,OAAO,aAAa,MAAM,KAAK,OAAO,aAAa,IAAI;AAC5D,cAAM,SAA6B;AAAA,UAC/B,UAAU,KAAK,OAAO;AAAA,UACtB,UAAU,KAAK,OAAO;AAAA,UACtB,SAAS;AAAA,UACT,UAAU;AAAA,UACV,gBAAgB;AAAA,UAChB,sBAAsB,KAAK,OAAO;AAAA,UAClC,oBAAoB;AAAA,UACpB,wBAAwB,KAAK,OAAO;AAAA,UACpC,mBAAmB,KAAK,OAAO;AAAA,UAC/B,SAAS;AAAA,YACL,OAAO,KAAK,IAAI,UAAU,UAAU,qCAAS,QAAQ,KAAK,IAAI,UAAU,UAAU,qCAAS,QAAQ,KAAK,IAAI,UAAU,SAAS,qCAAS,OAAO,KAAK,IAAI,UAAU,SAAS,qCAAS,OAAO,KAAK,IAAI,UAAU,UAAU,qCAAS,QAAQ,qCAAS;AAAA,UACtP;AAAA,QACJ;AAEA,aAAK,OAAO,MAAM,yCAAa,WAAW,QAAQ,KAAK,MAAM;AAC7D,aAAK,KAAK,GAAG,mBAAmB,CAAC,SAAiB,KAAK,iBAAiB,IAAI,CAAC;AAC7E,aAAK,KAAK,GAAG,iBAAiB,CAAC,YAAqB,KAAK,eAAe,OAAO,CAAC;AAChF,aAAK,KAAK,GAAG,gBAAgB,CAAC,WAAmB,KAAK,cAAc,MAAM,CAAC;AAC3E,aAAK,KAAK,GAAG,mBAAmB,CAAC,YAAqB,KAAK,iBAAiB,OAAO,CAAC;AACpF,aAAK,KAAK,GAAG,kBAAkB,CAAC,WAAmB,KAAK,gBAAgB,MAAM,CAAC;AAC/E,aAAK,KAAK,GAAG,gBAAgB,CAAC,aAAa,KAAK,uBAAuB,QAAQ,CAAC;AAChF,aAAK,KAAK,GAAG,gBAAgB,MAAM,KAAK,cAAc,CAAC;AACvD,aAAK,KAAK,GAAG,cAAc,MAAM,KAAK,YAAY,CAAC;AACnD,aAAK,KAAK,GAAG,gBAAgB,MAAM,KAAK,cAAc,CAAC;AACvD,aAAK,KAAK,GAAG,cAAc,MAAM,KAAK,YAAY,CAAC;AACnD,aAAK,KAAK,GAAG,WAAW,MAAM,KAAK,UAAU,CAAC;AAC9C,aAAK,KAAK,GAAG,SAAS,MAAM,KAAK,QAAQ,CAAC;AAE1C,aAAK,KAAK,GAAG,2BAA2B,CAAC,QAAgB,MAAc,UAAyB,KAAK,wBAAwB,QAAQ,MAAM,KAAK,CAAC;AAEjJ,aAAK,KAAK,GAAG,0BAA0B,CAAC,SAAkB,WAA0B,KAAK,uBAAuB,SAAS,MAAM,CAAC;AAGhI,aAAK,KAAK,GAAG,4BAA4B,CAAC,SAAkB,QAAgB,UAA0B,aAAuB,gBAA0B,KAAK,yBAAyB,SAAS,QAAQ,UAAU,aAAa,WAAW,CAAC;AACzO,aAAK,KAAK,GAAG,2BAA2B,CAAC,SAAkB,WAAmB,KAAK,wBAAwB,SAAS,MAAM,CAAC;AAC3H,aAAK,KAAK,GAAG,oBAAqB,CAAC,SAAkB,QAAgB,UAAkB,KAAK,iBAAiB,SAAS,QAAQ,KAAK,CAAC;AACpI,aAAK,KAAK,GAAG,4BAA4B,CAAC,SAAkB,MAAc,UAAyB,KAAK,yBAAyB,SAAS,MAAM,KAAK,CAAC;AACtJ,aAAK,KAAK,GAAG,mBAAmB,CAAC,YAAqB,KAAK,iBAAiB,OAAO,CAAC;AACpF,aAAK,KAAK,GAAG,iBAAiB,CAAC,YAAqB,KAAK,eAAe,OAAO,CAAC;AAChF,aAAK,KAAK,GAAG,eAAe,MAAM,KAAK,aAAa,CAAC;AACrD,aAAK,KAAK,GAAG,mBAAmB,CAAC,WAAmB,YAAoB,KAAK,iBAAiB,WAAW,OAAO,CAAC;AACjH,aAAK,KAAK,+BAA+B,KAAK,OAAO,qBAAqB;AAE1E,cAAM,KAAK,KAAK,QAAQ;AAExB,YAAI,qBAAAC,SAAc;AACd,gBAAM,eAIF;AAAA,YACA,OAAO;AAAA,cACH,UAAU,IAAI,KAAK,OAAO,eAAe;AAAA,YAC7C;AAAA,YACA,QAAQ;AAAA,cACJ,UAAU,IAAI,KAAK,OAAO,gBAAgB;AAAA,YAC9C;AAAA,YACA,QAAQ;AAAA,cACJ,UAAU,IAAI,KAAK,OAAO,gBAAgB;AAAA,YAC9C;AAAA,YACA,UAAU;AAAA,cACN,UAAU,IAAI,KAAK,OAAO,kBAAkB;AAAA,YAChD;AAAA,YACA,UAAU;AAAA,cACN,OAAO,6BAAAC,YAAiB,MAAM,6BAAAA,YAAiB,SAAY,6BAAAA,UAAe;AAAA,YAC9E;AAAA,YACA,WAAW,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAUhB;AACA,cAAI,KAAK,OAAO,yBAAyB,MAAM,KAAK,OAAO,yBAAyB,IAAI;AACpF,yBAAa,KAAK,WAAW,KAAK,OAAO;AACzC,yBAAa,KAAK,WAAW,KAAK,OAAO;AAAA,UAC7C;AACA,qBAAW,UAAU,MAAM,KAAK,KAAK,WAAW,GAAG;AAC/C,yBAAa,QAAQ,OAAO,UAAU,CAAC,IAAI;AAAA,UAC/C;AACA,gBAAM,SAAS,qBAAAC,QAAa,MAAM,qBAAAF,SAAc,CAAC,WAAW,KAAK,UAAU,YAAY,CAAC,GAAG,EAAE,OAAO,OAAO,UAAU,OAAO,aAAa,KAAK,CAAC;AAC/I,iBAAO,GAAG,SAAS,CAAC,UAAU;AAC1B,iBAAK,IAAI,MAAM,iBAAiB,KAAK,EAAE;AAAA,UAC3C,CAAC;AACD,iBAAO,OAAO,YAAY,MAAM;AAChC,iBAAO,OAAO,GAAG,QAAQ,CAAC,SAAS;AAC/B,iBAAK,IAAI,KAAK,mBAAmB,IAAI,EAAE;AAAA,UAC3C,CAAC;AACD,iBAAO,OAAO,YAAY,MAAM;AAChC,iBAAO,OAAO,GAAG,QAAQ,CAAC,SAAS;AAC/B,iBAAK,IAAI,MAAM,iBAAiB,IAAI,EAAE;AAAA,UAC1C,CAAC;AACD,iBAAO,GAAG,SAAS,CAAC,aAAa;AAC7B,iBAAK,IAAI,KAAK,mCAAmC,QAAQ,EAAE;AAAA,UAC/D,CAAC;AACD,kBAAQ,GAAG,QAAQ,MAAM;AACrB,mBAAO,KAAK;AAAA,UAChB,CAAC;AAAA,QACL;AAAA,MACJ;AAEA,YAAM,WAAW,MAAM,KAAK,iBAAiB;AAC7C,iBAAW,WAAW,UAAU;AAC5B,YAAI,QAAQ,OAAO,SAAS,WAAW;AACnC,gBAAM,SAAS,MAAM,KAAK,eAAe,GAAG,QAAQ,GAAG,IAAI;AAC3D,cAAI,OAAO,KAAK,MAAM,EAAE,WAAW,GAAG;AAClC,kBAAM,KAAK,eAAe,QAAQ,GAAG;AAAA,UACzC;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,MAAa,sBAAqC;AAC9C,QAAI;AACA,YAAM,KAAK,eAAe,KAAK,WAAW,KAAK,gBAAgB,KAAK,UAAU,KAAK,cAAc,CAAC;AAAA,IACtG,SAAQ,OAAO;AACX,WAAK,OAAO,MAAM,kCAAkC,KAAK,EAAE;AAAA,IAC/D;AAAA,EACJ;AAAA,EAEQ,iBAAiB,MAAoB;AACzC,SAAK,eAAe,KAAK,WAAW,KAAK,sBAAsB,IAAI,EAAE,MAAM,CAAC,UAAU;AAClF,WAAK,OAAO,MAAM,wCAAwC,KAAK,EAAE;AAAA,IACrE,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,SAAS,UAAqC;AACxD,QAAI;AAEA,YAAM,KAAK,oBAAoB;AAE/B,UAAI,KAAK,MAAM;AACX,YAAI,KAAK,KAAK,YAAY;AACtB,gBAAM,KAAK,cAAc,mBAAmB,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC,EAAE,MAAM;AACjF,aAAK,KAAK,mBAAmB;AAC7B,aAAK,KAAK,MAAM;AAAA,MACpB;AAEA,eAAS;AAAA,IACb,SAAS,GAAG;AACR,eAAS;AAAA,IACb;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,MAAc,cAAc,IAAY,OAAyD;AAC7F,QAAI,OAAO;AAGP,UAAI,CAAC,MAAM,MAAM,KAAK;AAClB,aAAK,OAAO,MAAM,SAAS,EAAE,aAAa,MAAM,GAAG,WAAW,MAAM,GAAG,0CAA0C;AACjH;AAAA,MACJ;AACA,WAAK,OAAO,MAAM,SAAS,EAAE,aAAa,MAAM,GAAG,WAAW,MAAM,GAAG,GAAG;AAE1E,YAAM,SAAS,GAAG,MAAM,GAAG;AAC3B,YAAM,aAAa,OAAO,CAAC;AAC3B,YAAM,cAAc,OAAO,CAAC;AAE5B,UAAI,cAAc,eAAe;AAC7B,YAAI,KAAK,QAAQ,KAAK,aAAa;AAC/B,eAAK,OAAO,KAAK,sDAAsD,MAAM,GAAG,GAAG;AACnF,gBAAM,KAAK,KAAK,QAAQ,EAAE,YAAY,MAAM,IAAc,CAAiB;AAC3E,eAAK,cAAc;AACnB,gBAAM,KAAK,cAAc,EAAE;AAAA,QAC/B;AAAA,MACJ,WAAW,cAAc,WAAW;AAChC,YAAI,KAAK,QAAQ,KAAK,WAAW;AAC7B,eAAK,OAAO,KAAK,wCAAwC,MAAM,GAAG,GAAG;AACrE,gBAAM,KAAK,KAAK,QAAQ;AAAA,YACpB,SAAS;AAAA,cACL,aAAa,MAAM;AAAA,cACnB,WAAW,KAAK;AAAA,YACpB;AAAA,UACJ,CAAiB;AACjB,eAAK,YAAY;AACjB,gBAAM,KAAK,cAAc,EAAE;AAC3B,gBAAM,KAAK,cAAc,uBAAuB;AAAA,QACpD;AAAA,MACJ,WAAW,eAAe,WAAW;AACjC,YAAI;AACA,gBAAM,qBAAqB,OAAO,CAAC;AACnC,cAAI,KAAK,MAAM;AACX,kBAAM,MAAM,MAAM,KAAK,eAAe,EAAE;AACxC,gBAAI,KAAK;AACL,kBAAI,IAAI,OAAO,SAAS,QAAW;AAC/B,sBAAM,KAAK,KAAK,mBAAmB,YAAY,IAAI,OAAO,MAAM,MAAM,GAAG;AACzE;AAAA,cACJ;AAAA,YACJ;AAEA,kBAAM,UAAU,MAAM,KAAK,KAAK,WAAW,UAAU;AACrD,oBAAO,oBAAoB;AAAA,cACvB,KAAK,4BAAe;AAChB,sBAAM,QAAQ,UAAU;AACxB;AAAA,cACJ,KAAK,4BAAe;AAChB,sBAAM,QAAQ,yBAAyB,KAAK,OAAO,kBAAkB;AACrE;AAAA,cACJ,KAAK,4BAAe;AAChB,sBAAM,QAAQ,uBAAuB;AACrC;AAAA,YACR;AAAA,UACJ;AAAA,QACJ,SAAS,OAAO;AACZ,eAAK,OAAO,MAAM,oBAAoB,KAAK;AAAA,QAC/C;AAAA,MACJ,OAAO;AACH,YAAI;AACA,gBAAM,YAAY,OAAO,CAAC;AAC1B,gBAAM,MAAM,MAAM,KAAK,eAAe,EAAE;AACxC,cAAI,KAAK;AACL,gBAAI,IAAI,OAAO,SAAS,QAAW;AAC/B,kBAAI;AACA,sBAAM,KAAK,KAAK,kBAAkB,WAAW,IAAI,OAAO,MAAM,IAAI,OAAO,SAAS,WAAW,KAAK,MAAM,MAAM,GAAa,IAAI,MAAM,GAAG;AAAA,cAC5I,SAAS,OAAO;AACZ,qBAAK,OAAO,MAAM,8CAA8C,IAAI,OAAO,IAAI,WAAW,MAAM,GAAG,KAAK,KAAK;AAAA,cACjH;AACA;AAAA,YACJ;AAAA,UACJ;AAEA,gBAAM,oBAAoB,OAAO,CAAC;AAClC,gBAAM,UAAU,MAAM,KAAK,KAAK,WAAW,UAAU;AACrD,gBAAM,SAAS,MAAM,KAAK,KAAK,UAAU,SAAS;AAElD,kBAAO,mBAAmB;AAAA,YACtB,KAAK,2BAAc;AACf,oBAAM,KAAK,gBAAgB,SAAS;AACpC;AAAA,YACJ,KAAK,2BAAc;AACf,oBAAM,KAAK,eAAe,SAAS;AACnC;AAAA,YACJ,KAAK,2BAAc;AACf,oBAAM,QAAQ,wBAAwB,QAAQ,KAAK,OAAO,kBAAkB;AAC5E;AAAA,YACJ,KAAK,2BAAc;AACf,oBAAM,QAAQ,sBAAsB,MAAM;AAC1C;AAAA,YACJ,KAAK,2BAAc;AACf,oBAAM,QAAQ,WAAW,QAAQ,6CAAiB,SAAS;AAC3D;AAAA,YACJ,KAAK,2BAAc;AACf,oBAAM,QAAQ,WAAW,QAAQ,6CAAiB,IAAI;AACtD;AAAA,YACJ,KAAK,2BAAc;AACf,oBAAM,QAAQ,WAAW,QAAQ,6CAAiB,KAAK;AACvD;AAAA,YACJ,KAAK,2BAAc;AACf,oBAAM,QAAQ,WAAW,QAAQ,6CAAiB,EAAE;AACpD;AAAA,YACJ,KAAK,2BAAc;AACf,oBAAM,QAAQ,WAAW,QAAQ,6CAAiB,IAAI;AACtD;AAAA,YACJ,KAAK,2BAAc;AACf,kBAAI,OAAO,OAAO,GAAG;AACjB,sBAAM,QAAQ,cAAc,MAAM;AAAA,cACtC,OAAO;AACH,sBAAM,QAAQ,UAAU,MAAM;AAAA,cAClC;AACA;AAAA,YACJ,KAAK,2BAAc;AACf,oBAAM,QAAQ,OAAO,MAAM;AAC3B;AAAA,YACJ,KAAK,2BAAc;AACf,oBAAM,QAAQ,gBAAgB,MAAM;AACpC;AAAA,YACJ,KAAK,2BAAc;AACf,oBAAM,QAAQ,gBAAgB,MAAM;AACpC;AAAA,YACJ,KAAK,2BAAc;AACf,oBAAM,QAAQ,KAAK,MAAM;AACzB;AAAA,UACR;AAAA,QACJ,SAAS,OAAO;AACZ,eAAK,OAAO,MAAM,oBAAoB,KAAK;AAAA,QAC/C;AAAA,MACJ;AAAA,IACJ,OAAO;AAEH,WAAK,OAAO,MAAM,SAAS,EAAE,UAAU;AAAA,IAC3C;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,UAAU,KAAsC;AAC1D,QAAI,OAAO,QAAQ,YAAY,IAAI,SAAS;AACxC,UAAI;AACA,YAAI,IAAI,YAAY,iBAAiB;AACjC,eAAK,IAAI,MAAM,oCAAoC,KAAK,UAAU,IAAI,OAAO,CAAC,EAAE;AAChF,cAAI,OAAO,IAAI,YAAY,YACvB,OAAO,IAAI,QAAQ,eAAe,YAAY,IAAI,QAAQ,eAAe,MACzE,OAAO,IAAI,QAAQ,cAAc,YAAY,IAAI,QAAQ,cAAc,MACvE,OAAO,IAAI,QAAQ,aAAa,UAAU;AAC1C,gBAAI;AACA,oBAAM,UAAU,MAAM,KAAK,KAAK,WAAW,IAAI,QAAQ,UAAU;AACjE,oBAAM,SAAS,MAAM,KAAK,KAAK,UAAU,IAAI,QAAQ,SAAS;AAE9D,kBAAI,OAAO,WAAW,wCAAY,mBAAmB,GAAG;AACpD,sBAAM,QAAQ,cAAc,QAAQ,IAAI,QAAQ,QAAQ;AACxD,oBAAI,IAAI;AACJ,uBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,oBAC/B,QAAQ;AAAA,oBACR,QAAQ;AAAA,kBACZ,GAAG,IAAI,QAAQ;AAAA,cACvB,OAAO;AACH,oBAAI,IAAI;AACJ,uBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,oBAC/B,QAAQ;AAAA,oBACR,QAAQ;AAAA,kBACZ,GAAG,IAAI,QAAQ;AAAA,cACvB;AAAA,YACJ,SAAS,OAAO;AACZ,kBAAI,iBAAiB,kDAAsB;AACvC,oBAAI,IAAI;AACJ,uBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,oBAC/B,QAAQ;AAAA,oBACR,QAAQ;AAAA,kBACZ,GAAG,IAAI,QAAQ;AAAA,cACvB,WAAW,iBAAiB,iDAAqB;AAC7C,oBAAI,IAAI;AACJ,uBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,oBAC/B,QAAQ;AAAA,oBACR,QAAQ;AAAA,kBACZ,GAAG,IAAI,QAAQ;AAAA,cACvB,OAAO;AACH,sBAAM;AAAA,cACV;AAAA,YACJ;AAAA,UACJ,OAAO;AACH,gBAAI,IAAI;AACJ,mBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,gBAC/B,QAAQ;AAAA,gBACR,QAAQ;AAAA,cACZ,GAAG,IAAI,QAAQ;AAAA,UACvB;AAAA,QACJ,WAAW,IAAI,YAAY,0BAA0B;AACjD,eAAK,IAAI,MAAM,6CAA6C,KAAK,UAAU,IAAI,OAAO,CAAC,EAAE;AACzF,cAAI,OAAO,IAAI,YAAY,YACvB,OAAO,IAAI,QAAQ,cAAc,YAAY,IAAI,QAAQ,cAAc,IAAI;AAC3E,kBAAM,SAAS,MAAM,KAAK,KAAK,OAAO,EAAE,UAAU,IAAI,QAAQ,SAAS;AAEvE,gBAAI,IAAI;AACJ,mBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,gBAC/B,QAAQ;AAAA,gBACR,QAAQ;AAAA,cACZ,GAAG,IAAI,QAAQ;AAAA,UACvB,OAAO;AACH,gBAAI,IAAI;AACJ,mBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,gBAC/B,QAAQ;AAAA,gBACR,QAAQ;AAAA,cACZ,GAAG,IAAI,QAAQ;AAAA,UACvB;AAAA,QACJ,WAAW,IAAI,YAAY,UAAU;AACjC,eAAK,IAAI,MAAM,6BAA6B,KAAK,UAAU,IAAI,OAAO,CAAC,EAAE;AACzE,cAAI,OAAO,IAAI,YAAY,YACvB,OAAO,IAAI,QAAQ,eAAe,YAAY,IAAI,QAAQ,eAAe,MACzE,OAAO,IAAI,QAAQ,cAAc,YAAY,IAAI,QAAQ,cAAc,MACvE,OAAO,IAAI,QAAQ,gBAAgB,aAClC,IAAI,QAAQ,iBAAiB,UAAa,OAAO,IAAI,QAAQ,iBAAiB,eAC9E,IAAI,QAAQ,oBAAoB,UAAa,OAAO,IAAI,QAAQ,oBAAoB,eACpF,IAAI,QAAQ,kBAAkB,UAAa,OAAO,IAAI,QAAQ,kBAAkB,YAAY;AAC7F,gBAAI;AACA,oBAAM,UAAU,MAAM,KAAK,KAAK,WAAW,IAAI,QAAQ,UAAU;AACjE,oBAAM,SAAS,MAAM,KAAK,KAAK,UAAU,IAAI,QAAQ,SAAS;AAE9D,kBAAI,OAAO,WAAW,wCAAY,YAAY,GAAG;AAC7C,sBAAM,QAAQ,OAAO,QAAQ;AAAA,kBACzB,aAAa,IAAI,QAAQ;AAAA,kBACzB,cAAc,IAAI,QAAQ;AAAA,kBAC1B,iBAAiB,IAAI,QAAQ;AAAA,kBAC7B,eAAe,IAAI,QAAQ;AAAA,gBAC/B,CAAC;AACD,oBAAI,IAAI;AACJ,uBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,oBAC/B,QAAQ;AAAA,oBACR,QAAQ;AAAA,kBACZ,GAAG,IAAI,QAAQ;AAAA,cACvB,OAAO;AACH,oBAAI,IAAI;AACJ,uBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,oBAC/B,QAAQ;AAAA,oBACR,QAAQ;AAAA,kBACZ,GAAG,IAAI,QAAQ;AAAA,cACvB;AAAA,YACJ,SAAS,OAAO;AACZ,kBAAI,iBAAiB,kDAAsB;AACvC,oBAAI,IAAI;AACJ,uBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,oBAC/B,QAAQ;AAAA,oBACR,QAAQ;AAAA,kBACZ,GAAG,IAAI,QAAQ;AAAA,cACvB,WAAW,iBAAiB,iDAAqB;AAC7C,oBAAI,IAAI;AACJ,uBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,oBAC/B,QAAQ;AAAA,oBACR,QAAQ;AAAA,kBACZ,GAAG,IAAI,QAAQ;AAAA,cACvB,OAAO;AACH,sBAAM;AAAA,cACV;AAAA,YACJ;AAAA,UACJ,OAAO;AACH,gBAAI,IAAI;AACJ,mBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,gBAC/B,QAAQ;AAAA,gBACR,QAAQ;AAAA,cACZ,GAAG,IAAI,QAAQ;AAAA,UACvB;AAAA,QACJ,WAAW,IAAI,YAAY,SAAS;AAChC,eAAK,IAAI,MAAM,6BAA6B,KAAK,UAAU,IAAI,OAAO,CAAC,EAAE;AACzE,cAAI,OAAO,IAAI,YAAY,YACvB,OAAO,IAAI,QAAQ,eAAe,YAAY,IAAI,QAAQ,eAAe,OACxE,IAAI,QAAQ,aAAa,UAAa,OAAO,IAAI,QAAQ,aAAa,WAAW;AAClF,gBAAI;AACA,oBAAM,UAAU,MAAM,KAAK,KAAK,WAAW,IAAI,QAAQ,UAAU;AAEjE,kBAAI,QAAQ,WAAW,wCAAY,YAAY,GAAG;AAC9C,sBAAM,QAAQ,cAAc,IAAI,QAAQ,aAAa,UAAa,OAAO,IAAI,QAAQ,aAAa,WAAW,IAAI,QAAQ,WAAW,CAAC;AACrI,oBAAI,IAAI;AACJ,uBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,oBAC/B,QAAQ;AAAA,oBACR,QAAQ;AAAA,kBACZ,GAAG,IAAI,QAAQ;AAAA,cACvB,OAAO;AACH,oBAAI,IAAI;AACJ,uBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,oBAC/B,QAAQ;AAAA,oBACR,QAAQ;AAAA,kBACZ,GAAG,IAAI,QAAQ;AAAA,cACvB;AAEA,kBAAI,IAAI;AACJ,qBAAK,OAAO,IAAI,MAAM,IAAI,SAAS,wBAAwB,IAAI,QAAQ;AAAA,YAC/E,SAAS,OAAO;AACZ,kBAAI,iBAAiB,kDAAsB;AACvC,oBAAI,IAAI;AACJ,uBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,oBAC/B,QAAQ;AAAA,oBACR,QAAQ;AAAA,kBACZ,GAAG,IAAI,QAAQ;AAAA,cACvB,OAAO;AACH,sBAAM;AAAA,cACV;AAAA,YACJ;AAAA,UACJ;AAAA,QACJ,WAAW,IAAI,YAAY,eAAe;AACtC,eAAK,IAAI,MAAM,qBAAqB;AACpC,gBAAM,KAAK,KAAK,iBAAiB;AAEjC,cAAI,IAAI;AACJ,iBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,cAC/B,QAAQ;AAAA,cACR,QAAQ;AAAA,YACZ,GAAG,IAAI,QAAQ;AAAA,QACvB,OAAO;AACH,gBAAM,eAAe,6BAA6B,KAAK,UAAU,IAAI,OAAO,CAAC;AAC7E,eAAK,IAAI,KAAK,YAAY;AAC1B,cAAI,IAAI;AACJ,iBAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,cAC/B,QAAQ;AAAA,cACR,QAAQ;AAAA,YACZ,GAAG,IAAI,QAAQ;AAAA,QACvB;AAAA,MACJ,SAAS,OAAO;AACZ,cAAM,eAAe,gDAAgD,iBAAiB,QAAQ,GAAG,MAAM,IAAI,MAAM,MAAM,OAAO,KAAK,KAAM;AACzI,aAAK,IAAI,MAAM,YAAY;AAC3B,YAAI,IAAI;AACJ,eAAK,OAAO,IAAI,MAAM,IAAI,SAAS;AAAA,YAC/B,QAAQ;AAAA,YACR,QAAQ;AAAA,UACZ,GAAG,IAAI,QAAQ;AAAA,MACvB;AAAA,IACJ;AAAA,EACJ;AAAA,EAEQ,eAAe,UAAqD;AACxE,UAAM,QAA8B;AAAA,MAChC,MAAM,SAAS;AAAA,MACf,MAAM,SAAS;AAAA,MACf,MAAM;AAAA,MACN,MAAM,SAAS;AAAA,MACf,OAAO,SAAS;AAAA,MAChB,KAAK,SAAS,SAAS,YAAY,OAAO,SAAS,YAAY,WAAW,KAAK,UAAU,SAAS,OAAO,IAAI,SAAS;AAAA,IAC1H;AACA,YAAQ,SAAS,MAAM;AAAA,MACnB,KAAK,UAAU;AACX,cAAM,iBAAiB;AACvB,cAAM,MAAM,eAAe;AAC3B,cAAM,MAAM,eAAe;AAC3B,cAAM,SAAS,eAAe;AAC9B,cAAM,OAAO,eAAe;AAC5B,cAAM,OAAO,eAAe;AAC5B,cAAM,OAAO,yBAAY,SAAS,IAAI,MAAM,SAAY,yBAAY,SAAS,IAAI,IAAI;AACrF;AAAA,MACJ;AAAA,MACA,KAAK,UAAU;AACX,cAAM,OAAO,yBAAY,SAAS,IAAI,MAAM,SAAY,yBAAY,SAAS,IAAI,IAAI;AACrF;AAAA,MACJ;AAAA,MACA,KAAK,WAAW;AACZ,cAAM,OAAO,yBAAY,SAAS,IAAI,MAAM,SAAY,yBAAY,SAAS,IAAI,IAAK,SAAS,YAAY,kBAAkB;AAC7H;AAAA,MACJ;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAEA,MAAc,kBAAkB,QAA0B,UAA8C;AACpG,QAAI,SAAS,SAAS,yCAAa,QAAQ,SAAS,SAAS,yCAAa,iBAAiB;AACvF,YAAM,QAAQ,KAAK,eAAe,QAAQ;AAC1C,YAAM,KAAa,OAAO,eAAW,0CAA4B,SAAS,IAAI,CAAC;AAC/E,YAAM,MAAM,MAAM,KAAK,eAAe,EAAE;AACxC,UAAI,KAAK;AACL,YAAI,UAAU;AACd,YAAI,IAAI,OAAO,SAAS,UAAa,IAAI,OAAO,SAAS,SAAS,MAAM;AACpE,cAAI,OAAO,OAAO,SAAS;AAC3B,oBAAU;AAAA,QACd;AACA,YAAI,IAAI,OAAO,QAAQ,UAAa,IAAI,OAAO,QAAQ,SAAS,KAAK;AACjE,cAAI,OAAO,MAAM,SAAS;AAC1B,oBAAU;AAAA,QACd;AACA,YAAI,IAAI,OAAO,cAAc,UAAa,IAAI,OAAO,cAAc,SAAS,WAAW;AACnF,cAAI,OAAO,YAAY,SAAS;AAChC,oBAAU;AAAA,QACd;AACA,YAAI,IAAI,WAAW,UAAa,CAAC,YAAAG,QAAK,kBAAkB,IAAI,QAAQ,KAAK,GAAG;AACxE,oBAAU;AAAA,QACd;AACA,YAAI,SAAS;AACT,gBAAM,mBAAmB,OAAO,sBAAsB,EAAE,SAAS,IAAI;AACrE,cAAI,qBAAqB,QAAW;AAChC,kBAAM,WAAW,KAAK,eAAe,gBAAgB;AACrD,gBAAI,SAAS;AAAA,UACjB;AACA,gBAAM,KAAK,eAAe,IAAI,GAAG;AAAA,QACrC;AAAA,MACJ,OAAO;AACH,cAAM,KAAK,wBAAwB,IAAI;AAAA,UACnC,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,QAAQ;AAAA,YACJ,KAAK,SAAS;AAAA,YACd,WAAW,SAAS;AAAA,YACpB,MAAM,SAAS;AAAA,UACnB;AAAA,QACJ,CAAC;AAAA,MACL;AACA,YAAM,QAAQ,OAAO,iBAAiB,SAAS,IAAI;AACnD,UAAI,UAAU;AACV,kBAAM,mCAAqB,MAAqC,KAAK,SAAS,SAAS,YAAY,SAAS,SAAS,aAAa,OAAO,UAAU,WAAW,KAAK,UAAU,KAAK,IAAI,KAAK;AAAA,IACnM;AAAA,EACJ;AAAA,EAEA,MAAc,cAAc,QAA+B;AACvD,SAAK,OAAO,MAAM,2BAA2B,OAAO,UAAU,CAAC,EAAE;AAEjE,UAAM,KAAK,wBAAwB,OAAO,WAAW,IAAI,CAAC,GAAG;AAAA,MACzD,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM,OAAO,gBAAgB;AAAA,MACjC;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AAED,UAAM,KAAK,wBAAwB,OAAO,WAAW,IAAI,CAAC,GAAG;AAAA,MACzD,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM,OAAO,QAAQ;AAAA,MACzB;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AAED,UAAM,WAAW,OAAO,sBAAsB;AAC9C,eAAU,YAAY,OAAO,OAAO,QAAQ,GAAG;AAC3C,UAAI,SAAS,SAAS,yCAAa;AAC/B,aAAK,kBAAkB,QAAQ,QAAQ;AAAA,IAC/C;AAEA,QAAI,OAAO,YAAY,yCAAa,aAAa,GAAG;AAChD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,WAAW,GAAG;AAAA,QAC7E,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AACD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,YAAY,GAAG;AAAA,QAC9E,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AAAA,IACL;AAEA,QAAI,OAAO,WAAW,wCAAY,uBAAuB,GAAG;AACxD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,mBAAmB,GAAG;AAAA,QACrF,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AACD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,iBAAiB,GAAG;AAAA,QACnF,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AAAA,IACL;AACA,QAAI,OAAO,WAAW,wCAAY,gBAAgB,GAAG;AACjD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,QAAQ,GAAG;AAAA,QAC1E,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AACD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,SAAS,GAAG;AAAA,QAC3E,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AACD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,UAAU,GAAG;AAAA,QAC5E,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AACD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,OAAO,GAAG;AAAA,QACzE,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AACD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,SAAS,GAAG;AAAA,QAC3E,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AAAA,IACL;AACA,QAAI,OAAO,WAAW,wCAAY,qBAAqB,GAAG;AACtD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,SAAS,GAAG;AAAA,QAC3E,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AAAA,IACL;AACA,QAAI,OAAO,WAAW,wCAAY,YAAY,GAAG;AAC7C,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,MAAM,GAAG;AAAA,QACxE,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AAAA,IACL;AACA,QAAI,OAAO,WAAW,wCAAY,qBAAqB,GAAG;AACtD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,iBAAiB,GAAG;AAAA,QACnF,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AAAA,IACL;AACA,QAAI,OAAO,WAAW,wCAAY,qBAAqB,GAAG;AACtD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,iBAAiB,GAAG;AAAA,QACnF,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AAAA,IACL;AACA,QAAI,OAAO,WAAW,wCAAY,eAAe,GAAG;AAChD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,SAAS,GAAG;AAAA,QAC3E,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AAAA,IACL;AACA,QAAI,OAAO,WAAW,wCAAY,UAAU,GAAG;AAC3C,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,QAAQ,GAAG;AAAA,QAC1E,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AAAA,IACL;AACA,QAAI,OAAO,WAAW,wCAAY,qBAAqB,GAAG;AAEtD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,YAAY,GAAG;AAAA,QAC9E,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AAGD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,WAAW,GAAG;AAAA,QAC7E,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AAGD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,UAAU,GAAG;AAAA,QAC5E,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AAGD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,eAAe,GAAG;AAAA,QACjF,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AAAA,IACL;AAEA,QAAI,OAAO,YAAY,yCAAa,gBAAgB,GAAG;AAEnD,YAAM,KAAK,wBAAwB,OAAO,WAAW,2BAAc,eAAe,GAAG;AAAA,QACjF,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AAAA,IACL;AAAA,EA8CJ;AAAA,EAEA,MAAc,gBAAgB,QAA+B;AACzD,SAAK,eAAe,OAAO,WAAW,IAAI,CAAC,GAAG,EAAE,WAAW,KAAK,CAAC,EAAE,MAAM,CAAC,UAAU;AAChF,WAAK,OAAO,MAAM,2CAA2C,KAAK;AAAA,IACtE,CAAC;AACD,kCAAY,MAAqC,OAAO,iBAAiB,GAAG,0BAAa,YAAY,OAAO,UAAU,CAAC,EAAE,MAAM,CAAC,UAAU;AACtI,WAAK,OAAO,MAAM,gDAAgD,KAAK;AAAA,IAC3E,CAAC;AAAA,EACL;AAAA,EAEA,MAAc,eAAe,SAAiC;AAC1D,SAAK,gBAAgB,GAAG,QAAQ,WAAW,IAAI,CAAC,CAAC,IAAI;AAErD,UAAM,KAAK,wBAAwB,QAAQ,WAAW,IAAI,CAAC,GAAG;AAAA,MAC1D,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM,QAAQ,QAAQ;AAAA,MAC1B;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AAED,UAAM,KAAK,wBAAwB,QAAQ,WAAW,IAAI,CAAC,GAAG;AAAA,MAC1D,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM,QAAQ,gBAAgB;AAAA,MAClC;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AAED,UAAM,KAAK,wBAAwB,QAAQ,WAAW,4BAAe,UAAU,GAAG;AAAA,MAC9E,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACX;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,cAAc,QAAQ,WAAW,4BAAe,UAAU,GAAG,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AAEjG,UAAM,WAAW,QAAQ,sBAAsB;AAC/C,eAAU,YAAY,OAAO,OAAO,QAAQ,GAAG;AAC3C,WAAK,kBAAkB,SAAS,QAAQ;AAAA,IAC5C;AAGA,QAAI,QAAQ,WAAW,wCAAY,aAAa,GAAG;AAC/C,YAAM,KAAK,wBAAwB,QAAQ,WAAW,4BAAe,MAAM,GAAG;AAAA,QAC1E,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AAAA,IACL;AAEA,QAAI,QAAQ,WAAW,wCAAY,wBAAwB,GAAG;AAC1D,YAAM,KAAK,wBAAwB,QAAQ,WAAW,4BAAe,mBAAmB,GAAG;AAAA,QACvF,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AACD,YAAM,KAAK,wBAAwB,QAAQ,WAAW,4BAAe,iBAAiB,GAAG;AAAA,QACrF,MAAM;AAAA,QACN,QAAQ;AAAA,UACJ,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,QACX;AAAA,QACA,QAAQ,CAAC;AAAA,MACb,CAAC;AAAA,IACL;AAAA,EACJ;AAAA,EAEA,MAAc,iBAAiB,SAAiC;AAC5D,SAAK,eAAe,QAAQ,WAAW,IAAI,CAAC,GAAG,EAAE,WAAW,KAAK,CAAC,EAAE,MAAM,CAAC,UAAU;AACjF,WAAK,OAAO,MAAM,4CAA4C,KAAK;AAAA,IACvE,CAAC;AACD,SAAK,aAAa,KAAK,WAAW,QAAQ,UAAU,CAAC,EAAE,MAAM,CAAC,UAAU;AACpE,WAAK,OAAO,MAAM,iDAAiD,KAAK;AAAA,IAC5E,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA+BA,MAAc,uBAAuB,SAAqC;AACtE,QAAI;AACA,UAAI,QAAQ,cAAc,QAAW;AAAA,MAMrC;AAAA,IACJ,SAAS,OAAO;AACZ,UAAI,iBAAiB,iDAAqB;AAAA,MAE1C,OAAO;AACH,aAAK,OAAO,MAAM,sCAAsC,KAAK;AAAA,MACjE;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,MAAc,YAA2B;AACrC,UAAM,KAAK,wBAAwB,QAAQ;AAAA,MACvC,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,MACV;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,wBAAwB,mBAAmB;AAAA,MAClD,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACX;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,cAAc,mBAAmB,EAAE,KAAK,MAAM,KAAK,KAAK,CAAC;AAEpE,UAAM,WAAW,MAAM,KAAK,KAAK,YAAY;AAC7C,UAAM,iBAA2B,CAAC;AAClC,eAAU,WAAW,UAAU;AAC3B,qBAAe,KAAK,QAAQ,UAAU,CAAC;AAAA,IAC3C;AACA,UAAM,UAAU,MAAM,KAAK,KAAK,WAAW;AAC3C,UAAM,gBAA0B,CAAC;AACjC,eAAU,UAAU,SAAS;AACzB,oBAAc,KAAK,OAAO,UAAU,CAAC;AAAA,IACzC;AAGA,QAAI;AACA,YAAM,aAAa,MAAM,KAAK,gBAAgB;AAC9C,YAAM,MAAM,IAAI,OAAO,IAAI,KAAK,SAAS,aAAc;AACvD,iBAAW,MAAM,YAAY;AACzB,YAAI,GAAG,IAAI,MAAM,GAAG,GAAG;AACnB,gBAAM,SAAS,GAAG,IAAI,QAAQ,GAAG,KAAK,SAAS,KAAK,EAAE;AACtD,cAAI,CAAC,eAAe,SAAS,MAAM,GAAG;AAClC,kBAAM,KAAK,eAAe,GAAG,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,UACzD;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ,SAAS,OAAO;AACZ,WAAK,IAAI,MAAM,oCAAoC,KAAK,UAAU,KAAK,CAAC,EAAE;AAAA,IAC9E;AAGA,QAAI;AACA,YAAM,aAAa,MAAM,KAAK,gBAAgB;AAC9C,YAAM,MAAM,IAAI,OAAO,IAAI,KAAK,SAAS,8BAAiC;AAC1E,iBAAW,MAAM,YAAY;AACzB,YAAI,GAAG,IAAI,MAAM,GAAG,GAAG;AACnB,gBAAM,SAAS,GAAG,IAAI,MAAM,GAAG;AAC/B,gBAAM,eAAe,OAAO,CAAC;AAC7B,gBAAM,SAAS,OAAO,CAAC;AACvB,cAAI,CAAC,cAAc,SAAS,MAAM,KAC7B,cAAc,SAAS,MAAM,KAAK,QAAQ,cAAc,QAAQ,MAAM,CAAC,EAAE,gBAAgB,MAAM,aAAa,iBAAiB,WAAY;AAC1I,kBAAM,KAAK,eAAe,GAAG,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,UACzD;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ,SAAS,OAAO;AACZ,WAAK,IAAI,MAAM,mCAAmC,KAAK,UAAU,KAAK,CAAC,EAAE;AAAA,IAC7E;AAGA,QAAI;AACA,YAAM,MAAM,MAAM,KAAK,eAAe,GAAG;AACzC,UAAI,KAAK;AACL,eAAO,KAAK,GAAG,EAAE,QAAQ,OAAO,YAAY;AA72C5D;AA82CoB,gBAAM,SAAS,MAAM,KAAK,eAAe,OAAO;AAChD,gBAAI,sCAAQ,WAAR,mBAAgB,UAAS,QAAW;AACpC,kBAAM,MAAM,QAAQ,MAAM,GAAG;AAC7B,gBAAI,IAAI,UAAU,GAAG;AACjB,oBAAM,gBAAgB,IAAI,CAAC;AAC3B,oBAAM,eAAe,IAAI,CAAC;AAE1B,kBAAI,aAAa,MAAM,YAAY,GAAG;AAElC,oBAAI;AACA,wBAAM,SAAS,MAAM,KAAK,KAAK,UAAU,YAAY;AACrD,sBAAI,CAAC,OAAO,YAAY,OAAO,OAAO,IAAI,GAAG;AACzC,yBAAK,eAAe,OAAO;AAAA,kBAC/B;AAAA,gBACJ,SAAS,OAAO;AACZ,sBAAI,iBAAiB,iDAAqB;AAAA,kBAC1C,OAAO;AACH,yBAAK,IAAI,MAAM,+CAA+C,KAAK,UAAU,KAAK,CAAC,EAAE;AAAA,kBACzF;AAAA,gBACJ;AAAA,cACJ,OAAO;AAEH,oBAAI;AACA,wBAAM,UAAU,MAAM,KAAK,KAAK,WAAW,aAAa;AACxD,sBAAI,CAAC,QAAQ,YAAY,OAAO,OAAO,IAAI,GAAG;AAC1C,yBAAK,eAAe,OAAO;AAAA,kBAC/B;AAAA,gBACJ,SAAS,OAAO;AACZ,sBAAI,iBAAiB,kDAAsB;AAAA,kBAC3C,OAAO;AACH,yBAAK,IAAI,MAAM,gDAAgD,KAAK,UAAU,KAAK,CAAC,EAAE;AAAA,kBAC1F;AAAA,gBACJ;AAAA,cACJ;AAAA,YACJ;AAAA,UACJ;AAAA,QACJ,CAAC;AAAA,MACL;AAAA,IACJ,SAAS,OAAO;AACZ,WAAK,IAAI,MAAM,sCAAsC,KAAK,UAAU,KAAK,CAAC,EAAE;AAAA,IAChF;AAGA,QAAI;AACA,YAAM,WAAW,MAAM,KAAK,aAAa,KAAK,WAAW,EAAE;AAC3D,iBAAW,WAAW,SAAS,OAAO,CAAC,OAAO,GAAG,KAAK,MAAM,cAAc,MAAM,QAAQ,GAAG,KAAK,GAAG;AAC/F,YAAI,CAAC,eAAe,SAAS,QAAQ,IAAI,GAAG;AACxC,gBAAM,KAAK,aAAa,KAAK,WAAW,QAAQ,IAAI;AAAA,QACxD,OAAO;AACH,gBAAM,cAAc,MAAM,KAAK,aAAa,KAAK,WAAW,QAAQ,IAAI;AACxE,qBAAW,OAAO,YAAY,OAAO,CAAC,OAAO,OAAO,OAAO,yBAAY,EAAE,SAAS,GAAG,IAAI,KAAK,GAAG,KAAK,GAAG;AACrG,kBAAM,QAAQ,MAAM,KAAK,aAAa,KAAK,WAAW,KAAK,KAAK,QAAQ,MAAM,IAAI,IAAI,CAAC;AACvF,gBAAI,eAAe;AACnB,uBAAW,QAAQ,MAAM,OAAO,CAAC,OAAO,CAAC,cAAc,SAAS,GAAG,KAAK,UAAU,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG;AACrG,oBAAM,KAAK,aAAa,KAAK,WAAW,KAAK,KAAK,QAAQ,MAAM,IAAI,MAAM,KAAK,IAAI,CAAC;AACpF;AAAA,YACJ;AACA,gBAAI,iBAAiB,MAAM,QAAQ;AAC/B,oBAAM,KAAK,aAAa,KAAK,WAAW,KAAK,KAAK,QAAQ,MAAM,IAAI,IAAI,CAAC;AAAA,YAC7E;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ,SAAS,OAAO;AACZ,WAAK,IAAI,MAAM,6CAA6C,KAAK,EAAE;AAAA,IACvE;AAAA,EACJ;AAAA,EAEA,MAAc,UAAyB;AACnC,UAAM,KAAK,cAAc,mBAAmB,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC,EAAE,MAAM;AAAA,EACjF;AAAA,EAEO,oBAAoC;AACvC,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,MAAc,gBAA+B;AACzC,UAAM,KAAK,wBAAwB,QAAQ;AAAA,MACvC,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,MACV;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,wBAAwB,wBAAwB;AAAA,MACvD,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACX;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,cAAc,wBAAwB,EAAE,KAAK,MAAM,KAAK,KAAK,CAAC;AAAA,EAC7E;AAAA,EAEA,MAAc,cAA6B;AACvC,UAAM,KAAK,wBAAwB,QAAQ;AAAA,MACvC,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,MACV;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,wBAAwB,wBAAwB;AAAA,MACvD,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACX;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,cAAc,wBAAwB,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,EAC9E;AAAA,EAEA,MAAc,gBAA+B;AACzC,UAAM,KAAK,wBAAwB,QAAQ;AAAA,MACvC,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,MACV;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,wBAAwB,wBAAwB;AAAA,MACvD,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACX;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,cAAc,wBAAwB,EAAE,KAAK,MAAM,KAAK,KAAK,CAAC;AAAA,EAC7E;AAAA,EAEA,MAAc,cAA6B;AACvC,UAAM,KAAK,wBAAwB,QAAQ;AAAA,MACvC,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,MACV;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,wBAAwB,wBAAwB;AAAA,MACvD,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACX;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,cAAc,wBAAwB,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,EAC9E;AAAA,EAEA,MAAc,uBAAuB,SAAkB,QAAsC;AACzF,QAAI,OAAO,gBAAgB,KAAK,OAAO,iBAAiB,wCAAY,0BAA0B;AAC1F,WAAK,OAAO,MAAM,YAAY,QAAQ,UAAU,CAAC,YAAY,wCAAY,OAAO,YAAY,CAAC,uBAAuB,sCAAU,OAAO,WAAW,CAAC,KAAK,OAAO,WAAW,GAAG;AAAA,IAC/K;AAAA,EACJ;AAAA,EAEA,MAAc,yBAAyB,SAAkB,MAAc,OAAqC;AACxG,UAAM,SAAS,MAAM,KAAK,eAAe,GAAG,QAAQ,WAAW,IAAI,CAAC,CAAC,IAAI;AACzE,eAAW,SAAS,QAAQ;AACxB,YAAM,MAAM,MAAM,KAAK,eAAe,KAAK;AAC3C,UAAI,KAAK;AACL,YAAI,IAAI,OAAO,SAAS,UAAa,IAAI,OAAO,SAAS,MAAM;AAC3D,oBAAM,mCAAqB,MAAqC,QAAQ,IAAI,OAAO,SAAS,YAAY,IAAI,OAAO,SAAS,aAAa,OAAO,UAAU,WAAW,KAAK,UAAU,KAAK,IAAI,KAAK;AAClM;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AACA,SAAK,OAAO,MAAM,yCAAyC,IAAI,+CAA+C,QAAQ,UAAU,CAAC,WAAW,KAAK,UAAU,KAAK,CAAC,GAAG;AAAA,EACxK;AAAA,EAEA,MAAc,wBAAwB,QAAgB,MAAc,OAAqC;AACrG,UAAM,SAAS,MAAM,KAAK,eAAe,GAAG,OAAO,WAAW,IAAI,CAAC,CAAC,IAAI;AACxE,eAAW,SAAS,QAAQ;AACxB,YAAM,MAAM,MAAM,KAAK,eAAe,KAAK;AAC3C,UAAI,KAAK;AACL,YAAI,IAAI,OAAO,SAAS,UAAa,IAAI,OAAO,SAAS,MAAM;AAC3D,oBAAM,mCAAqB,MAAqC,QAAQ,IAAI,OAAO,SAAS,YAAY,IAAI,OAAO,SAAS,aAAa,OAAO,UAAU,WAAW,KAAK,UAAU,KAAK,IAAI,KAAK;AAClM,kBAAO,MAAM;AAAA,YACT,KAAK,yCAAa;AACd,kBAAI,UAAqB,OAAO;AAC5B,qBAAK,cAAc,OAAO,WAAW,2BAAc,eAAe,CAAC;AAAA,cACvE;AACA;AAAA,UACR;AACA;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AACA,QAAI,SAAS,yCAAa,eAAe;AACrC,UAAI;AACA,cAAM,UAAU;AAChB,cAAM,WAAW,GAAG,OAAO,UAAU,CAAC,IAAI,QAAQ,KAAK,GAAG;AAC1D,cAAM,WAAW,KAAK,KAAK,OAAO,iBAAiB,GAAG,0BAAa,UAAU;AAC7E,YAAI,CAAC,MAAM,KAAK,gBAAgB,KAAK,WAAW,QAAQ,GAAG;AACvD,gBAAM,KAAK,WAAW,KAAK,WAAW,QAAQ;AAAA,QAClD;AACA,cAAM,KAAK,eAAe,KAAK,WAAW,KAAK,KAAK,UAAU,QAAQ,GAAG,QAAQ,IAAI;AAErF,cAAM,KAAK,cAAc,OAAO,WAAW,2BAAc,WAAW,GAAG,UAAU,KAAK,SAAS,IAAI,OAAO,iBAAiB,CAAC,IAAI,0BAAa,UAAU,IAAI,OAAO,UAAU,CAAC,IAAI,QAAQ,KAAK,GAAG,IAAI,IAAI;AACzM,kBAAM,mCAAqB,MAAqC,OAAO,WAAW,2BAAc,YAAY,OAAG,6BAAe,QAAQ,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,MAClK,SAAS,KAAK;AACV,cAAM,YAAQ,yCAAY,GAAG;AAC7B,aAAK,OAAO,MAAM,sDAAsD,KAAK;AAAA,MACjF;AAAA,IACJ,OAAO;AACH,WAAK,OAAO,MAAM,wCAAwC,IAAI,8CAA8C,OAAO,UAAU,CAAC,WAAW,KAAK,UAAU,KAAK,CAAC,GAAG;AAAA,IACrK;AAAA,EACJ;AAAA,EAEA,MAAc,gBAAgB,WAAkC;AAC5D,QAAI;AACA,YAAM,SAAS,MAAM,KAAK,KAAK,UAAU,SAAS;AAClD,YAAM,UAAU,MAAM,KAAK,KAAK,WAAW,OAAO,iBAAiB,CAAC;AAEpE,UAAI,QAAQ,YAAY,KAAK,QAAQ,qBAAqB,GAAG;AACzD,YAAI,CAAC,QAAQ,gBAAgB,MAAM,GAAG;AAClC,eAAK,KAAK,uBAAuB,SAAS;AAAA,QAC9C,OAAO;AACH,eAAK,OAAO,KAAK,6BAA6B,SAAS,sDAAsD;AAAA,QACjH;AAAA,MACJ,OAAO;AACH,aAAK,OAAO,KAAK,6BAA6B,SAAS,iEAAiE,QAAQ,UAAU,CAAC,GAAG;AAAA,MAClJ;AAAA,IACJ,SAAS,OAAO;AACZ,WAAK,OAAO,MAAM,4BAA4B,KAAK;AAAA,IACvD;AAAA,EACJ;AAAA,EAEA,MAAc,eAAe,WAAkC;AAC3D,QAAI;AACA,YAAM,SAAS,MAAM,KAAK,KAAK,UAAU,SAAS;AAClD,YAAM,UAAU,MAAM,KAAK,KAAK,WAAW,OAAO,iBAAiB,CAAC;AACpE,UAAI,OAAO,SAAS,GAAG;AACnB,cAAM,SAAS;AACf,YAAI,MAAM,KAAK,KAAK,mBAAmB,OAAO,iBAAiB,CAAC,KAAK,QAAQ,gBAAgB,MAAM,GAAG;AAClG,gBAAM,KAAK,KAAK,sBAAsB,SAAS;AAAA,QACnD,OAAO;AACH,eAAK,OAAO,KAAK,6BAA6B,SAAS,iDAAiD;AAAA,QAC5G;AAAA,MACJ;AAAA,IAEJ,SAAS,OAAO;AACZ,WAAK,OAAO,MAAM,2BAA2B,KAAK;AAAA,IACtD;AAAA,EACJ;AAAA,EAEA,MAAc,yBAAyB,SAAkB,QAAgB,UAA0B,aAAuB,aAAsC;AAC5J,QAAI;AACA,WAAK,cAAc,OAAO,WAAW,2BAAc,UAAU,GAAG,EAAE,KAAK,GAAG,KAAK,OAAO,QAAQ,UAAU,MAAM,MAAM,KAAK,OAAO,QAAQ,IAAI,KAAK,OAAO,eAAe,oBAAoB,OAAO,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC;AAC5N,WAAK,cAAc,OAAO,WAAW,2BAAc,eAAe,GAAG,EAAE,KAAK,UAAU,KAAK,OAAO,QAAQ,IAAI,KAAK,OAAO,gBAAgB,IAAI,OAAO,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC;AAE/K,gBAAM,6BAAe,OAAO,UAAU,GAAG,aAAa,aAAa,KAAK,QAAQ,KAAK,QAAQ,KAAK,WAAW,QAAQ,EAAE,MAAM,CAAC,UAAU;AACpI,aAAK,OAAO,MAAM,YAAY,QAAQ,UAAU,CAAC,YAAY,OAAO,UAAU,CAAC,6BAA6B,KAAK;AAAA,MACrH,CAAC;AAAA,IACL,SAAQ,OAAO;AACX,WAAK,OAAO,MAAM,YAAY,QAAQ,UAAU,CAAC,YAAY,OAAO,UAAU,CAAC,qCAAqC,KAAK;AACzH,WAAK,KAAK,sBAAsB,OAAO,UAAU,CAAC,EAC7C,MAAM,OAAOC,WAAU;AACpB,aAAK,OAAO,MAAM,YAAY,QAAQ,UAAU,CAAC,YAAY,OAAO,UAAU,CAAC,0CAA0CA,MAAK;AAAA,MAClI,CAAC;AAAA,IACT;AAAA,EACJ;AAAA,EAEQ,wBAAwB,UAAmB,QAAsB;AACrE,SAAK,cAAc,OAAO,WAAW,2BAAc,UAAU,CAAC;AAC9D,SAAK,cAAc,OAAO,WAAW,2BAAc,eAAe,CAAC;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyDQ,iBAAiB,SAAkB,QAAgB,OAAqB;AAC5E,2CAAqB,MAAqC,OAAO,WAAW,2BAAc,eAAe,GAAG,KAAK;AAAA,EACrH;AAAA,EAEA,MAAc,iBAAiB,SAAiC;AAC5D,UAAM,KAAK,wBAAwB,QAAQ,WAAW,4BAAe,UAAU,GAAG;AAAA,MAC9E,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACX;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,cAAc,QAAQ,WAAW,4BAAe,UAAU,GAAG,EAAE,KAAK,MAAM,KAAK,KAAK,CAAC;AAAA,EACpG;AAAA,EAEA,MAAc,eAAe,SAAiC;AAC1D,UAAM,KAAK,wBAAwB,QAAQ,WAAW,4BAAe,UAAU,GAAG;AAAA,MAC9E,MAAM;AAAA,MACN,QAAQ;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACX;AAAA,MACA,QAAQ,CAAC;AAAA,IACb,CAAC;AACD,UAAM,KAAK,cAAc,QAAQ,WAAW,4BAAe,UAAU,GAAG,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC;AAAA,EACrG;AAAA,EAEQ,eAAqB;AACzB,SAAK,OAAO,KAAK,6FAA6F,KAAK,SAAS,cAAc;AAC1I,SAAK,cAAa;AAAA,EACtB;AAAA,EAEQ,iBAAiB,WAAmB,SAAuB;AAC/D,SAAK,YAAY;AACjB,SAAK,OAAO,KAAK,gFAAgF,KAAK,SAAS,UAAU;AACzH,SAAK,OAAO,KAAK,sBAAsB,OAAO,IAAI;AAClD,SAAK,cAAc,yBAAyB,EAAE,KAAK,aAAa,OAAO,MAAM,KAAK,KAAK,CAAC;AAAA,EAC5F;AAEJ;AAEA,IAAI,QAAQ,SAAS,QAAQ;AAEzB,SAAO,UAAU,CAAC,YAAuD,IAAI,MAAM,OAAO;AAC9F,OAAO;AAEH,GAAC,MAAM,IAAI,MAAM,GAAG;AACxB;",
4
+ "sourcesContent": ["/*\r\n * Created with @iobroker/create-adapter v2.5.0\r\n */\r\n\r\n// The adapter-core module gives you access to the core ioBroker functions\r\n// you need to create an adapter\r\nimport * as utils from \"@iobroker/adapter-core\";\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nimport { strict } from \"assert\";\r\nimport * as path from \"path\";\r\nimport { Camera, Device, Station, PushMessage, P2PConnectionType, EufySecurity, EufySecurityConfig, CommandResult, CommandType, ErrorCode, PropertyValue, PropertyName, StreamMetadata, PropertyMetadataNumeric, PropertyMetadataAny, CommandName, PanTiltDirection, DeviceNotFoundError, LoginOptions, Picture, StationNotFoundError, ensureError, LogLevel } from \"eufy-security-client\";\r\nimport { getAlpha2Code as getCountryCode } from \"i18n-iso-countries\"\r\nimport { isValid as isValidLanguageCode } from \"@cospired/i18n-iso-languages\"\r\nimport { Readable } from \"stream\";\r\nimport util from \"util\";\r\nimport childProcess from \"child_process\";\r\nimport pathToGo2rtc from \"go2rtc-static\";\r\nimport pathToFfmpeg from \"ffmpeg-for-homebridge\";\r\n\r\nimport { DeviceStateID, DataLocation, RoleMapping, StationStateID } from \"./lib/types\";\r\nimport { convertCamelCaseToSnakeCase, getImageAsHTML, handleUpdate, removeFiles, removeLastChar, setStateChangedAsync } from \"./lib/utils\";\r\nimport { PersistentData } from \"./lib/interfaces\";\r\nimport { ioBrokerLogger } from \"./lib/log\";\r\nimport { streamToGo2rtc } from \"./lib/video\";\r\n\r\nexport class euSec extends utils.Adapter {\r\n\r\n private eufy!: EufySecurity;\r\n /*private downloadEvent: {\r\n [index: string]: NodeJS.Timeout;\r\n } = {};*/\r\n\r\n private persistentFile: string = \"adapter.json\";\r\n private persistentDriverFile: string = \"driver.json\";\r\n private logger!: ioBrokerLogger;\r\n private persistentData: PersistentData = {\r\n version: \"\"\r\n };\r\n private captchaId: string | null = null;\r\n private verify_code = false;\r\n private skipInit = false;\r\n\r\n public constructor(options: Partial<utils.AdapterOptions> = {}) {\r\n super({\r\n ...options,\r\n name: \"eusec\",\r\n });\r\n\r\n this.on(\"ready\", this.onReady.bind(this));\r\n this.on(\"stateChange\", this.onStateChange.bind(this));\r\n // this.on(\"objectChange\", this.onObjectChange.bind(this));\r\n this.on(\"message\", this.onMessage.bind(this));\r\n this.on(\"unload\", this.onUnload.bind(this));\r\n }\r\n\r\n public restartAdapter(): void {\r\n this.skipInit = true;\r\n this.restart();\r\n }\r\n\r\n /**\r\n * Is called when databases are connected and adapter received configuration.\r\n */\r\n private async onReady(): Promise<void> {\r\n\r\n this.logger = new ioBrokerLogger(this.log as ioBroker.Logger);\r\n\r\n await this.setObjectNotExistsAsync(\"verify_code\", {\r\n type: \"state\",\r\n common: {\r\n name: \"2FA verification code\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"received_captcha_html\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Received captcha image HTML\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"captcha\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Enter captcha\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Global connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: false, ack: true });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: false, ack: true });\r\n\r\n try {\r\n const connection = await this.getStatesAsync(\"*.connection\");\r\n if (connection)\r\n Object.keys(connection).forEach(async id => {\r\n await this.setStateAsync(id, { val: false, ack: true });\r\n });\r\n } catch (error) {\r\n this.logger.error(\"Reset connection states - Error\", error);\r\n }\r\n\r\n try {\r\n const sensorList = [\r\n PropertyName.DeviceMotionDetected,\r\n PropertyName.DevicePersonDetected,\r\n PropertyName.DeviceSoundDetected,\r\n PropertyName.DeviceCryingDetected,\r\n PropertyName.DevicePetDetected,\r\n PropertyName.DeviceRinging\r\n ];\r\n for(const sensorName of sensorList) {\r\n const sensors = await this.getStatesAsync(`*.${convertCamelCaseToSnakeCase(sensorName)}`);\r\n if (sensors)\r\n Object.keys(sensors).forEach(async id => {\r\n await this.setStateAsync(id, { val: false, ack: true });\r\n });\r\n }\r\n } catch (error) {\r\n this.logger.error(\"Reset sensor states - Error\", error);\r\n }\r\n\r\n try {\r\n if (await this.fileExistsAsync(this.namespace, this.persistentFile)) {\r\n const fileContent = await this.readFileAsync(this.namespace, this.persistentFile);\r\n this.persistentData = JSON.parse(fileContent.file.toString(\"utf8\")) as PersistentData;\r\n }\r\n } catch (error) {\r\n this.logger.debug(\"No adapter stored data from last exit found.\", error);\r\n }\r\n\r\n let persistentDriverData: string = \"{}\";\r\n try {\r\n if (await this.fileExistsAsync(this.namespace, this.persistentDriverFile)) {\r\n const fileContent = await this.readFileAsync(this.namespace, this.persistentDriverFile);\r\n persistentDriverData = fileContent.file.toString(\"utf8\");\r\n }\r\n } catch (error) {\r\n this.logger.debug(\"No driver stored data from last exit found.\", error);\r\n }\r\n\r\n this.subscribeStates(\"verify_code\");\r\n this.subscribeStates(\"captcha\");\r\n\r\n const hosts = await this.getForeignObjectsAsync(\"system.host.*\", \"host\");\r\n if (hosts !== undefined && hosts !== null && Object.values(hosts).length !== 0) {\r\n if (this.config.hostname === \"\") {\r\n this.config.hostname = Object.values(hosts)[0].native.os.hostname;\r\n }\r\n\r\n const nodeVersion = Object.values(hosts)[0].native.process.versions.node;\r\n const nodeMajorVersion = nodeVersion.split(\".\")[0];\r\n\r\n let fixNeeded;\r\n switch (parseInt(nodeMajorVersion)) {\r\n case 18:\r\n fixNeeded = nodeVersion.localeCompare(\"18.19.1\", undefined, { numeric: true, sensitivity: \"base\" });\r\n break;\r\n case 20:\r\n fixNeeded = nodeVersion.localeCompare(\"20.11.1\", undefined, { numeric: true, sensitivity: \"base\" });\r\n break;\r\n default:\r\n fixNeeded = nodeVersion.localeCompare(\"21.6.2\", undefined, { numeric: true, sensitivity: \"base\" });\r\n break;\r\n }\r\n if (fixNeeded >= 0) {\r\n const adapter = await this.getForeignObjectAsync(`system.adapter.${this.namespace}`);\r\n if (adapter !== undefined && adapter !== null) {\r\n if (!adapter.common.nodeProcessParams?.includes(\"--security-revert=CVE-2023-46809\")) {\r\n adapter.common.nodeProcessParams = [\"--security-revert=CVE-2023-46809\"]\r\n await this.setForeignObjectAsync(`system.adapter.${this.namespace}`, adapter);\r\n this.log.warn(\"Required fix to use livestreaming with this version of Node.js (CVE-2023-46809) applied. Restart of the adapter initiated to activate the fix.\");\r\n this.restartAdapter();\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (!this.skipInit) {\r\n const systemConfig = await this.getForeignObjectAsync(\"system.config\");\r\n let countryCode = undefined;\r\n let languageCode = undefined;\r\n if (systemConfig) {\r\n countryCode = getCountryCode(systemConfig.common.country!, \"en\");\r\n if (isValidLanguageCode(systemConfig.common.language))\r\n languageCode = systemConfig.common.language;\r\n }\r\n if (this.config.country !== \"iobroker\") {\r\n countryCode = this.config.country;\r\n }\r\n\r\n // Handling adapter version update\r\n try {\r\n if (this.persistentData.version !== this.version) {\r\n const currentVersion = Number.parseFloat(removeLastChar(this.version!, \".\"));\r\n const previousVersion = this.persistentData.version !== \"\" && this.persistentData.version !== undefined ? Number.parseFloat(removeLastChar(this.persistentData.version, \".\")) : 0;\r\n this.logger.debug(`Handling of adapter update - currentVersion: ${currentVersion} previousVersion: ${previousVersion}`);\r\n\r\n if (previousVersion < currentVersion) {\r\n await handleUpdate(this, this.logger, previousVersion, currentVersion);\r\n this.persistentData.version = this.version!;\r\n await this.writePersistentData();\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`Handling of adapter update - Error:`, error);\r\n }\r\n\r\n let connectionType = P2PConnectionType.QUICKEST;\r\n if (this.config.p2pConnectionType === \"only_local\") {\r\n connectionType = P2PConnectionType.ONLY_LOCAL;\r\n }\r\n\r\n if (this.config.username !== \"\" && this.config.password !== \"\") {\r\n const config: EufySecurityConfig = {\r\n username: this.config.username,\r\n password: this.config.password,\r\n country: countryCode,\r\n language: languageCode,\r\n persistentData: persistentDriverData,\r\n eventDurationSeconds: this.config.eventDuration,\r\n p2pConnectionSetup: connectionType,\r\n pollingIntervalMinutes: this.config.pollingInterval,\r\n acceptInvitations: this.config.acceptInvitations,\r\n logging: {\r\n level: this.log.level === \"silly\" ? LogLevel.Trace : this.log.level === \"debug\" ? LogLevel.Debug : this.log.level === \"info\" ? LogLevel.Info : this.log.level === \"warn\" ? LogLevel.Warn : this.log.level === \"error\" ? LogLevel.Error : LogLevel.Info\r\n }\r\n };\r\n\r\n this.eufy = await EufySecurity.initialize(config, this.logger);\r\n this.eufy.on(\"persistent data\", (data: string) => this.onPersistentData(data))\r\n this.eufy.on(\"station added\", (station: Station) => this.onStationAdded(station));\r\n this.eufy.on(\"device added\", (device: Device) => this.onDeviceAdded(device));\r\n this.eufy.on(\"station removed\", (station: Station) => this.onStationRemoved(station));\r\n this.eufy.on(\"device removed\", (device: Device) => this.onDeviceRemoved(device));\r\n this.eufy.on(\"push message\", (messages) => this.handlePushNotification(messages));\r\n this.eufy.on(\"push connect\", () => this.onPushConnect());\r\n this.eufy.on(\"push close\", () => this.onPushClose());\r\n this.eufy.on(\"mqtt connect\", () => this.onMQTTConnect());\r\n this.eufy.on(\"mqtt close\", () => this.onMQTTClose());\r\n this.eufy.on(\"connect\", () => this.onConnect());\r\n this.eufy.on(\"close\", () => this.onClose());\r\n\r\n this.eufy.on(\"device property changed\", (device: Device, name: string, value: PropertyValue) => this.onDevicePropertyChanged(device, name, value));\r\n\r\n this.eufy.on(\"station command result\", (station: Station, result: CommandResult) => this.onStationCommandResult(station, result));\r\n //this.eufy.on(\"station download start\", (station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable) => this.onStationDownloadStart(station, device, metadata, videostream, audiostream));\r\n //this.eufy.on(\"station download finish\", (station: Station, device: Device) => this.onStationDownloadFinish(station, device));\r\n this.eufy.on(\"station livestream start\", (station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable) => this.onStationLivestreamStart(station, device, metadata, videostream, audiostream));\r\n this.eufy.on(\"station livestream stop\", (station: Station, device: Device) => this.onStationLivestreamStop(station, device));\r\n this.eufy.on(\"station rtsp url\", (station: Station, device: Device, value: string) => this.onStationRTSPUrl(station, device, value));\r\n this.eufy.on(\"station property changed\", (station: Station, name: string, value: PropertyValue) => this.onStationPropertyChanged(station, name, value));\r\n this.eufy.on(\"station connect\", (station: Station) => this.onStationConnect(station));\r\n this.eufy.on(\"station close\", (station: Station) => this.onStationClose(station));\r\n this.eufy.on(\"tfa request\", () => this.onTFARequest());\r\n this.eufy.on(\"captcha request\", (captchaId: string, captcha: string) => this.onCaptchaRequest(captchaId, captcha));\r\n this.eufy.setCameraMaxLivestreamDuration(this.config.maxLivestreamDuration);\r\n\r\n await this.eufy.connect();\r\n\r\n if (pathToGo2rtc) {\r\n const go2rtcConfig: {\r\n [index: string]: {\r\n [index: string]: string | number | null\r\n }\r\n } = {\r\n \"api\": {\r\n \"listen\": `:${this.config.go2rtc_api_port}`\r\n },\r\n \"rtsp\": {\r\n \"listen\": `:${this.config.go2rtc_rtsp_port}`\r\n },\r\n \"srtp\": {\r\n \"listen\": `:${this.config.go2rtc_srtp_port}`\r\n },\r\n \"webrtc\": {\r\n \"listen\": `:${this.config.go2rtc_webrtc_port}`\r\n },\r\n \"ffmpeg\": {\r\n \"bin\": pathToFfmpeg !== \"\" && pathToFfmpeg !== undefined ? pathToFfmpeg : \"ffmpeg\",\r\n },\r\n \"streams\": {},\r\n /*\"log\": {\r\n \"level\": \"debug\", // default level\r\n \"api\": \"debug\",\r\n \"exec\": \"debug\",\r\n \"ngrok\": \"debug\",\r\n \"rtsp\": \"debug\",\r\n \"streams\": \"debug\",\r\n \"webrtc\": \"debug\",\r\n }*/\r\n };\r\n if (this.config.go2rtc_rtsp_username !== \"\" && this.config.go2rtc_rtsp_password !== \"\") {\r\n go2rtcConfig.rtsp.username = this.config.go2rtc_rtsp_username;\r\n go2rtcConfig.rtsp.password = this.config.go2rtc_rtsp_password;\r\n }\r\n for (const device of await this.eufy.getDevices()) {\r\n go2rtcConfig.streams[device.getSerial()] = null;\r\n }\r\n const go2rtc = childProcess.spawn(pathToGo2rtc, [\"-config\", JSON.stringify(go2rtcConfig)], { shell: false, detached: false, windowsHide: true });\r\n go2rtc.on(\"error\", (error) => {\r\n this.log.error(`go2rtc error: ${error}`);\r\n });\r\n go2rtc.stdout.setEncoding(\"utf8\");\r\n go2rtc.stdout.on(\"data\", (data) => {\r\n this.log.info(`go2rtc started: ${data}`);\r\n });\r\n go2rtc.stderr.setEncoding(\"utf8\");\r\n go2rtc.stderr.on(\"data\", (data) => {\r\n this.log.error(`go2rtc error: ${data}`);\r\n });\r\n go2rtc.on(\"close\", (exitcode) => {\r\n this.log.info(`go2rtc terminated with exitcode ${exitcode}`);\r\n });\r\n process.on(\"exit\", () => {\r\n go2rtc.kill();\r\n });\r\n }\r\n }\r\n // Delete cunknown channels without childs\r\n const channels = await this.getChannelsAsync();\r\n for (const channel of channels) {\r\n if (channel.common.name === \"unknown\") {\r\n const states = await this.getStatesAsync(`${channel._id}.*`);\r\n if (Object.keys(states).length === 0) {\r\n await this.delObjectAsync(channel._id);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n public async writePersistentData(): Promise<void> {\r\n try {\r\n await this.writeFileAsync(this.namespace, this.persistentFile, JSON.stringify(this.persistentData));\r\n } catch(error) {\r\n this.logger.error(`writePersistentData() - Error: ${error}`);\r\n }\r\n }\r\n\r\n private onPersistentData(data: string): void {\r\n this.writeFileAsync(this.namespace, this.persistentDriverFile, data).catch((error) => {\r\n this.logger.error(`writePersistentDriverData() - Error: ${error}`);\r\n });\r\n }\r\n\r\n /**\r\n * Is called when adapter shuts down - callback has to be called under any circumstances!\r\n */\r\n private async onUnload(callback: () => void): Promise<void> {\r\n try {\r\n\r\n await this.writePersistentData();\r\n\r\n if (this.eufy) {\r\n if (this.eufy.isConnected())\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true }).catch();\r\n this.eufy.removeAllListeners();\r\n this.eufy.close();\r\n }\r\n\r\n callback();\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n } catch (e) {\r\n callback();\r\n }\r\n }\r\n\r\n // If you need to react to object changes, uncomment the following block and the corresponding line in the constructor.\r\n // You also need to subscribe to the objects with `this.subscribeObjects`, similar to `this.subscribeStates`.\r\n // /**\r\n // * Is called if a subscribed object changes\r\n // */\r\n // private onObjectChange(id: string, obj: ioBroker.Object | null | undefined): void {\r\n // if (obj) {\r\n // // The object was changed\r\n // this.log.info(`object ${id} changed: ${JSON.stringify(obj)}`);\r\n // } else {\r\n // // The object was deleted\r\n // this.log.info(`object ${id} deleted`);\r\n // }\r\n // }\r\n\r\n /**\r\n * Is called if a subscribed state changes\r\n */\r\n private async onStateChange(id: string, state: ioBroker.State | null | undefined): Promise<void> {\r\n if (state) {\r\n\r\n // don't do anything if the state is acked\r\n if (!id || state.ack) {\r\n this.logger.debug(`state ${id} changed: ${state.val} (ack = ${state.ack}) was already acknowledged, ignore it...`);\r\n return;\r\n }\r\n this.logger.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`);\r\n\r\n const values = id.split(\".\");\r\n const station_sn = values[2];\r\n const device_type = values[3];\r\n\r\n if (station_sn == \"verify_code\") {\r\n if (this.eufy && this.verify_code) {\r\n this.logger.info(`Verification code received, send it. (verify_code: ${state.val})`);\r\n await this.eufy.connect({ verifyCode: state.val as string } as LoginOptions);\r\n this.verify_code = false;\r\n await this.delStateAsync(id);\r\n }\r\n } else if (station_sn == \"captcha\") {\r\n if (this.eufy && this.captchaId) {\r\n this.logger.info(`Captcha received, send it. (captcha: ${state.val})`);\r\n await this.eufy.connect({\r\n captcha: {\r\n captchaCode: state.val as string,\r\n captchaId: this.captchaId\r\n }\r\n } as LoginOptions);\r\n this.captchaId = null;\r\n await this.delStateAsync(id);\r\n await this.delStateAsync(\"received_captcha_html\");\r\n }\r\n } else if (device_type == \"station\") {\r\n try {\r\n const station_state_name = values[4];\r\n if (this.eufy) {\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n if (obj.native.name !== undefined) {\r\n await this.eufy.setStationProperty(station_sn, obj.native.name, state.val);\r\n return;\r\n }\r\n }\r\n\r\n const station = await this.eufy.getStation(station_sn);\r\n switch(station_state_name) {\r\n case StationStateID.REBOOT:\r\n await station.rebootHUB();\r\n break;\r\n case StationStateID.TRIGGER_ALARM_SOUND:\r\n await station.triggerStationAlarmSound(this.config.alarmSoundDuration);\r\n break;\r\n case StationStateID.RESET_ALARM_SOUND:\r\n await station.resetStationAlarmSound();\r\n break;\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`station - Error:`, error);\r\n }\r\n } else {\r\n try {\r\n const device_sn = values[4];\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n if (obj.native.name !== undefined) {\r\n try {\r\n await this.eufy.setDeviceProperty(device_sn, obj.native.name, obj.common.type === \"object\" ? JSON.parse(state.val as string) : state.val);\r\n } catch (error) {\r\n this.logger.error(`Error in setting property value (property: ${obj.native.name} value: ${state.val})`, error);\r\n }\r\n return;\r\n }\r\n }\r\n\r\n const device_state_name = values[5];\r\n const station = await this.eufy.getStation(station_sn);\r\n const device = await this.eufy.getDevice(device_sn);\r\n\r\n switch(device_state_name) {\r\n case DeviceStateID.START_STREAM:\r\n await this.startLivestream(device_sn);\r\n break;\r\n case DeviceStateID.STOP_STREAM:\r\n await this.stopLivestream(device_sn);\r\n break;\r\n case DeviceStateID.TRIGGER_ALARM_SOUND:\r\n await station.triggerDeviceAlarmSound(device, this.config.alarmSoundDuration);\r\n break;\r\n case DeviceStateID.RESET_ALARM_SOUND:\r\n await station.resetDeviceAlarmSound(device);\r\n break;\r\n case DeviceStateID.ROTATE_360:\r\n await station.panAndTilt(device, PanTiltDirection.ROTATE360);\r\n break;\r\n case DeviceStateID.PAN_LEFT:\r\n await station.panAndTilt(device, PanTiltDirection.LEFT);\r\n break;\r\n case DeviceStateID.PAN_RIGHT:\r\n await station.panAndTilt(device, PanTiltDirection.RIGHT);\r\n break;\r\n case DeviceStateID.TILT_UP:\r\n await station.panAndTilt(device, PanTiltDirection.UP);\r\n break;\r\n case DeviceStateID.TILT_DOWN:\r\n await station.panAndTilt(device, PanTiltDirection.DOWN);\r\n break;\r\n case DeviceStateID.CALIBRATE:\r\n if (device.isLock()) {\r\n await station.calibrateLock(device);\r\n } else {\r\n await station.calibrate(device);\r\n }\r\n break;\r\n case DeviceStateID.UNLOCK:\r\n await station.unlock(device);\r\n break;\r\n case DeviceStateID.SET_DEFAULT_ANGLE:\r\n await station.setDefaultAngle(device);\r\n break;\r\n case DeviceStateID.SET_PRIVACY_ANGLE:\r\n await station.setPrivacyAngle(device);\r\n break;\r\n case DeviceStateID.OPEN_BOX:\r\n await station.open(device);\r\n break;\r\n }\r\n } catch (error) {\r\n this.logger.error(`cameras - Error:`, error);\r\n }\r\n }\r\n } else {\r\n // The state was deleted\r\n this.logger.debug(`state ${id} deleted`);\r\n }\r\n }\r\n\r\n /**\r\n * Some message was sent to this instance over message box. Used by email, pushover, text2speech, ...\r\n * Using this method requires \"common.message\" property to be set to true in io-package.json\r\n */\r\n private async onMessage(obj: ioBroker.Message): Promise<void> {\r\n if (typeof obj === \"object\" && obj.message) {\r\n try {\r\n if (obj.command === \"quickResponse\") {\r\n this.log.debug(`quickResponse command - message: ${JSON.stringify(obj.message)}`);\r\n if (typeof obj.message === \"object\" &&\r\n typeof obj.message.station_sn === \"string\" && obj.message.station_sn !== \"\" &&\r\n typeof obj.message.device_sn === \"string\" && obj.message.device_sn !== \"\" &&\r\n typeof obj.message.voice_id === \"number\") {\r\n try {\r\n const station = await this.eufy.getStation(obj.message.station_sn);\r\n const device = await this.eufy.getDevice(obj.message.device_sn);\r\n\r\n if (device.hasCommand(CommandName.DeviceQuickResponse)) {\r\n await station.quickResponse(device, obj.message.voice_id);\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: true,\r\n result: \"quickResponse command sended\"\r\n }, obj.callback);\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"quickResponse command not supported by specified device\"\r\n }, obj.callback);\r\n }\r\n } catch (error) {\r\n if (error instanceof StationNotFoundError) {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"quickResponse command not sended because specified station doesn't exists\"\r\n }, obj.callback);\r\n } else if (error instanceof DeviceNotFoundError) {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"quickResponse command not sended because specified device doesn't exists\"\r\n }, obj.callback);\r\n } else {\r\n throw error;\r\n }\r\n }\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"quickResponse command not sended because some required parameters are missing\"\r\n }, obj.callback);\r\n }\r\n } else if (obj.command === \"getQuickResponseVoices\") {\r\n this.log.debug(`getQuickResponseVoices command - message: ${JSON.stringify(obj.message)}`);\r\n if (typeof obj.message === \"object\" &&\r\n typeof obj.message.device_sn === \"string\" && obj.message.device_sn !== \"\") {\r\n const voices = await this.eufy.getApi().getVoices(obj.message.device_sn);\r\n\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: true,\r\n result: voices\r\n }, obj.callback);\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"getQuickResponseVoices command not sended because some required parameters are missing\"\r\n }, obj.callback);\r\n }\r\n } else if (obj.command === \"snooze\") {\r\n this.log.debug(`snooze command - message: ${JSON.stringify(obj.message)}`);\r\n if (typeof obj.message === \"object\" &&\r\n typeof obj.message.station_sn === \"string\" && obj.message.station_sn !== \"\" &&\r\n typeof obj.message.device_sn === \"string\" && obj.message.device_sn !== \"\" &&\r\n typeof obj.message.snooze_time === \"number\" &&\r\n (obj.message.snooze_chime === undefined || typeof obj.message.snooze_chime === \"boolean\") &&\r\n (obj.message.snooze_homebase === undefined || typeof obj.message.snooze_homebase === \"boolean\") &&\r\n (obj.message.snooze_motion === undefined || typeof obj.message.snooze_motion === \"boolean\")) {\r\n try {\r\n const station = await this.eufy.getStation(obj.message.station_sn);\r\n const device = await this.eufy.getDevice(obj.message.device_sn);\r\n\r\n if (device.hasCommand(CommandName.DeviceSnooze)) {\r\n await station.snooze(device, {\r\n snooze_time: obj.message.snooze_time,\r\n snooze_chime: obj.message.snooze_chime,\r\n snooze_homebase: obj.message.snooze_homebase,\r\n snooze_motion: obj.message.snooze_motion,\r\n });\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: true,\r\n result: \"snooze command sended\"\r\n }, obj.callback);\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"snooze command not supported by specified device\"\r\n }, obj.callback);\r\n }\r\n } catch (error) {\r\n if (error instanceof StationNotFoundError) {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"snooze command not sended because specified station doesn't exists\"\r\n }, obj.callback);\r\n } else if (error instanceof DeviceNotFoundError) {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"snooze command not sended because specified device doesn't exists\"\r\n }, obj.callback);\r\n } else {\r\n throw error;\r\n }\r\n }\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"snooze command not sended because some required parameters are missing\"\r\n }, obj.callback);\r\n }\r\n } else if (obj.command === \"chime\") {\r\n this.log.debug(`snooze command - message: ${JSON.stringify(obj.message)}`);\r\n if (typeof obj.message === \"object\" &&\r\n typeof obj.message.station_sn === \"string\" && obj.message.station_sn !== \"\" &&\r\n (obj.message.ringtone === undefined || typeof obj.message.ringtone === \"number\")) {\r\n try {\r\n const station = await this.eufy.getStation(obj.message.station_sn);\r\n\r\n if (station.hasCommand(CommandName.StationChime)) {\r\n await station.chimeHomebase(obj.message.ringtone !== undefined && typeof obj.message.ringtone === \"number\" ? obj.message.ringtone : 0);\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: true,\r\n result: \"chime command sended\"\r\n }, obj.callback);\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"chime command not supported by specified station\"\r\n }, obj.callback);\r\n }\r\n\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, \"chime command sended\", obj.callback);\r\n } catch (error) {\r\n if (error instanceof StationNotFoundError) {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"snooze command not sended because specified station doesn't exists\"\r\n }, obj.callback);\r\n } else {\r\n throw error;\r\n }\r\n }\r\n }\r\n } else if (obj.command === \"pollRefresh\") {\r\n this.log.debug(`pollRefresh command`);\r\n await this.eufy.refreshCloudData();\r\n\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: true,\r\n result: \"pollRefresh command sended\"\r\n }, obj.callback);\r\n } else {\r\n const errorMessage = `Received unknown message: ${JSON.stringify(obj.message)}`;\r\n this.log.warn(errorMessage);\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: errorMessage\r\n }, obj.callback);\r\n }\r\n } catch (error) {\r\n const errorMessage = `Error during processing of received message: ${error instanceof Error ? `${error.name} - ${error.message}` : error }`;\r\n this.log.error(errorMessage);\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: errorMessage\r\n }, obj.callback);\r\n }\r\n }\r\n }\r\n\r\n private getStateCommon(property: PropertyMetadataAny): ioBroker.StateCommon {\r\n const state: ioBroker.StateCommon = {\r\n name: property.label!,\r\n type: property.type,\r\n role: \"state\",\r\n read: property.readable,\r\n write: property.writeable,\r\n def: property.type === \"object\" && typeof property.default === \"object\" ? JSON.stringify(property.default) : property.default\r\n };\r\n switch (property.type) {\r\n case \"number\": {\r\n const numberProperty = property as PropertyMetadataNumeric;\r\n state.min = numberProperty.min;\r\n state.max = numberProperty.max;\r\n state.states = numberProperty.states;\r\n state.unit = numberProperty.unit;\r\n state.step = numberProperty.steps;\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : \"value\";\r\n break;\r\n }\r\n case \"string\": {\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : \"text\";\r\n break;\r\n }\r\n case \"boolean\": {\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : (property.writeable ? \"switch.enable\" : \"state\");\r\n break;\r\n }\r\n }\r\n return state;\r\n }\r\n\r\n private async createAndSetState(device: Device | Station, property: PropertyMetadataAny): Promise<void> {\r\n if (property.name !== PropertyName.Type && property.name !== PropertyName.DeviceStationSN) {\r\n const state = this.getStateCommon(property);\r\n const id: string = device.getStateID(convertCamelCaseToSnakeCase(property.name));\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n let changed = false;\r\n if (obj.native.name !== undefined && obj.native.name !== property.name) {\r\n obj.native.name = property.name;\r\n changed = true;\r\n }\r\n if (obj.native.key !== undefined && obj.native.key !== property.key) {\r\n obj.native.key = property.key;\r\n changed = true;\r\n }\r\n if (obj.native.commandId !== undefined && obj.native.commandId !== property.commandId) {\r\n obj.native.commandId = property.commandId;\r\n changed = true;\r\n }\r\n if (obj.common !== undefined && !util.isDeepStrictEqual(obj.common, state)) {\r\n changed = true;\r\n }\r\n if (changed) {\r\n const propertyMetadata = device.getPropertiesMetadata()[property.name];\r\n if (propertyMetadata !== undefined) {\r\n const newState = this.getStateCommon(propertyMetadata);\r\n obj.common = newState;\r\n }\r\n await this.setObjectAsync(id, obj);\r\n }\r\n } else {\r\n await this.setObjectNotExistsAsync(id, {\r\n type: \"state\",\r\n common: state,\r\n native: {\r\n key: property.key,\r\n commandId: property.commandId,\r\n name: property.name,\r\n },\r\n });\r\n }\r\n const value = device.getPropertyValue(property.name);\r\n if (value !== undefined)\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, id, (property.type === \"string\" || property.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n }\r\n }\r\n\r\n private async onDeviceAdded(device: Device): Promise<void> {\r\n this.logger.debug(`onDeviceAdded - device: ${device.getSerial()}`);\r\n\r\n await this.setObjectNotExistsAsync(device.getStateID(\"\", 0), {\r\n type: \"channel\",\r\n common: {\r\n name: device.getStateChannel()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(device.getStateID(\"\", 1), {\r\n type: \"device\",\r\n common: {\r\n name: device.getName()\r\n },\r\n native: {},\r\n });\r\n\r\n const metadata = device.getPropertiesMetadata();\r\n for(const property of Object.values(metadata)) {\r\n if (property.name !== PropertyName.DevicePicture)\r\n this.createAndSetState(device, property);\r\n }\r\n\r\n if (device.hasProperty(PropertyName.DevicePicture)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PICTURE_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Picture URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PICTURE_HTML), {\r\n type: \"state\",\r\n common: {\r\n name: \"Picture HTML image\",\r\n type: \"string\",\r\n role: \"html\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n if (device.hasCommand(CommandName.DeviceTriggerAlarmSound)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TRIGGER_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Trigger Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.RESET_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reset Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DevicePanAndTilt)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PAN_LEFT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Pan Left\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PAN_RIGHT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Pan Right\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.ROTATE_360), {\r\n type: \"state\",\r\n common: {\r\n name: \"Rotate 360\u00B0\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TILT_UP), {\r\n type: \"state\",\r\n common: {\r\n name: \"Tilt Up\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TILT_DOWN), {\r\n type: \"state\",\r\n common: {\r\n name: \"Tilt Down\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceLockCalibration)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.CALIBRATE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Calibrate Lock\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceUnlock)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.UNLOCK), {\r\n type: \"state\",\r\n common: {\r\n name: \"Unlock\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceSetDefaultAngle)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.SET_DEFAULT_ANGLE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Set Default Angle\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceSetPrivacyAngle)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.SET_PRIVACY_ANGLE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Set Default Angle\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceCalibrate)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.CALIBRATE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Calibrate\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceOpen)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.OPEN_BOX), {\r\n type: \"state\",\r\n common: {\r\n name: \"Open Box\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceStartLivestream)) {\r\n // Start Stream\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.START_STREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Start stream\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n\r\n // Stop Stream\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.STOP_STREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Stop stream\",\r\n type: \"boolean\",\r\n role: \"button.stop\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n\r\n // Livestream URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LIVESTREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Livestream URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n\r\n // Livestream RTSP URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP), {\r\n type: \"state\",\r\n common: {\r\n name: \"Livestream RTSP URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n if (device.hasProperty(PropertyName.DeviceRTSPStream)) {\r\n // RTSP Stream URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.RTSP_STREAM_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"RTSP stream URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n /*if (device.hasCommand(CommandName.DeviceStartDownload)) {\r\n // Last event video URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_VIDEO_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event video URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n\r\n // Last event picture URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_PIC_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event picture URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n\r\n // Last event picture HTML image\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_PIC_HTML), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event picture HTML image\",\r\n type: \"string\",\r\n role: \"html\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n }*/\r\n }\r\n\r\n private async onDeviceRemoved(device: Device): Promise<void> {\r\n this.delObjectAsync(device.getStateID(\"\", 0), { recursive: true }).catch((error) => {\r\n this.logger.error(`Error deleting states of removed device`, error);\r\n });\r\n removeFiles(this as unknown as ioBroker.Adapter, device.getStationSerial(), DataLocation.LAST_EVENT, device.getSerial()).catch((error) => {\r\n this.logger.error(`Error deleting fs contents of removed device`, error);\r\n });\r\n }\r\n\r\n private async onStationAdded(station: Station): Promise<void> {\r\n this.subscribeStates(`${station.getStateID(\"\", 0)}.*`);\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(\"\", 0), {\r\n type: \"device\",\r\n common: {\r\n name: station.getName()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(\"\", 1), {\r\n type: \"channel\",\r\n common: {\r\n name: station.getStateChannel()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: false, ack: true });\r\n\r\n const metadata = station.getPropertiesMetadata();\r\n for(const property of Object.values(metadata)) {\r\n this.createAndSetState(station, property);\r\n }\r\n\r\n // Reboot station\r\n if (station.hasCommand(CommandName.StationReboot)) {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.REBOOT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reboot station\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n // Alarm Sound\r\n if (station.hasCommand(CommandName.StationTriggerAlarmSound)) {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.TRIGGER_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Trigger Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.RESET_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reset Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n }\r\n\r\n private async onStationRemoved(station: Station): Promise<void> {\r\n this.delObjectAsync(station.getStateID(\"\", 0), { recursive: true }).catch((error) => {\r\n this.logger.error(`Error deleting states of removed station`, error);\r\n });\r\n this.delFileAsync(this.namespace, station.getSerial()).catch((error) => {\r\n this.logger.error(`Error deleting fs contents of removed station`, error);\r\n });\r\n }\r\n\r\n /*private async downloadEventVideo(device: Device, event_time: number, full_path: string | undefined, cipher_id: number | undefined): Promise<void> {\r\n this.logger.debug(`Device: ${device.getSerial()} full_path: ${full_path} cipher_id: ${cipher_id}`);\r\n try {\r\n if (!isEmpty(full_path) && cipher_id !== undefined) {\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n\r\n if (station !== undefined) {\r\n if (this.downloadEvent[device.getSerial()])\r\n clearTimeout(this.downloadEvent[device.getSerial()]);\r\n\r\n let videoLength = getVideoClipLength(device);\r\n const time_passed = (new Date().getTime() - new Date(event_time).getTime()) / 1000;\r\n\r\n if (time_passed >= videoLength)\r\n videoLength = 1;\r\n else\r\n videoLength = videoLength - time_passed;\r\n\r\n this.logger.info(`Downloading video event for device ${device.getSerial()} in ${videoLength} seconds...`);\r\n this.downloadEvent[device.getSerial()] = setTimeout(async () => {\r\n station.startDownload(device, full_path!, cipher_id);\r\n }, videoLength * 1000);\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`Device: ${device.getSerial()} - Error`, error);\r\n }\r\n }*/\r\n\r\n private async handlePushNotification(message: PushMessage): Promise<void> {\r\n try {\r\n if (message.device_sn !== undefined) {\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n /*const device: Device = await this.eufy.getDevice(message.device_sn);\r\n if ((message.push_count === 1 || message.push_count === undefined) && (message.file_path !== undefined && message.file_path !== \"\" && message.cipher !== undefined))\r\n if (this.config.autoDownloadVideo)\r\n await this.downloadEventVideo(device, message.event_time, message.file_path, message.cipher);*/\r\n }\r\n } catch (error) {\r\n if (error instanceof DeviceNotFoundError) {\r\n //Do nothing\r\n } else {\r\n this.logger.error(\"Handling push notification - Error\", error);\r\n }\r\n }\r\n }\r\n\r\n private async onConnect(): Promise<void> {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Global connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.connection\", { val: true, ack: true });\r\n\r\n const stations = await this.eufy.getStations();\r\n const stationSerials: string[] = [];\r\n for(const station of stations) {\r\n stationSerials.push(station.getSerial());\r\n }\r\n const devices = await this.eufy.getDevices();\r\n const deviceSerials: string[] = [];\r\n for(const device of devices) {\r\n deviceSerials.push(device.getSerial());\r\n }\r\n\r\n // Delete obsolete stations\r\n try {\r\n const allDevices = await this.getDevicesAsync();\r\n const reg = new RegExp(`^${this.namespace}\\.[0-9A-Z]+$`);\r\n for (const id of allDevices) {\r\n if (id._id.match(reg)) {\r\n const serial = id._id.replace(`${this.namespace}.`, \"\");\r\n if (!stationSerials.includes(serial)) {\r\n await this.delObjectAsync(id._id, { recursive: true });\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete stations ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete devices\r\n try {\r\n const allDevices = await this.getDevicesAsync();\r\n const reg = new RegExp(`^${this.namespace}\\.[0-9A-Z]+\\.[a-z]+\\.[0-9A-Z]+$`);\r\n for (const id of allDevices) {\r\n if (id._id.match(reg)) {\r\n const values = id._id.split(\".\");\r\n const stateChannel = values[3];\r\n const serial = values[4];\r\n if (!deviceSerials.includes(serial) ||\r\n (deviceSerials.includes(serial) && devices[deviceSerials.indexOf(serial)].getStateChannel() !== \"unknown\" && stateChannel === \"unknown\")) {\r\n await this.delObjectAsync(id._id, { recursive: true });\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete devices ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete properties\r\n try {\r\n const all = await this.getStatesAsync(\"*\");\r\n if (all) {\r\n Object.keys(all).forEach(async (stateid) => {\r\n const object = await this.getObjectAsync(stateid);\r\n if (object?.native?.name !== undefined) {\r\n const tmp = stateid.split(\".\");\r\n if (tmp.length >= 5) {\r\n const stationSerial = tmp[2];\r\n const deviceSerial = tmp[4];\r\n\r\n if (deviceSerial.match(/^[A-Z0-9]+/)) {\r\n // Device\r\n try {\r\n const device = await this.eufy.getDevice(deviceSerial);\r\n if (!device.hasProperty(object.native.name)) {\r\n this.delObjectAsync(stateid);\r\n }\r\n } catch (error) {\r\n if (error instanceof DeviceNotFoundError) {\r\n } else {\r\n this.log.error(`Delete obsolete properties ERROR - device - ${JSON.stringify(error)}`);\r\n }\r\n }\r\n } else {\r\n // Station\r\n try {\r\n const station = await this.eufy.getStation(stationSerial);\r\n if (!station.hasProperty(object.native.name)) {\r\n this.delObjectAsync(stateid);\r\n }\r\n } catch (error) {\r\n if (error instanceof StationNotFoundError) {\r\n } else {\r\n this.log.error(`Delete obsolete properties ERROR - station - ${JSON.stringify(error)}`);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n });\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete properties ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete directories/files\r\n try {\r\n const contents = await this.readDirAsync(this.namespace, \"\");\r\n for (const content of contents.filter((fn) => fn.file.match(\"^T[0-9A-Z]+$\") !== null && fn.isDir)) {\r\n if (!stationSerials.includes(content.file)) {\r\n await this.delFileAsync(this.namespace, content.file);\r\n } else {\r\n const dirContents = await this.readDirAsync(this.namespace, content.file);\r\n for (const dir of dirContents.filter((fn) => Object.values(DataLocation).includes(fn.file) && fn.isDir)) {\r\n const files = await this.readDirAsync(this.namespace, path.join(content.file, dir.file));\r\n let deletedFiles = 0;\r\n for (const file of files.filter((fn) => !deviceSerials.includes(fn.file.substring(0, 16)) && !fn.isDir)) {\r\n await this.delFileAsync(this.namespace, path.join(content.file, dir.file, file.file));\r\n deletedFiles++;\r\n }\r\n if (deletedFiles === files.length) {\r\n await this.delFileAsync(this.namespace, path.join(content.file, dir.file));\r\n }\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete directories/files ERROR - ${error}`);\r\n }\r\n }\r\n\r\n private async onClose(): Promise<void> {\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true }).catch();\r\n }\r\n\r\n public getPersistentData(): PersistentData {\r\n return this.persistentData;\r\n }\r\n\r\n private async onPushConnect(): Promise<void> {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: true, ack: true });\r\n }\r\n\r\n private async onPushClose(): Promise<void> {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: false, ack: true });\r\n }\r\n\r\n private async onMQTTConnect(): Promise<void> {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: true, ack: true });\r\n }\r\n\r\n private async onMQTTClose(): Promise<void> {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: false, ack: true });\r\n }\r\n\r\n private async onStationCommandResult(station: Station, result: CommandResult): Promise<void> {\r\n if ((result.return_code !== 0 && result.command_type !== CommandType.P2P_QUERY_STATUS_IN_LOCK && result.command_type !== CommandType.CMD_STORAGE_INFO_HB3) ||\r\n (result.return_code !== ErrorCode.ERROR_DEV_BUSY && result.command_type === CommandType.CMD_STORAGE_INFO_HB3)) {\r\n this.logger.error(`Station: ${station.getSerial()} command ${CommandType[result.command_type]} failed with error: ${ErrorCode[result.return_code]} (${result.return_code})`);\r\n }\r\n }\r\n\r\n private async onStationPropertyChanged(station: Station, name: string, value: PropertyValue): Promise<void> {\r\n const states = await this.getStatesAsync(`${station.getStateID(\"\", 1)}.*`);\r\n for (const state in states) {\r\n const obj = await this.getObjectAsync(state);\r\n if (obj) {\r\n if (obj.native.name !== undefined && obj.native.name === name) {\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, state, (obj.common.type === \"string\" || obj.common.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n return;\r\n }\r\n }\r\n }\r\n this.logger.debug(`onStationPropertyChanged(): Property \"${name}\" not implemented in this adapter (station: ${station.getSerial()} value: ${JSON.stringify(value)})`);\r\n }\r\n\r\n private async onDevicePropertyChanged(device: Device, name: string, value: PropertyValue): Promise<void> {\r\n const states = await this.getStatesAsync(`${device.getStateID(\"\", 1)}.*`);\r\n for (const state in states) {\r\n const obj = await this.getObjectAsync(state);\r\n if (obj) {\r\n if (obj.native.name !== undefined && obj.native.name === name) {\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, state, (obj.common.type === \"string\" || obj.common.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n switch(name) {\r\n case PropertyName.DeviceRTSPStream:\r\n if (value as boolean === false) {\r\n this.delStateAsync(device.getStateID(DeviceStateID.RTSP_STREAM_URL));\r\n }\r\n break;\r\n }\r\n return;\r\n }\r\n }\r\n }\r\n if (name === PropertyName.DevicePicture) {\r\n try {\r\n const picture = value as Picture;\r\n const fileName = `${device.getSerial()}.${picture.type.ext}`;\r\n const filePath = path.join(device.getStationSerial(), DataLocation.LAST_EVENT);\r\n if (!await this.fileExistsAsync(this.namespace, filePath)) {\r\n await this.mkdirAsync(this.namespace, filePath);\r\n }\r\n await this.writeFileAsync(this.namespace, path.join(filePath, fileName), picture.data);\r\n\r\n await this.setStateAsync(device.getStateID(DeviceStateID.PICTURE_URL), `/files/${this.namespace}/${device.getStationSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}.${picture.type.ext}`, true);\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, device.getStateID(DeviceStateID.PICTURE_HTML), getImageAsHTML(picture.data, picture.type.mime));\r\n } catch (err) {\r\n const error = ensureError(err);\r\n this.logger.error(\"onDevicePropertyChanged - Property picture - Error\", error);\r\n }\r\n } else {\r\n this.logger.debug(`onDevicePropertyChanged(): Property \"${name}\" not implemented in this adapter (device: ${device.getSerial()} value: ${JSON.stringify(value)})`);\r\n }\r\n }\r\n\r\n private async startLivestream(device_sn: string): Promise<void> {\r\n try {\r\n const device = await this.eufy.getDevice(device_sn);\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n\r\n if (station.isConnected() || station.isEnergySavingDevice()) {\r\n if (!station.isLiveStreaming(device)) {\r\n this.eufy.startStationLivestream(device_sn);\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be started, because it is already streaming!`);\r\n }\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be started, because there is no connection to station ${station.getSerial()}!`);\r\n }\r\n } catch (error) {\r\n this.logger.error(\"Start livestream - Error\", error);\r\n }\r\n }\r\n\r\n private async stopLivestream(device_sn: string): Promise<void> {\r\n try {\r\n const device = await this.eufy.getDevice(device_sn);\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n if (device.isCamera()) {\r\n const camera = device as Camera;\r\n if (await this.eufy.isStationConnected(device.getStationSerial()) && station.isLiveStreaming(camera)) {\r\n await this.eufy.stopStationLivestream(device_sn);\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be stopped, because it isn't streaming!`);\r\n }\r\n }\r\n\r\n } catch (error) {\r\n this.logger.error(\"Stop livestream - Error\", error);\r\n }\r\n }\r\n\r\n private async onStationLivestreamStart(station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable): Promise<void> {\r\n try {\r\n this.setStateAsync(device.getStateID(DeviceStateID.LIVESTREAM), { val: `${this.config.https ? \"https\" : \"http\"}://${this.config.hostname}:${this.config.go2rtc_api_port}/stream.html?src=${device.getSerial()}`, ack: true });\r\n this.setStateAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP), { val: `rtsp://${this.config.hostname}:${this.config.go2rtc_rtsp_port}/${device.getSerial()}`, ack: true });\r\n //await ffmpegStreamToGo2rtc(this.config, this.namespace, device.getSerial(), metadata, videostream, audiostream, this.logger);\r\n await streamToGo2rtc(device.getSerial(), videostream, audiostream, this.logger, this.config, this.namespace, metadata).catch((error) => {\r\n this.logger.debug(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Stopping livestream...`, error);\r\n });\r\n } catch(error) {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Stopping livestream...`, error);\r\n this.eufy.stopStationLivestream(device.getSerial())\r\n .catch(async (error) => {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error during stopping livestream...`, error);\r\n });\r\n }\r\n }\r\n\r\n private onStationLivestreamStop(_station: Station, device: Device): void {\r\n this.delStateAsync(device.getStateID(DeviceStateID.LIVESTREAM));\r\n this.delStateAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP));\r\n }\r\n\r\n /*private async onStationDownloadFinish(_station: Station, _device: Device): Promise<void> {\r\n //this.logger.trace(`Station: ${station.getSerial()} channel: ${channel}`);\r\n }*/\r\n\r\n /*private async onStationDownloadStart(station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable): Promise<void> {\r\n try {\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n await removeFiles(this, station.getSerial(), DataLocation.TEMP, device.getSerial()).catch();\r\n const file_path = getDataFilePath(this, station.getSerial(), DataLocation.TEMP, `${device.getSerial()}${STREAM_FILE_NAME_EXT}`);\r\n\r\n await ffmpegStreamToHls(this.config, this.namespace, metadata, videostream, audiostream, file_path, this.logger)\r\n .then(async () => {\r\n if (fse.pathExistsSync(file_path)) {\r\n await removeFiles(this, station.getSerial(), DataLocation.LAST_EVENT, device.getSerial());\r\n return true;\r\n }\r\n return false;\r\n })\r\n .then(async (result) => {\r\n if (result)\r\n await moveFiles(this, station.getSerial(), device.getSerial(), DataLocation.TEMP, DataLocation.LAST_EVENT);\r\n return result;\r\n })\r\n .then(async (result) => {\r\n if (result) {\r\n const filename_without_ext = getDataFilePath(this, station.getSerial(), DataLocation.LAST_EVENT, device.getSerial());\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_VIDEO_URL), \"Last captured video URL\", `/${this.namespace}/${station.getSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}${STREAM_FILE_NAME_EXT}`, \"url\");\r\n if (fse.pathExistsSync(`${filename_without_ext}${STREAM_FILE_NAME_EXT}`))\r\n await ffmpegPreviewImage(this.config, `${filename_without_ext}${STREAM_FILE_NAME_EXT}`, `${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`, this.logger)\r\n .then(() => {\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_PIC_URL), \"Last event picture URL\", `/${this.namespace}/${station.getSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}${IMAGE_FILE_JPEG_EXT}`, \"url\");\r\n try {\r\n if (fse.existsSync(`${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`)) {\r\n const image_data = getImageAsHTML(fse.readFileSync(`${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`));\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_PIC_HTML), \"Last event picture HTML image\", image_data, \"html\");\r\n }\r\n } catch (error) {\r\n this.logger.error(`Station: ${station.getSerial()} device: ${device.getSerial()} - Error`, error);\r\n }\r\n })\r\n .catch((error) => {\r\n this.logger.error(`ffmpegPreviewImage - station: ${station.getSerial()} device: ${device.getSerial()} - Error`, error);\r\n });\r\n }\r\n })\r\n .catch(async (error) => {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Cancelling download...`, error);\r\n await this.eufy.cancelStationDownload(device.getSerial());\r\n });\r\n } catch(error) {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Cancelling download...`, error);\r\n await this.eufy.cancelStationDownload(device.getSerial());\r\n }\r\n }*/\r\n\r\n private onStationRTSPUrl(station: Station, device: Device, value: string): void {\r\n setStateChangedAsync(this as unknown as ioBroker.Adapter, device.getStateID(DeviceStateID.RTSP_STREAM_URL), value);\r\n }\r\n\r\n private async onStationConnect(station: Station): Promise<void> {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: true, ack: true });\r\n }\r\n\r\n private async onStationClose(station: Station): Promise<void> {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: false, ack: true });\r\n }\r\n\r\n private onTFARequest(): void {\r\n this.logger.warn(`Two factor authentication request received, please enter valid verification code in state ${this.namespace}.verify_code`);\r\n this.verify_code= true;\r\n }\r\n\r\n private onCaptchaRequest(captchaId: string, captcha: string): void {\r\n this.captchaId = captchaId;\r\n this.logger.warn(`Captcha authentication request received, please enter valid captcha in state ${this.namespace}.captcha`);\r\n this.logger.warn(`Captcha: <img src=\"${captcha}\">`);\r\n this.setStateAsync(\"received_captcha_html\", { val: `<img src=\"${captcha}\">`, ack: true });\r\n }\r\n\r\n}\r\n\r\nif (require.main !== module) {\r\n // Export the constructor in compact mode\r\n module.exports = (options: Partial<utils.AdapterOptions> | undefined) => new euSec(options);\r\n} else {\r\n // otherwise start the instance directly\r\n (() => new euSec())();\r\n}"],
5
+ "mappings": "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",
6
6
  "names": ["getCountryCode", "isValidLanguageCode", "pathToGo2rtc", "pathToFfmpeg", "childProcess", "util", "error"]
7
7
  }
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "eusec",
4
- "version": "1.3.0",
4
+ "version": "1.3.1",
5
5
  "news": {
6
+ "1.3.1": {
7
+ "en": "Fixed issues #436, #439\n",
8
+ "uk": "Fixed issues #436, #439\n",
9
+ "de": "Behobene Probleme #436, #439\n",
10
+ "ru": "Исправлены проблемы #436, #439\n",
11
+ "pt": "Problemas corrigidos #436, #439\n",
12
+ "nl": "Problemen opgelost #436, #439\n",
13
+ "fr": "Correction des problèmes #436, #439\n",
14
+ "it": "Risolti i problemi #436, #439\n",
15
+ "es": "Solucionados los problemas #436, #439\n",
16
+ "pl": "Naprawiono błędy #436, #439\n",
17
+ "zh-cn": "修正問題 #436、#439\n"
18
+ },
6
19
  "1.3.0": {
7
20
  "en": "Requires ioBroker.js-controller version >= 6.0.0\nRequires ioBroker.admin version >= 7.0.12\nRequires node version >= 20\nAdded support for Floodlight Cam E340 (T8425; #428)\nAdded support for Solar Wall Light Cam S120 (T84A0; #406)\nAdded support for Indoor Cam S350 (T8416; #403)\nAdded support for eufyCam E330 (Professional; T8600; #391)\nAdded support for SoloCam S340 (T8170; #392, #399)\nImplemented sendTo functionality (#294)\nUpdated version of the package eufy-security-client (3.1.0)\nUpdated version of the package go2rtc-static (1.9.4)\nFixed issues #371, #376, #379, #380, #387, #420, #422, #432\n",
8
21
  "uk": "Requires ioBroker.js-controller version >= 6.0.0\nRequires ioBroker.admin version >= 7.0.12\nRequires node version >= 20\nAdded support for Floodlight Cam E340 (T8425; #428)\nAdded support for Solar Wall Light Cam S120 (T84A0; #406)\nAdded support for Indoor Cam S350 (T8416; #403)\nAdded support for eufyCam E330 (Professional; T8600; #391)\nAdded support for SoloCam S340 (T8170; #392, #399)\nImplemented sendTo functionality (#294)\nUpdated version of the package eufy-security-client (3.1.0)\nUpdated version of the package go2rtc-static (1.9.4)\nFixed issues #371, #376, #379, #380, #387, #420, #422, #432\n",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.eusec",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "ioBroker adapter that integrates Eufy-Security cameras with stations",
5
5
  "author": {
6
6
  "name": "bropat",
@@ -57,7 +57,7 @@
57
57
  "@tsconfig/node20": "^20.1.4",
58
58
  "chai": "^5.1.1",
59
59
  "chai-as-promised": "^8.0.0",
60
- "eslint": "^9.9.1",
60
+ "eslint": "^8.57.0",
61
61
  "mocha": "^10.7.3",
62
62
  "proxyquire": "^2.1.3",
63
63
  "rimraf": "^6.0.1",