UNPKG

@iotize/ionic

Version:

Iotize specific building blocks on top of @ionic/angular.

598 lines 69.6 kB
import { Validators } from '@angular/forms'; import { bufferToHexString, hexStringToBuffer, } from '@iotize/common/byte-converter'; import { FACTORY_RESET_MODE_VERSION, TapInfo, TAP_MANAGER_APP_ID, } from '@iotize/ionic'; import { HostProtocol, SpecialFeature, TapResponse, TargetProtocol, } from '@iotize/tap'; import { converters } from '@iotize/tap/service/core'; import { NfcConnectionPriority, NfcPairingMode, } from '@iotize/tap/service/impl/interface'; import { WifiKeyVisibility, WifiMode, WifiSSIDVisibility, } from '@iotize/tap/service/impl/wifi'; import { combineLatest } from 'rxjs'; import { map } from 'rxjs/operators'; import { enumToOptions } from './utility'; const TAP_CONFIG_PATTERN = /^([0-9]+)\.([0-9]+)\.([0-9]+)$/; const IPV4_PATTERN = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/; const IPV4_MASK_PATTERN = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/; const SSID_PATTERN = /^[^ !#;+\]\/"\t][^+\]\/"\t]{0,30}[^ !#;+\]\/"\t]$|^[^ !#;+\]\/"\t]$/; function regexValidator(pattern, message) { return (control) => { const value = control.value; const valueMatchPattern = pattern.test(value); return !valueMatchPattern ? { invalidFormat: { value: control.value, message } } : null; }; } const validateTapVersion = regexValidator(TAP_CONFIG_PATTERN, `Must be a valid semantic version (Major.Minor.Patch).`); function enumFormatter(data) { return (value) => { if (Array.isArray(value)) { if (value.length === 0) { return '-'; } return value.map((key) => HostProtocol[key]).join(', '); } else { return data[value]; } }; } export function isTapConfigured(version) { return !(version.major === 0 && version.minor === 0 && version.patch === 0); } function stringToEnumArray(v, mapping) { return v .split(',') .map((item) => item.trim()) .map((item) => { if (!(item in mapping)) { throw new Error(`Invalid value "${item}". Must one of the following: ${Object.keys(mapping).join(', ')}`); } return mapping[item]; }); } var WifiTxPowerEnum; (function (WifiTxPowerEnum) { WifiTxPowerEnum[WifiTxPowerEnum["default"] = 0] = "default"; WifiTxPowerEnum[WifiTxPowerEnum["10 dBm"] = 40] = "10 dBm"; WifiTxPowerEnum[WifiTxPowerEnum["12.5 dBm"] = 50] = "12.5 dBm"; WifiTxPowerEnum[WifiTxPowerEnum["15 dBm"] = 60] = "15 dBm"; WifiTxPowerEnum[WifiTxPowerEnum["17.5 dBm"] = 70] = "17.5 dBm"; WifiTxPowerEnum[WifiTxPowerEnum["20 dBm"] = 80] = "20 dBm"; })(WifiTxPowerEnum || (WifiTxPowerEnum = {})); const IPV4_VALIDATOR = regexValidator(IPV4_PATTERN, `Not a valid IPv4 address (eg 192.168.20.1)`); export const defaultInfoResolverConfig = [ { key: TapInfo.HostProtocol, input: createEnumField('HostProtocol', HostProtocol), viewFormatter: enumFormatter(HostProtocol), }, { key: TapInfo.configVersion, input: { formValidators: [validateTapVersion], }, viewFormatter: (v) => { if (v === FACTORY_RESET_MODE_VERSION) { return 'FACTORY RESET'; } else if (v === '255.255.65535') { return 'CONFIGURATION MODE'; } else if (v) { return `v${v}`; } else { return 'UNKNOWN'; } }, editFormatter: { read: (input) => { return input; }, write: (v) => { return v || FACTORY_RESET_MODE_VERSION; }, }, }, { key: TapInfo.CloudEndpoint, getValue: async (tap) => { const hostname = (await tap.service.mqtt.getBrokerHostname()).body(); const port = (await tap.service.mqtt.getBrokerPort()).body(); return `${hostname}:${port}`; }, putValue: async (tap, value) => { const [hostname, port] = value.split(':'); const setPort = await tap.service.mqtt.putBrokerPort(port || '1883'); setPort.successful(); return tap.service.mqtt.putBrokerHostname(hostname); }, }, { key: TapInfo.TargetProtocolConfiguration, viewFormatter: (v) => `${bufferToHexString(v)}`, editFormatter: { read: (input) => { return input ? hexStringToBuffer(input) : new Uint8Array(); }, write: (v) => { return v ? bufferToHexString(v) : ''; }, }, getValue: async (tap) => { const result = await tap.service.target.getModbusTcpConfiguration(); result.successful(); return result.rawBody(); }, putValue: async (tap, value) => { return await tap.lwm2m.put('/1027//21', value); }, }, { input: { type: 'toggle', }, key: TapInfo.NFCConnectionPriority, getValue: async (tap) => { const value = (await tap.service.interface.getNfcConnectionPriority()).body(); return value === NfcConnectionPriority.NFC_PRIORITY; }, putValue: (tap, val) => { const mode = val ? NfcConnectionPriority.NFC_NON_PRIORITY : NfcConnectionPriority.NFC_PRIORITY; return tap.service.interface.putNfcConnectionPriority(mode); }, }, { key: TapInfo.NFCPairingMode, input: createEnumField('NfcPairingMode', NfcPairingMode), }, { key: TapInfo.DataLogMaxPacketCount, viewFormatter: (v) => { return v === 0 ? 'NO LIMIT' : v.toString(); }, input: { type: 'number', }, }, { key: TapInfo.IsTargetConnected, // viewFormatter: (v: boolean) => v ? 'YES' : 'NO', getValue: (tap) => tap.service.target.isConnected(), putValue: (tap, enabled) => { if (enabled) { return tap.service.target.connect(); } else { return tap.service.target.disconnect(); } }, input: { type: 'toggle', }, }, { key: TapInfo.universalLink, icon: 'link', }, { key: TapInfo.androidApplicationRecord, // TODO replace with getAndroidApplicationId() getValue: async (tap) => { const appPath = (await tap.service.interface.getAppPath()).body(); if (appPath.startsWith('$4/')) { return appPath.substring(3); } else { return TAP_MANAGER_APP_ID; } }, viewFormatter: (input) => { if (input === TAP_MANAGER_APP_ID) { return `${input} (Tap Manager)`; } return input; }, putValue: async (tap, value) => { return tap.service.interface.putAppPath(`$4/${value}`); }, }, { key: TapInfo.useEncryption, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return lockOptions.scramActivated; }, }, { key: TapInfo.lockFactoryReset, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return !lockOptions.disableHardwareFactoryReset; }, }, { key: TapInfo.InterfaceSecurityScramActivated, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return lockOptions.scramActivated; }, }, { key: TapInfo.InterfaceSecurityDisableHardwareFactoryReset, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return lockOptions.disableHardwareFactoryReset; }, }, { key: TapInfo.InterfaceSecurityDisabledResourceFactoryReset, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return lockOptions.disableResourceFactoryReset; }, }, { key: TapInfo.InterfaceSecurityDisabledLoginWithUID, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return lockOptions.disableLoginWithUID; }, }, { key: TapInfo.hashPassword, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return lockOptions.hashPassword; }, }, { key: TapInfo.isLoginWithUIDEnabled, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return !lockOptions.disableLoginWithUID; }, }, { key: TapInfo.isLWM2MFactoryResetEnabled, input: { type: 'toggle', }, editable: false, getValue: async (tap) => { const lockOptions = (await tap.service.interface.getSecurityOptions()).body(); return !lockOptions.disableResourceFactoryReset; }, }, { key: TapInfo.appPath, putValue: (tap, value) => { return tap.service.interface.putAppPath(value); }, getValue: (tap) => tap.service.interface.getAppPathResolved(), }, { key: TapInfo.TargetProtocol, getValue: (tap) => { return tap.service.target.getProtocol(); }, putValue: (tap, protocol) => { return tap.service.target.putProtocol(protocol); }, setValue: (tap, protocol) => { return tap.service.target.setProtocol(protocol); }, viewFormatter: enumFormatter(TargetProtocol), input: { type: 'select', options: enumToOptions(TargetProtocol).filter((f) => { return f.key !== TargetProtocol.JTAG; }), }, }, { key: '/interface/available-host-protocols', viewFormatter: enumFormatter(HostProtocol), editFormatter: { write: (v) => { // console.log('Host protocols: ', v); if (!v || v.length === 0) { return 'NONE'; } return v.map((key) => HostProtocol[key]).join(', '); }, read: (v) => { return stringToEnumArray(v, HostProtocol); }, }, }, { key: TapInfo.authorizedHostProtocols, input: { type: 'select', multiple: true, options: [], }, viewFormatter: enumFormatter(HostProtocol), init: async (_service, config, infoResolver) => { const hostProtocols = await infoResolver.getValue(TapInfo.availableHostProtocols); if (config.input !== undefined) { config.input.options = hostProtocols.map((key) => { return { key: key, text: HostProtocol[key] }; }); } }, }, { key: TapInfo.AdpVersion, getValue: (tap) => tap.service.tapnpass.getStatus(), viewFormatter: (stats) => { const v = stats.header.version; return `${v.major}.${v.minor}.${v.patch}`; }, }, { key: TapInfo.WifiHostname, viewFormatter: (v) => { if (v === '0.0.0.0') { return 'NO IP'; } return v; }, }, { key: TapInfo.WifiSSID, input: { formValidators: [ regexValidator(SSID_PATTERN, `This is not a valid SSID. It can be any alphanumeric, case-sensitive entry from 1 to 32 characters. Trailing or leading spaces are not allowed.`), ], }, }, { key: TapInfo.WifiSSIDVisibility, input: createEnumField('WifiSSIDVisibility', WifiSSIDVisibility), viewFormatter: enumFormatter(WifiSSIDVisibility), }, { key: TapInfo.WifiKeyVisibility, input: createEnumField('WifiKeyVisibility', WifiKeyVisibility), viewFormatter: enumFormatter(WifiKeyVisibility), }, { key: TapInfo.WifiTxPower, viewFormatter: enumFormatter(WifiTxPowerEnum), input: createEnumField('WifiTxPowerEnum', WifiTxPowerEnum), }, { key: TapInfo.NetworkInfraIp, input: { formValidators: [IPV4_VALIDATOR], }, viewFormatter: (value) => { if (value === '0.0.0.0') { return 'Dynamic (DHCP)'; } return value; }, }, { key: TapInfo.NetworkIpMask, input: { formValidators: [ regexValidator(IPV4_MASK_PATTERN, `Not a valid IPv4 mask (eg 192.168.20.1)`), ], }, isDisplayed: ({ tapConfigItemStateService }) => { return combineLatest([ tapConfigItemStateService.valueChange(TapInfo.WifiMode), tapConfigItemStateService.valueChange(TapInfo.NetworkInfraIp), ]).pipe(map(([mode, ip]) => { return mode === WifiMode.NETWORK && ip !== '0.0.0.0'; })); }, }, { key: TapInfo.NetworkGatewayIp, input: { formValidators: [IPV4_VALIDATOR], }, isDisplayed: ({ tapConfigItemStateService }) => { return combineLatest([ tapConfigItemStateService.valueChange(TapInfo.WifiMode), tapConfigItemStateService.valueChange(TapInfo.NetworkInfraIp), ]).pipe(map(([mode, ip]) => { return mode === WifiMode.NETWORK && ip !== '0.0.0.0'; })); }, }, { key: TapInfo.NetworkDNSIp, input: { formValidators: [IPV4_VALIDATOR], }, isDisplayed: ({ tapConfigItemStateService }) => { return combineLatest([ tapConfigItemStateService.valueChange(TapInfo.WifiMode), tapConfigItemStateService.valueChange(TapInfo.NetworkInfraIp), ]).pipe(map(([mode, ip]) => { return mode === WifiMode.NETWORK && ip !== '0.0.0.0'; })); }, }, { key: TapInfo.WifiMode, input: createEnumField('WifiMode', WifiMode), }, { key: TapInfo.isHostProtocolAuthorized, input: { type: 'toggle', }, getValue: async (tap, protocol) => { if (protocol === undefined) { throw new Error('Illegal argument error: missing protocol'); } const protocols = (await tap.service.interface.getAuthorizedHostProtocol()).body(); return protocols.find((p) => p === protocol) !== undefined; }, putValue: async (tap, value, protocol) => { const protocols = (await tap.service.interface.getAuthorizedHostProtocol()).body(); if (protocol === undefined) { throw new Error('Illegal argument error: missing protocol'); } const indexOfProtocol = protocols.findIndex((p) => p === protocol); if (value) { if (indexOfProtocol === -1) { protocols.push(protocol); } } else { if (indexOfProtocol >= 0) { protocols.splice(indexOfProtocol, 1); } } return tap.service.interface.putAuthorizedHostProtocol(protocols); }, }, { key: TapInfo.WifiKey, input: { type: 'password', formValidators: [Validators.minLength(8), Validators.maxLength(128)], }, }, { key: TapInfo.variableMetaData, input: {}, getValue: async (tap, variableId) => { const metaData = (await tap.service.variable.getRawMeta(variableId)).body(); return converters.ascii.decode(metaData); }, putValue: (tap, value, bundleId) => { const data = converters.ascii.encode(value); return tap.service.variable.putRawMeta(bundleId, data); }, }, { key: TapInfo.profilePassword, input: { type: 'password', formValidators: [Validators.minLength(1), Validators.maxLength(16)], }, viewFormatter: () => { return '********'; }, putValue: async (tap, value, profileId) => { await tap.auth.changePassword(value, profileId); return TapResponse.SUCCESS(); }, }, { key: TapInfo.DeviceMemoryFree, viewFormatter(value) { return Math.floor((value / 1024) * 100) / 100 + ' KB'; }, }, { key: TapInfo.TimeLocalTime, viewFormatter(localTime) { if (!localTime) { return ''; } const date = new Date(Date.UTC(localTime.year, 0, localTime.dayOfYear)); date.setHours(localTime.hours); date.setMinutes(localTime.minutes); date.setSeconds(localTime.seconds); // {"seconds":54,"minutes":3,"hours":8,"dayOfMonth":8,"month":8,"year":122,"dayOfWeek":4,"dayOfYear":250,"isdst":0} return `${date.toUTCString()}`; }, }, { key: TapInfo.InterfaceSpecialFeatureSWDDirect, ...createSpecialFeatureDAO(SpecialFeature.SWD_DIRECT_ACCESS), }, { key: TapInfo.InterfaceSpecialFeatureSerial, ...createSpecialFeatureDAO(SpecialFeature.SERIAL_ACCESS), }, { key: TapInfo.InterfaceSpecialFeatureModbusDirect, ...createSpecialFeatureDAO(SpecialFeature.MODBUS_DIRECT_ACCESS), }, { key: '/wifi/enabled', input: { type: 'toggle', }, getValue: async (tap) => { const response = await tap.service.wifi.getDisabled(); return !response.body(); }, putValue: (tap, enabled) => { return tap.service.wifi.putDisabled(!enabled); }, }, ]; function createSpecialFeatureDAO(feature) { return { input: { type: 'number', formValidators: [Validators.min(0), Validators.max(65535)], }, getValue: async (tap) => { const result = (await tap.service.interface.getSpecialFeatureProfile(feature)).body(); if (result === 65535 - (feature - 100)) { return 'UNAUTHORIZED'; } else { return result; } }, putValue: async (tap, body) => { return await tap.service.interface.putSpecialFeatureProfile(feature, body); }, }; } function createEnumField(enumId, enumData) { return { type: 'select', enum: { id: enumId, data: enumData, }, }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW90aXplLWlvbmljL2NvbmZpZy9zcmMvbGliL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWdDLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzFFLE9BQU8sRUFDTCxpQkFBaUIsRUFDakIsaUJBQWlCLEdBQ2xCLE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUNMLDBCQUEwQixFQUUxQixPQUFPLEVBQ1Asa0JBQWtCLEdBQ25CLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFDTCxZQUFZLEVBQ1osY0FBYyxFQUVkLFdBQVcsRUFFWCxjQUFjLEdBQ2YsTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sRUFDTCxxQkFBcUIsRUFDckIsY0FBYyxHQUNmLE1BQU0sb0NBQW9DLENBQUM7QUFFNUMsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixRQUFRLEVBQ1Isa0JBQWtCLEdBQ25CLE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNyQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFckMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUUxQyxNQUFNLGtCQUFrQixHQUFHLGdDQUFnQyxDQUFDO0FBQzVELE1BQU0sWUFBWSxHQUFHLGlDQUFpQyxDQUFDO0FBQ3ZELE1BQU0saUJBQWlCLEdBQUcsaUNBQWlDLENBQUM7QUFDNUQsTUFBTSxZQUFZLEdBQ2hCLHFFQUFxRSxDQUFDO0FBRXhFLFNBQVMsY0FBYyxDQUFDLE9BQWUsRUFBRSxPQUFlO0lBQ3RELE9BQU8sQ0FBQyxPQUF3QixFQUFpQyxFQUFFO1FBQ2pFLE1BQU0s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QUFLLEVBQUUsR0FBUSxFQUFFLElBQVksRUFBRSxFQUFFO1lBQ3pDLE9BQU8sTUFBTSxHQUFHLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyx3QkFBd0IsQ0FDekQsT0FBTyxFQUNQLElBQUksQ0FDTCxDQUFDO1FBQ0osQ0FBQztLQUNGLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxlQUFlLENBQ3RCLE1BQWMsRUFDZCxRQUFtQjtJQUVuQixPQUFPO1FBQ0wsSUFBSSxFQUFFLFFBQVE7UUFDZCxJQUFJLEVBQUU7WUFDSixFQUFFLEVBQUUsTUFBTTtZQUNWLElBQUksRUFBRSxRQUFRO1NBQ2Y7S0FDRixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgVmFsaWRhdG9yRm4sIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge1xuICBidWZmZXJUb0hleFN0cmluZyxcbiAgaGV4U3RyaW5nVG9CdWZmZXIsXG59IGZyb20gJ0Bpb3RpemUvY29tbW9uL2J5dGUtY29udmVydGVyJztcbmltcG9ydCB7XG4gIEZBQ1RPUllfUkVTRVRfTU9ERV9WRVJTSU9OLFxuICBMd20ybUVudW0sXG4gIFRhcEluZm8sXG4gIFRBUF9NQU5BR0VSX0FQUF9JRCxcbn0gZnJvbSAnQGlvdGl6ZS9pb25pYyc7XG5pbXBvcnQge1xuICBIb3N0UHJvdG9jb2wsXG4gIFNwZWNpYWxGZWF0dXJlLFxuICBUYXAsXG4gIFRhcFJlc3BvbnNlLFxuICBUYXBWZXJzaW9uLFxuICBUYXJnZXRQcm90b2NvbCxcbn0gZnJvbSAnQGlvdGl6ZS90YXAnO1xuaW1wb3J0IHsgY29udmVydGVycyB9IGZyb20gJ0Bpb3RpemUvdGFwL3NlcnZpY2UvY29yZSc7XG5pbXBvcnQge1xuICBOZmNDb25uZWN0aW9uUHJpb3JpdHksXG4gIE5mY1BhaXJpbmdNb2RlLFxufSBmcm9tICdAaW90aXplL3RhcC9zZXJ2aWNlL2ltcGwvaW50ZXJmYWNlJztcbmltcG9ydCB7IEFkcFN0YXRzIH0gZnJvbSAnQGlvdGl6ZS90YXAvc2VydmljZS9pbXBsL3RhcG5wYXNzJztcbmltcG9ydCB7XG4gIFdpZmlLZXlWaXNpYmlsaXR5LFxuICBXaWZpTW9kZSxcbiAgV2lmaVNTSURWaXNpYmlsaXR5LFxufSBmcm9tICdAaW90aXplL3RhcC9zZXJ2aWNlL2ltcGwvd2lmaSc7XG5pbXBvcnQgeyBjb21iaW5lTGF0ZXN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUYXBDb25maWdJdGVtRXh0ZW5kZWQgfSBmcm9tICcuL3RhcC1jb25maWctaXRlbS90YXAtY29uZmlnLWl0ZW0uZGVmaW5pdGlvbic7XG5pbXBvcnQgeyBlbnVtVG9PcHRpb25zIH0gZnJvbSAnLi91dGlsaXR5JztcblxuY29uc3QgVEFQX0NPTkZJR19QQVRURVJOID0gL14oWzAtOV0rKVxcLihbMC05XSspXFwuKFswLTldKykkLztcbmNvbnN0IElQVjRfUEFUVEVSTiA9IC9eKD86WzAtOV17MSwzfVxcLil7M31bMC05XXsxLDN9JC87XG5jb25zdCBJUFY0X01BU0tfUEFUVEVSTiA9IC9eKD86WzAtOV17MSwzfVxcLil7M31bMC05XXsxLDN9JC87XG5jb25zdCBTU0lEX1BBVFRFUk4gPVxuICAvXlteICEjOytcXF1cXC9cIlxcdF1bXitcXF1cXC9cIlxcdF17MCwzMH1bXiAhIzsrXFxdXFwvXCJcXHRdJHxeW14gISM7K1xcXVxcL1wiXFx0XSQvO1xuXG5mdW5jdGlvbiByZWdleFZhbGlkYXRvcihwYXR0ZXJuOiBSZWdFeHAsIG1lc3NhZ2U6IHN0cmluZyk6IFZhbGlkYXRvckZuIHtcbiAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9IHwgbnVsbCA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBjb250cm9sLnZhbHVlO1xuICAgIGNvbnN0IHZhbHVlTWF0Y2hQYXR0ZXJuID0gcGF0dGVybi50ZXN0KHZhbHVlKTtcbiAgICByZXR1cm4gIXZhbHVlTWF0Y2hQYXR0ZXJuXG4gICAgICA/IHsgaW52YWxpZEZvcm1hdDogeyB2YWx1ZTogY29udHJvbC52YWx1ZSwgbWVzc2FnZSB9IH1cbiAgICAgIDogbnVsbDtcbiAgfTtcbn1cblxuY29uc3QgdmFsaWRhdGVUYXBWZXJzaW9uOiBWYWxpZGF0b3JGbiA9IHJlZ2V4VmFsaWRhdG9yKFxuICBUQVBfQ09ORklHX1BBVFRFUk4sXG4gIGBNdXN0IGJlIGEgdmFsaWQgc2VtYW50aWMgdmVyc2lvbiAoTWFqb3IuTWlub3IuUGF0Y2gpLmBcbik7XG5cbmZ1bmN0aW9uIGVudW1Gb3JtYXR0ZXIoZGF0YTogYW55KTogKHZhbHVlOiBhbnkpID0+IHN0cmluZyB7XG4gIHJldHVybiAodmFsdWU6IGFueSkgPT4ge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgaWYgKHZhbHVlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gJy0nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlLm1hcCgoa2V5KSA9PiBIb3N0UHJvdG9jb2xba2V5XSkuam9pbignLCAnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGRhdGFbdmFsdWVdIGFzIHN0cmluZztcbiAgICB9XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1RhcENvbmZpZ3VyZWQodmVyc2lvbjogVGFwVmVyc2lvbikge1xuICByZXR1cm4gISh2ZXJzaW9uLm1ham9yID09PSAwICYmIHZlcnNpb24ubWlub3IgPT09IDAgJiYgdmVyc2lvbi5wYXRjaCA9PT0gMCk7XG59XG5cbmZ1bmN0aW9uIHN0cmluZ1RvRW51bUFycmF5PFQ+KHY6IHN0cmluZywgbWFwcGluZzogYW55KTogVFtdIHtcbiAgcmV0dXJuIHZcbiAgICAuc3BsaXQoJywnKVxuICAgIC5tYXAoKGl0ZW0pID0+IGl0ZW0udHJpbSgpKVxuICAgIC5tYXAoKGl0ZW0pID0+IHtcbiAgICAgIGlmICghKGl0ZW0gaW4gbWFwcGluZykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBJbnZhbGlkIHZhbHVlIFwiJHtpdGVtfVwiLiBNdXN0IG9uZSBvZiB0aGUgZm9sbG93aW5nOiAke09iamVjdC5rZXlzKFxuICAgICAgICAgICAgbWFwcGluZ1xuICAgICAgICAgICkuam9pbignLCAnKX1gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWFwcGluZ1tpdGVtIGFzIGFueV0gYXMgdW5rbm93biBhcyBUO1xuICAgIH0pO1xufVxuXG5lbnVtIFdpZmlUeFBvd2VyRW51bSB7XG4gICdkZWZhdWx0JyA9IDAsXG4gICcxMCBkQm0nID0gNDAsXG4gICcxMi41IGRCbScgPSA1MCxcbiAgJzE1IGRCbScgPSA2MCxcbiAgJzE3LjUgZEJtJyA9IDcwLFxuICAnMjAgZEJtJyA9IDgwLFxufVxuXG5jb25zdCBJUFY0X1ZBTElEQVRPUiA9IHJlZ2V4VmFsaWRhdG9yKFxuICBJUFY0X1BBVFRFUk4sXG4gIGBOb3QgYSB2YWxpZCBJUHY0IGFkZHJlc3MgKGVnIDE5Mi4xNjguMjAuMSlgXG4pO1xuXG5leHBvcnQgY29uc3QgZGVmYXVsdEluZm9SZXNvbHZlckNvbmZpZzogVGFwQ29uZmlnSXRlbUV4dGVuZGVkW10gPSBbXG4gIHtcbiAgICBrZXk6IFRhcEluZm8uSG9zdFByb3RvY29sLFxuICAgIGlucHV0OiBjcmVhdGVFbnVtRmllbGQoJ0hvc3RQcm90b2NvbCcsIEhvc3RQcm90b2NvbCksXG4gICAgdmlld0Zvcm1hdHRlcjogZW51bUZvcm1hdHRlcihIb3N0UHJvdG9jb2wpLFxuICB9LFxuICB7XG4gICAga2V5OiBUYXBJbmZvLmNvbmZpZ1ZlcnNpb24sXG4gICAgaW5wdXQ6IHtcbiAgICAgIGZvcm1WYWxpZGF0b3JzOiBbdmFsaWRhdGVUYXBWZXJzaW9uXSxcbiAgICB9LFxuICAgIHZpZXdGb3JtYXR0ZXI6ICh2OiBzdHJpbmcpID0+IHtcbiAgICAgIGlmICh2ID09PSBGQUNUT1JZX1JFU0VUX01PREVfVkVSU0lPTikge1xuICAgICAgICByZXR1cm4gJ0ZBQ1RPUlkgUkVTRVQnO1xuICAgICAgfSBlbHNlIGlmICh2ID09PSAnMjU1LjI1NS42NTUzNScpIHtcbiAgICAgICAgcmV0dXJuICdDT05GSUdVUkFUSU9OIE1PREUnO1xuICAgICAgfSBlbHNlIGlmICh2KSB7XG4gICAgICAgIHJldHVybiBgdiR7dn1gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuICdVTktOT1dOJztcbiAgICAgIH1cbiAgICB9LFxuICAgIGVkaXRGb3JtYXR0ZXI6IHtcbiAgICAgIHJlYWQ6IChpbnB1dDogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgICAgfSxcbiAgICAgIHdyaXRlOiAodjogc3RyaW5nIHwgdW5kZWZpbmVkKSA9PiB7XG4gICAgICAgIHJldHVybiB2IHx8IEZBQ1RPUllfUkVTRVRfTU9ERV9WRVJTSU9OO1xuICAgICAgfSxcbiAgICB9LFxuICB9LFxuICB7XG4gICAga2V5OiBUYXBJbmZvLkNsb3VkRW5kcG9pbnQsXG4gICAgZ2V0VmFsdWU6IGFzeW5jICh0YXApID0+IHtcbiAgICAgIGNvbnN0IGhvc3RuYW1lID0gKGF3YWl0IHRhcC5zZXJ2aWNlLm1xdHQuZ2V0QnJva2VySG9zdG5hbWUoKSkuYm9keSgpO1xuICAgICAgY29uc3QgcG9ydCA9IChhd2FpdCB0YXAuc2VydmljZS5tcXR0LmdldEJyb2tlclBvcnQoKSkuYm9keSgpO1xuICAgICAgcmV0dXJuIGAke2hvc3RuYW1lfToke3BvcnR9YDtcbiAgICB9LFxuICAgIHB1dFZhbHVlOiBhc3luYyAodGFwOiBUYXAsIHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IFtob3N0bmFtZSwgcG9ydF0gPSB2YWx1ZS5zcGxpdCgnOicpO1xuICAgICAgY29uc3Qgc2V0UG9ydCA9IGF3YWl0IHRhcC5zZXJ2aWNlLm1xdHQucHV0QnJva2VyUG9ydChwb3J0IHx8ICcxODgzJyk7XG4gICAgICBzZXRQb3J0LnN1Y2Nlc3NmdWwoKTtcbiAgICAgIHJldHVybiB0YXAuc2VydmljZS5tcXR0LnB1dEJyb2tlckhvc3RuYW1lKGhvc3RuYW1lKTtcbiAgICB9LFxuICB9LFxuICB7XG4gICAga2V5OiBUYXBJbmZvLlRhcmdldFByb3RvY29sQ29uZmlndXJhdGlvbixcbiAgICB2aWV3Rm9ybWF0dGVyOiAodjogVWludDhBcnJheSkgPT4gYCR7YnVmZmVyVG9IZXhTdHJpbmcodil9YCxcbiAgICBlZGl0Rm9ybWF0dGVyOiB7XG4gICAgICByZWFkOiAoaW5wdXQ6IHN0cmluZyk6IFVpbnQ4QXJyYXkgPT4ge1xuICAgICAgICByZXR1cm4gaW5wdXQgPyBoZXhTdHJpbmdUb0J1ZmZlcihpbnB1dCkgOiBuZXcgVWludDhBcnJheSgpO1xuICAgICAgfSxcbiAgICAgIHdyaXRlOiAodjogVWludDhBcnJheSB8IHVuZGVmaW5lZCkgPT4ge1xuICAgICAgICByZXR1cm4gdiA/IGJ1ZmZlclRvSGV4U3RyaW5nKHYpIDo