appium-android-driver 5.7.2 → 5.7.3

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.
Files changed (55) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/build/index.js +1 -2
  3. package/build/lib/android-helpers.js +2 -26
  4. package/build/lib/android-helpers.js.map +1 -1
  5. package/build/lib/bootstrap.js +1 -8
  6. package/build/lib/bootstrap.js.map +1 -1
  7. package/build/lib/commands/actions.js +1 -2
  8. package/build/lib/commands/actions.js.map +1 -1
  9. package/build/lib/commands/alert.js +1 -2
  10. package/build/lib/commands/alert.js.map +1 -1
  11. package/build/lib/commands/app-management.js +2 -16
  12. package/build/lib/commands/app-management.js.map +1 -1
  13. package/build/lib/commands/context.js +1 -15
  14. package/build/lib/commands/context.js.map +1 -1
  15. package/build/lib/commands/element.js +1 -4
  16. package/build/lib/commands/element.js.map +1 -1
  17. package/build/lib/commands/emu-console.js +1 -3
  18. package/build/lib/commands/emu-console.js.map +1 -1
  19. package/build/lib/commands/file-actions.js +1 -13
  20. package/build/lib/commands/file-actions.js.map +1 -1
  21. package/build/lib/commands/find.js +1 -5
  22. package/build/lib/commands/find.js.map +1 -1
  23. package/build/lib/commands/general.js +1 -14
  24. package/build/lib/commands/general.js.map +1 -1
  25. package/build/lib/commands/index.js +2 -3
  26. package/build/lib/commands/index.js.map +1 -1
  27. package/build/lib/commands/intent.js +1 -5
  28. package/build/lib/commands/intent.js.map +1 -1
  29. package/build/lib/commands/log.js +1 -4
  30. package/build/lib/commands/log.js.map +1 -1
  31. package/build/lib/commands/media-projection.js +1 -5
  32. package/build/lib/commands/media-projection.js.map +1 -1
  33. package/build/lib/commands/network.js +1 -7
  34. package/build/lib/commands/network.js.map +1 -1
  35. package/build/lib/commands/performance.js +1 -8
  36. package/build/lib/commands/performance.js.map +1 -1
  37. package/build/lib/commands/recordscreen.js +1 -3
  38. package/build/lib/commands/recordscreen.js.map +1 -1
  39. package/build/lib/commands/streamscreen.js +4 -9
  40. package/build/lib/commands/streamscreen.js.map +1 -1
  41. package/build/lib/commands/system-bars.js +1 -4
  42. package/build/lib/commands/system-bars.js.map +1 -1
  43. package/build/lib/commands/touch.js +1 -9
  44. package/build/lib/commands/touch.js.map +1 -1
  45. package/build/lib/desired-caps.js +2 -4
  46. package/build/lib/desired-caps.js.map +1 -1
  47. package/build/lib/driver.js +1 -20
  48. package/build/lib/driver.js.map +1 -1
  49. package/build/lib/uiautomator.js +1 -3
  50. package/build/lib/uiautomator.js.map +1 -1
  51. package/build/lib/unlock-helpers.js +1 -3
  52. package/build/lib/unlock-helpers.js.map +1 -1
  53. package/build/lib/webview-helpers.js +1 -13
  54. package/build/lib/webview-helpers.js.map +1 -1
  55. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"performance.js","names":["commands","helpers","extensions","NETWORK_KEYS","CPU_KEYS","BATTERY_KEYS","MEMORY_KEYS","SUPPORTED_PERFORMANCE_DATA_TYPES","Object","freeze","cpuinfo","memoryinfo","batteryinfo","networkinfo","MEMINFO_TITLES","NATIVE","DALVIK","EGL","GL","MTRACK","TOTAL","HEAP","RETRY_PAUSE_MS","parseMeminfoForApi19To29","entries","valDict","type","subType","nativePss","nativePrivateDirty","nativeHeapSize","nativeHeapAllocatedSize","dalvikPss","dalvikPrivateDirty","eglPss","eglPrivateDirty","glPss","glPrivateDirty","length","totalPss","totalPrivateDirty","parseMeminfoForApiBelow19","parseMeminfoForApiAbove29","nativeRss","dalvikRss","totalRss","getPerformanceDataTypes","_","keys","getPerformanceData","packageName","dataType","retries","toLower","getBatteryInfo","getCPUInfo","getMemoryInfo","getNetworkTrafficInfo","Error","JSON","stringify","retryInterval","output","adb","shell","e","stderr","log","info","usagesPattern","RegExp","escapeRegExp","match","exec","debug","cmd","data","power","parseInt","split","trim","Number","isNaN","clone","toString","apiLevel","getApiLevel","line","filter","Boolean","headers","values","map","header","returnValue","bucketDuration","bucketStart","activeTime","rxBytes","rxPackets","txBytes","txPackets","operations","index","fromXtstats","indexOf","start","delimiter","end","pendingBytes","substring","arrayList","j","k","returnIndex","i","isEqual","isUndefined","assign"],"sources":["../../../lib/commands/performance.js"],"sourcesContent":["import _ from 'lodash';\nimport { retryInterval } from 'asyncbox';\n\nconst commands = {}, helpers = {}, extensions = {};\n\nconst NETWORK_KEYS = [\n ['bucketStart', 'activeTime', 'rxBytes', 'rxPackets', 'txBytes', 'txPackets', 'operations', 'bucketDuration'],\n ['st', 'activeTime', 'rb', 'rp', 'tb', 'tp', 'op', 'bucketDuration']\n];\nconst CPU_KEYS = ['user', 'kernel'];\nconst BATTERY_KEYS = ['power'];\nconst MEMORY_KEYS = [\n 'totalPrivateDirty', 'nativePrivateDirty', 'dalvikPrivateDirty',\n 'eglPrivateDirty', 'glPrivateDirty',\n 'totalPss', 'nativePss', 'dalvikPss', 'eglPss', 'glPss',\n 'nativeHeapAllocatedSize', 'nativeHeapSize',\n 'nativeRss', 'dalvikRss', 'totalRss'\n];\nconst SUPPORTED_PERFORMANCE_DATA_TYPES = Object.freeze({\n cpuinfo: 'the amount of cpu by user and kernel process - cpu information for applications on real devices and simulators',\n memoryinfo: 'the amount of memory used by the process - memory information for applications on real devices and simulators',\n batteryinfo: 'the remaining battery power - battery power information for applications on real devices and simulators',\n networkinfo: 'the network statistics - network rx/tx information for applications on real devices and simulators'\n});\nconst MEMINFO_TITLES = Object.freeze({\n NATIVE: 'Native',\n DALVIK: 'Dalvik',\n EGL: 'EGL',\n GL: 'GL',\n MTRACK: 'mtrack',\n TOTAL: 'TOTAL',\n HEAP: 'Heap'\n});\nconst RETRY_PAUSE_MS = 1000;\n\n/**\n * API level between 18 and 30\n * ['<System Type>', '<Memory Type>', <pss total>, <private dirty>, <private clean>, <swapPss dirty>, <heap size>, <heap alloc>, <heap free>]\n * except 'TOTAL', which skips the second type name\n * !!! valDict gets mutated\n */\nfunction parseMeminfoForApi19To29 (entries, valDict) {\n const [type, subType] = entries;\n if (type === MEMINFO_TITLES.NATIVE && subType === MEMINFO_TITLES.HEAP) {\n [,, valDict.nativePss, valDict.nativePrivateDirty,,, valDict.nativeHeapSize, valDict.nativeHeapAllocatedSize] = entries;\n } else if (type === MEMINFO_TITLES.DALVIK && subType === MEMINFO_TITLES.HEAP) {\n [,, valDict.dalvikPss, valDict.dalvikPrivateDirty] = entries;\n } else if (type === MEMINFO_TITLES.EGL && subType === MEMINFO_TITLES.MTRACK) {\n [,, valDict.eglPss, valDict.eglPrivateDirty] = entries;\n } else if (type === MEMINFO_TITLES.GL && subType === MEMINFO_TITLES.MTRACK) {\n [,, valDict.glPss, valDict.glPrivateDirty] = entries;\n } else if (type === MEMINFO_TITLES.TOTAL && entries.length === 8) {\n // there are two totals, and we only want the full listing, which has 8 entries\n [, valDict.totalPss, valDict.totalPrivateDirty] = entries;\n }\n}\n\n/**\n * ['<System Type', '<pps>', '<shared dirty>', '<private dirty>', '<heap size>', '<heap alloc>', '<heap free>']\n * !!! valDict gets mutated\n */\nfunction parseMeminfoForApiBelow19 (entries, valDict) {\n const type = entries[0];\n if (type === MEMINFO_TITLES.NATIVE) {\n [, valDict.nativePss,, valDict.nativePrivateDirty, valDict.nativeHeapSize, valDict.nativeHeapAllocatedSize] = entries;\n } else if (type === MEMINFO_TITLES.DALVIK) {\n [, valDict.dalvikPss,, valDict.dalvikPrivateDirty] = entries;\n } else if (type === MEMINFO_TITLES.EGL) {\n [, valDict.eglPss,, valDict.eglPrivateDirty] = entries;\n } else if (type === MEMINFO_TITLES.GL) {\n [, valDict.glPss,, valDict.glPrivateDirty] = entries;\n } else if (type === MEMINFO_TITLES.TOTAL) {\n [, valDict.totalPss,, valDict.totalPrivateDirty] = entries;\n }\n}\n\n/**\n * API level 30 and above\n * ['<System Type>', '<Memory Type>', <pss total>, <private dirty>, <private clean>, <swapPss dirty>, <rss total>, <heap size>, <heap alloc>, <heap free>]\n * !!! valDict gets mutated\n */\nfunction parseMeminfoForApiAbove29 (entries, valDict) {\n const [type, subType] = entries;\n if (type === MEMINFO_TITLES.NATIVE && subType === MEMINFO_TITLES.HEAP) {\n [,, valDict.nativePss, valDict.nativePrivateDirty,,, valDict.nativeRss, valDict.nativeHeapSize, valDict.nativeHeapAllocatedSize] = entries;\n } else if (type === MEMINFO_TITLES.DALVIK && subType === MEMINFO_TITLES.HEAP) {\n [,, valDict.dalvikPss, valDict.dalvikPrivateDirty,,, valDict.dalvikRss] = entries;\n } else if (type === MEMINFO_TITLES.EGL && subType === MEMINFO_TITLES.MTRACK) {\n [,, valDict.eglPss, valDict.eglPrivateDirty] = entries;\n } else if (type === MEMINFO_TITLES.GL && subType === MEMINFO_TITLES.MTRACK) {\n [,, valDict.glPss, valDict.glPrivateDirty] = entries;\n } else if (type === MEMINFO_TITLES.TOTAL && entries.length === 9) {\n // has 9 entries\n [, valDict.totalPss, valDict.totalPrivateDirty,,, valDict.totalRss] = entries;\n }\n}\n\n//\n// returns the information type of the system state which is supported to read as like cpu, memory, network traffic, and battery.\n// output - array like below\n// [cpuinfo, batteryinfo, networkinfo, memoryinfo]\n//\ncommands.getPerformanceDataTypes = function getPerformanceDataTypes () {\n return _.keys(SUPPORTED_PERFORMANCE_DATA_TYPES);\n};\n\n/**\n * @returns The information type of the system state which is supported to read as like cpu, memory, network traffic, and battery.\n * input - (packageName) the package name of the application\n * (dataType) the type of system state which wants to read. It should be one of the keys of the SUPPORTED_PERFORMANCE_DATA_TYPES\n * (dataReadTimeout) the number of attempts to read\n * output - table of the performance data, The first line of the table represents the type of data. The remaining lines represent the values of the data.\n *\n * in case of battery info : [[power], [23]]\n * in case of memory info : [[totalPrivateDirty, nativePrivateDirty, dalvikPrivateDirty, eglPrivateDirty, glPrivateDirty, totalPss,\n * nativePss, dalvikPss, eglPss, glPss, nativeHeapAllocatedSize, nativeHeapSize], [18360, 8296, 6132, null, null, 42588, 8406, 7024, null, null, 26519, 10344]]\n * in case of network info : [[bucketStart, activeTime, rxBytes, rxPackets, txBytes, txPackets, operations, bucketDuration,],\n * [1478091600000, null, 1099075, 610947, 928, 114362, 769, 0, 3600000], [1478095200000, null, 1306300, 405997, 509, 46359, 370, 0, 3600000]]\n * in case of network info : [[st, activeTime, rb, rp, tb, tp, op, bucketDuration], [1478088000, null, null, 32115296, 34291, 2956805, 25705, 0, 3600],\n * [1478091600, null, null, 2714683, 11821, 1420564, 12650, 0, 3600], [1478095200, null, null, 10079213, 19962, 2487705, 20015, 0, 3600],\n * [1478098800, null, null, 4444433, 10227, 1430356, 10493, 0, 3600]]\n * in case of cpu info : [[user, kernel], [0.9, 1.3]]\n */\ncommands.getPerformanceData = async function getPerformanceData (packageName, dataType, retries = 2) {\n switch (_.toLower(dataType)) {\n case 'batteryinfo':\n return await this.getBatteryInfo(retries);\n case 'cpuinfo':\n return await this.getCPUInfo(packageName, retries);\n case 'memoryinfo':\n return await this.getMemoryInfo(packageName, retries);\n case 'networkinfo':\n return await this.getNetworkTrafficInfo(retries);\n default:\n throw new Error(`No performance data of type '${dataType}' found. ` +\n `Only the following values are supported: ${JSON.stringify(SUPPORTED_PERFORMANCE_DATA_TYPES, ' ', 2)}`);\n }\n};\n\nhelpers.getCPUInfo = async function getCPUInfo (packageName, retries = 2) {\n // TODO: figure out why this is\n // sometimes, the function of 'adb.shell' fails. when I tested this function on the target of 'Galaxy Note5',\n // adb.shell(dumpsys cpuinfo) returns cpu datas for other application packages, but I can't find the data for packageName.\n // It usually fails 30 times and success for the next time,\n // Since then, he has continued to succeed.\n return await retryInterval(retries, RETRY_PAUSE_MS, async () => {\n let output;\n try {\n output = await this.adb.shell(['dumpsys', 'cpuinfo']);\n } catch (e) {\n if (e.stderr) {\n this.log.info(e.stderr);\n }\n throw e;\n }\n // `output` will be something like\n // +0% 2209/io.appium.android.apis: 0.1% user + 0.2% kernel / faults: 70 minor\n const usagesPattern =\n new RegExp(`^.+\\\\/${_.escapeRegExp(packageName)}:\\\\D+([\\\\d.]+)%\\\\s+user\\\\s+\\\\+\\\\s+([\\\\d.]+)%\\\\s+kernel`, 'm');\n const match = usagesPattern.exec(output);\n if (!match) {\n this.log.debug(output);\n throw new Error(`Unable to parse cpu usage data for '${packageName}'. Check the server log for more details`);\n }\n return [CPU_KEYS, [match[1], match[2]]];\n });\n};\n\nhelpers.getBatteryInfo = async function getBatteryInfo (retries = 2) {\n return await retryInterval(retries, RETRY_PAUSE_MS, async () => {\n let cmd = ['dumpsys', 'battery', '|', 'grep', 'level'];\n let data = await this.adb.shell(cmd);\n if (!data) throw new Error('No data from dumpsys'); //eslint-disable-line curly\n\n let power = parseInt((data.split(':')[1] || '').trim(), 10);\n\n if (!Number.isNaN(power)) {\n return [_.clone(BATTERY_KEYS), [power.toString()]];\n } else {\n throw new Error(`Unable to parse battery data: '${data}'`);\n }\n });\n};\n\nhelpers.getMemoryInfo = async function getMemoryInfo (packageName, retries = 2) {\n return await retryInterval(retries, RETRY_PAUSE_MS, async () => {\n const cmd = [\n 'dumpsys', 'meminfo', `'${packageName}'`,\n '|', 'grep', '-E',\n `'${MEMINFO_TITLES.NATIVE}|${MEMINFO_TITLES.DALVIK}|${MEMINFO_TITLES.EGL}` +\n `|${MEMINFO_TITLES.GL}|${MEMINFO_TITLES.TOTAL}'`\n ];\n const data = await this.adb.shell(cmd);\n if (!data) {\n throw new Error('No data from dumpsys');\n }\n const valDict = {totalPrivateDirty: ''};\n const apiLevel = await this.adb.getApiLevel();\n for (const line of data.split('\\n')) {\n const entries = line.trim().split(/\\s+/).filter(Boolean);\n if (apiLevel >= 30) {\n parseMeminfoForApiAbove29(entries, valDict);\n } else if (apiLevel > 18 && apiLevel < 30) {\n parseMeminfoForApi19To29(entries, valDict);\n } else {\n parseMeminfoForApiBelow19(entries, valDict);\n }\n }\n if (valDict.totalPrivateDirty && valDict.totalPrivateDirty !== 'nodex') {\n const headers = _.clone(MEMORY_KEYS);\n const values = headers.map((header) => valDict[header]);\n return [headers, values];\n }\n\n throw new Error(`Unable to parse memory data: '${data}'`);\n });\n};\n\nhelpers.getNetworkTrafficInfo = async function getNetworkTrafficInfo (retries = 2) {\n return await retryInterval(retries, RETRY_PAUSE_MS, async () => {\n let returnValue = [];\n let bucketDuration, bucketStart, activeTime, rxBytes, rxPackets, txBytes, txPackets, operations;\n\n let cmd = ['dumpsys', 'netstats'];\n let data = await this.adb.shell(cmd);\n if (!data) throw new Error('No data from dumpsys'); //eslint-disable-line curly\n\n // In case of network traffic information, it is different for the return data between emulator and real device.\n // the return data of emulator\n // Xt stats:\n // Pending bytes: 39250\n // History since boot:\n // ident=[[type=WIFI, subType=COMBINED, networkId=\"WiredSSID\"]] uid=-1 set=ALL tag=0x0\n // NetworkStatsHistory: bucketDuration=3600000\n // bucketStart=1478098800000 activeTime=31824 rxBytes=21502 rxPackets=78 txBytes=17748 txPackets=90 operations=0\n //\n // 7.1\n // Xt stats:\n // Pending bytes: 481487\n // History since boot:\n // ident=[{type=MOBILE, subType=COMBINED, subscriberId=310260..., metered=true}] uid=-1 set=ALL tag=0x0\n // NetworkStatsHistory: bucketDuration=3600\n // st=1483984800 rb=0 rp=0 tb=12031 tp=184 op=0\n // st=1483988400 rb=0 rp=0 tb=38476 tp=587 op=0\n // st=1483999200 rb=315616 rp=400 tb=94800 tp=362 op=0\n // st=1484002800 rb=15826 rp=20 tb=4738 tp=16 op=0\n //\n // the return data of real device\n // Xt stats:\n // Pending bytes: 0\n // History since boot:\n // ident=[{type=MOBILE, subType=COMBINED, subscriberId=450050...}] uid=-1 set=ALL tag=0x0\n // NetworkStatsHistory: bucketDuration=3600\n // st=1478088000 rb=32115296 rp=34291 tb=2956805 tp=25705 op=0\n // st=1478091600 rb=2714683 rp=11821 tb=1420564 tp=12650 op=0\n // st=1478095200 rb=10079213 rp=19962 tb=2487705 tp=20015 op=0\n // st=1478098800 rb=4444433 rp=10227 tb=1430356 tp=10493 op=0\n let index = 0;\n let fromXtstats = data.indexOf('Xt stats:');\n\n let start = data.indexOf('Pending bytes:', fromXtstats);\n let delimiter = data.indexOf(':', start + 1);\n let end = data.indexOf('\\n', delimiter + 1);\n let pendingBytes = data.substring(delimiter + 1, end).trim();\n\n if (end > delimiter) {\n start = data.indexOf('bucketDuration', end + 1);\n delimiter = data.indexOf('=', start + 1);\n end = data.indexOf('\\n', delimiter + 1);\n bucketDuration = data.substring(delimiter + 1, end).trim();\n }\n\n if (start >= 0) {\n data = data.substring(end + 1, data.length);\n let arrayList = data.split('\\n');\n\n if (arrayList.length > 0) {\n start = -1;\n\n for (let j = 0; j < NETWORK_KEYS.length; ++j) {\n start = arrayList[0].indexOf(NETWORK_KEYS[j][0]);\n\n if (start >= 0) {\n index = j;\n returnValue[0] = [];\n\n for (let k = 0; k < NETWORK_KEYS[j].length; ++k) {\n returnValue[0][k] = NETWORK_KEYS[j][k];\n }\n break;\n }\n }\n\n let returnIndex = 1;\n for (let i = 0; i < arrayList.length; i++) {\n data = arrayList[i];\n start = data.indexOf(NETWORK_KEYS[index][0]);\n\n if (start >= 0) {\n delimiter = data.indexOf('=', start + 1);\n end = data.indexOf(' ', delimiter + 1);\n bucketStart = data.substring(delimiter + 1, end).trim();\n\n if (end > delimiter) {\n start = data.indexOf(NETWORK_KEYS[index][1], end + 1);\n if (start >= 0) {\n delimiter = data.indexOf('=', start + 1);\n end = data.indexOf(' ', delimiter + 1);\n activeTime = data.substring(delimiter + 1, end).trim();\n }\n }\n\n if (end > delimiter) {\n start = data.indexOf(NETWORK_KEYS[index][2], end + 1);\n if (start >= 0) {\n delimiter = data.indexOf('=', start + 1);\n end = data.indexOf(' ', delimiter + 1);\n rxBytes = data.substring(delimiter + 1, end).trim();\n }\n }\n\n if (end > delimiter) {\n start = data.indexOf(NETWORK_KEYS[index][3], end + 1);\n if (start >= 0) {\n delimiter = data.indexOf('=', start + 1);\n end = data.indexOf(' ', delimiter + 1);\n rxPackets = data.substring(delimiter + 1, end).trim();\n }\n }\n\n if (end > delimiter) {\n start = data.indexOf(NETWORK_KEYS[index][4], end + 1);\n if (start >= 0) {\n delimiter = data.indexOf('=', start + 1);\n end = data.indexOf(' ', delimiter + 1);\n txBytes = data.substring(delimiter + 1, end).trim();\n }\n }\n\n if (end > delimiter) {\n start = data.indexOf(NETWORK_KEYS[index][5], end + 1);\n if (start >= 0) {\n delimiter = data.indexOf('=', start + 1);\n end = data.indexOf(' ', delimiter + 1);\n txPackets = data.substring(delimiter + 1, end).trim();\n }\n }\n\n if (end > delimiter) {\n start = data.indexOf(NETWORK_KEYS[index][6], end + 1);\n if (start >= 0) {\n delimiter = data.indexOf('=', start + 1);\n end = data.length;\n operations = data.substring(delimiter + 1, end).trim();\n\n }\n }\n returnValue[returnIndex++] = [bucketStart, activeTime, rxBytes, rxPackets, txBytes, txPackets, operations, bucketDuration];\n }\n }\n }\n }\n\n if (!_.isEqual(pendingBytes, '') && !_.isUndefined(pendingBytes) && !_.isEqual(pendingBytes, 'nodex')) {\n return returnValue;\n } else {\n throw new Error(`Unable to parse network traffic data: '${data}'`);\n }\n });\n};\n\nObject.assign(extensions, commands, helpers);\nexport {\n commands, helpers, SUPPORTED_PERFORMANCE_DATA_TYPES, CPU_KEYS, MEMORY_KEYS,\n BATTERY_KEYS, NETWORK_KEYS,\n};\nexport default extensions;\n\n"],"mappings":"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"}
1
+ {"version":3,"file":"performance.js","names":["commands","helpers","extensions","NETWORK_KEYS","CPU_KEYS","BATTERY_KEYS","MEMORY_KEYS","SUPPORTED_PERFORMANCE_DATA_TYPES","Object","freeze","cpuinfo","memoryinfo","batteryinfo","networkinfo","MEMINFO_TITLES","NATIVE","DALVIK","EGL","GL","MTRACK","TOTAL","HEAP","RETRY_PAUSE_MS","parseMeminfoForApi19To29","entries","valDict","type","subType","nativePss","nativePrivateDirty","nativeHeapSize","nativeHeapAllocatedSize","dalvikPss","dalvikPrivateDirty","eglPss","eglPrivateDirty","glPss","glPrivateDirty","length","totalPss","totalPrivateDirty","parseMeminfoForApiBelow19","parseMeminfoForApiAbove29","nativeRss","dalvikRss","totalRss","getPerformanceDataTypes","_","keys","getPerformanceData","packageName","dataType","retries","toLower","getBatteryInfo","getCPUInfo","getMemoryInfo","getNetworkTrafficInfo","Error","JSON","stringify","retryInterval","output","adb","shell","e","stderr","log","info","usagesPattern","RegExp","escapeRegExp","match","exec","debug","cmd","data","power","parseInt","split","trim","Number","isNaN","clone","toString","apiLevel","getApiLevel","line","filter","Boolean","headers","values","map","header","returnValue","bucketDuration","bucketStart","activeTime","rxBytes","rxPackets","txBytes","txPackets","operations","index","fromXtstats","indexOf","start","delimiter","end","pendingBytes","substring","arrayList","j","k","returnIndex","i","isEqual","isUndefined","assign"],"sources":["../../../lib/commands/performance.js"],"sourcesContent":["import _ from 'lodash';\nimport { retryInterval } from 'asyncbox';\n\nconst commands = {}, helpers = {}, extensions = {};\n\nconst NETWORK_KEYS = [\n ['bucketStart', 'activeTime', 'rxBytes', 'rxPackets', 'txBytes', 'txPackets', 'operations', 'bucketDuration'],\n ['st', 'activeTime', 'rb', 'rp', 'tb', 'tp', 'op', 'bucketDuration']\n];\nconst CPU_KEYS = ['user', 'kernel'];\nconst BATTERY_KEYS = ['power'];\nconst MEMORY_KEYS = [\n 'totalPrivateDirty', 'nativePrivateDirty', 'dalvikPrivateDirty',\n 'eglPrivateDirty', 'glPrivateDirty',\n 'totalPss', 'nativePss', 'dalvikPss', 'eglPss', 'glPss',\n 'nativeHeapAllocatedSize', 'nativeHeapSize',\n 'nativeRss', 'dalvikRss', 'totalRss'\n];\nconst SUPPORTED_PERFORMANCE_DATA_TYPES = Object.freeze({\n cpuinfo: 'the amount of cpu by user and kernel process - cpu information for applications on real devices and simulators',\n memoryinfo: 'the amount of memory used by the process - memory information for applications on real devices and simulators',\n batteryinfo: 'the remaining battery power - battery power information for applications on real devices and simulators',\n networkinfo: 'the network statistics - network rx/tx information for applications on real devices and simulators'\n});\nconst MEMINFO_TITLES = Object.freeze({\n NATIVE: 'Native',\n DALVIK: 'Dalvik',\n EGL: 'EGL',\n GL: 'GL',\n MTRACK: 'mtrack',\n TOTAL: 'TOTAL',\n HEAP: 'Heap'\n});\nconst RETRY_PAUSE_MS = 1000;\n\n/**\n * API level between 18 and 30\n * ['<System Type>', '<Memory Type>', <pss total>, <private dirty>, <private clean>, <swapPss dirty>, <heap size>, <heap alloc>, <heap free>]\n * except 'TOTAL', which skips the second type name\n * !!! valDict gets mutated\n */\nfunction parseMeminfoForApi19To29 (entries, valDict) {\n const [type, subType] = entries;\n if (type === MEMINFO_TITLES.NATIVE && subType === MEMINFO_TITLES.HEAP) {\n [,, valDict.nativePss, valDict.nativePrivateDirty,,, valDict.nativeHeapSize, valDict.nativeHeapAllocatedSize] = entries;\n } else if (type === MEMINFO_TITLES.DALVIK && subType === MEMINFO_TITLES.HEAP) {\n [,, valDict.dalvikPss, valDict.dalvikPrivateDirty] = entries;\n } else if (type === MEMINFO_TITLES.EGL && subType === MEMINFO_TITLES.MTRACK) {\n [,, valDict.eglPss, valDict.eglPrivateDirty] = entries;\n } else if (type === MEMINFO_TITLES.GL && subType === MEMINFO_TITLES.MTRACK) {\n [,, valDict.glPss, valDict.glPrivateDirty] = entries;\n } else if (type === MEMINFO_TITLES.TOTAL && entries.length === 8) {\n // there are two totals, and we only want the full listing, which has 8 entries\n [, valDict.totalPss, valDict.totalPrivateDirty] = entries;\n }\n}\n\n/**\n * ['<System Type', '<pps>', '<shared dirty>', '<private dirty>', '<heap size>', '<heap alloc>', '<heap free>']\n * !!! valDict gets mutated\n */\nfunction parseMeminfoForApiBelow19 (entries, valDict) {\n const type = entries[0];\n if (type === MEMINFO_TITLES.NATIVE) {\n [, valDict.nativePss,, valDict.nativePrivateDirty, valDict.nativeHeapSize, valDict.nativeHeapAllocatedSize] = entries;\n } else if (type === MEMINFO_TITLES.DALVIK) {\n [, valDict.dalvikPss,, valDict.dalvikPrivateDirty] = entries;\n } else if (type === MEMINFO_TITLES.EGL) {\n [, valDict.eglPss,, valDict.eglPrivateDirty] = entries;\n } else if (type === MEMINFO_TITLES.GL) {\n [, valDict.glPss,, valDict.glPrivateDirty] = entries;\n } else if (type === MEMINFO_TITLES.TOTAL) {\n [, valDict.totalPss,, valDict.totalPrivateDirty] = entries;\n }\n}\n\n/**\n * API level 30 and above\n * ['<System Type>', '<Memory Type>', <pss total>, <private dirty>, <private clean>, <swapPss dirty>, <rss total>, <heap size>, <heap alloc>, <heap free>]\n * !!! valDict gets mutated\n */\nfunction parseMeminfoForApiAbove29 (entries, valDict) {\n const [type, subType] = entries;\n if (type === MEMINFO_TITLES.NATIVE && subType === MEMINFO_TITLES.HEAP) {\n [,, valDict.nativePss, valDict.nativePrivateDirty,,, valDict.nativeRss, valDict.nativeHeapSize, valDict.nativeHeapAllocatedSize] = entries;\n } else if (type === MEMINFO_TITLES.DALVIK && subType === MEMINFO_TITLES.HEAP) {\n [,, valDict.dalvikPss, valDict.dalvikPrivateDirty,,, valDict.dalvikRss] = entries;\n } else if (type === MEMINFO_TITLES.EGL && subType === MEMINFO_TITLES.MTRACK) {\n [,, valDict.eglPss, valDict.eglPrivateDirty] = entries;\n } else if (type === MEMINFO_TITLES.GL && subType === MEMINFO_TITLES.MTRACK) {\n [,, valDict.glPss, valDict.glPrivateDirty] = entries;\n } else if (type === MEMINFO_TITLES.TOTAL && entries.length === 9) {\n // has 9 entries\n [, valDict.totalPss, valDict.totalPrivateDirty,,, valDict.totalRss] = entries;\n }\n}\n\n//\n// returns the information type of the system state which is supported to read as like cpu, memory, network traffic, and battery.\n// output - array like below\n// [cpuinfo, batteryinfo, networkinfo, memoryinfo]\n//\ncommands.getPerformanceDataTypes = function getPerformanceDataTypes () {\n return _.keys(SUPPORTED_PERFORMANCE_DATA_TYPES);\n};\n\n/**\n * @returns The information type of the system state which is supported to read as like cpu, memory, network traffic, and battery.\n * input - (packageName) the package name of the application\n * (dataType) the type of system state which wants to read. It should be one of the keys of the SUPPORTED_PERFORMANCE_DATA_TYPES\n * (dataReadTimeout) the number of attempts to read\n * output - table of the performance data, The first line of the table represents the type of data. The remaining lines represent the values of the data.\n *\n * in case of battery info : [[power], [23]]\n * in case of memory info : [[totalPrivateDirty, nativePrivateDirty, dalvikPrivateDirty, eglPrivateDirty, glPrivateDirty, totalPss,\n * nativePss, dalvikPss, eglPss, glPss, nativeHeapAllocatedSize, nativeHeapSize], [18360, 8296, 6132, null, null, 42588, 8406, 7024, null, null, 26519, 10344]]\n * in case of network info : [[bucketStart, activeTime, rxBytes, rxPackets, txBytes, txPackets, operations, bucketDuration,],\n * [1478091600000, null, 1099075, 610947, 928, 114362, 769, 0, 3600000], [1478095200000, null, 1306300, 405997, 509, 46359, 370, 0, 3600000]]\n * in case of network info : [[st, activeTime, rb, rp, tb, tp, op, bucketDuration], [1478088000, null, null, 32115296, 34291, 2956805, 25705, 0, 3600],\n * [1478091600, null, null, 2714683, 11821, 1420564, 12650, 0, 3600], [1478095200, null, null, 10079213, 19962, 2487705, 20015, 0, 3600],\n * [1478098800, null, null, 4444433, 10227, 1430356, 10493, 0, 3600]]\n * in case of cpu info : [[user, kernel], [0.9, 1.3]]\n */\ncommands.getPerformanceData = async function getPerformanceData (packageName, dataType, retries = 2) {\n switch (_.toLower(dataType)) {\n case 'batteryinfo':\n return await this.getBatteryInfo(retries);\n case 'cpuinfo':\n return await this.getCPUInfo(packageName, retries);\n case 'memoryinfo':\n return await this.getMemoryInfo(packageName, retries);\n case 'networkinfo':\n return await this.getNetworkTrafficInfo(retries);\n default:\n throw new Error(`No performance data of type '${dataType}' found. ` +\n `Only the following values are supported: ${JSON.stringify(SUPPORTED_PERFORMANCE_DATA_TYPES, ' ', 2)}`);\n }\n};\n\nhelpers.getCPUInfo = async function getCPUInfo (packageName, retries = 2) {\n // TODO: figure out why this is\n // sometimes, the function of 'adb.shell' fails. when I tested this function on the target of 'Galaxy Note5',\n // adb.shell(dumpsys cpuinfo) returns cpu datas for other application packages, but I can't find the data for packageName.\n // It usually fails 30 times and success for the next time,\n // Since then, he has continued to succeed.\n return await retryInterval(retries, RETRY_PAUSE_MS, async () => {\n let output;\n try {\n output = await this.adb.shell(['dumpsys', 'cpuinfo']);\n } catch (e) {\n if (e.stderr) {\n this.log.info(e.stderr);\n }\n throw e;\n }\n // `output` will be something like\n // +0% 2209/io.appium.android.apis: 0.1% user + 0.2% kernel / faults: 70 minor\n const usagesPattern =\n new RegExp(`^.+\\\\/${_.escapeRegExp(packageName)}:\\\\D+([\\\\d.]+)%\\\\s+user\\\\s+\\\\+\\\\s+([\\\\d.]+)%\\\\s+kernel`, 'm');\n const match = usagesPattern.exec(output);\n if (!match) {\n this.log.debug(output);\n throw new Error(`Unable to parse cpu usage data for '${packageName}'. Check the server log for more details`);\n }\n return [CPU_KEYS, [match[1], match[2]]];\n });\n};\n\nhelpers.getBatteryInfo = async function getBatteryInfo (retries = 2) {\n return await retryInterval(retries, RETRY_PAUSE_MS, async () => {\n let cmd = ['dumpsys', 'battery', '|', 'grep', 'level'];\n let data = await this.adb.shell(cmd);\n if (!data) throw new Error('No data from dumpsys'); //eslint-disable-line curly\n\n let power = parseInt((data.split(':')[1] || '').trim(), 10);\n\n if (!Number.isNaN(power)) {\n return [_.clone(BATTERY_KEYS), [power.toString()]];\n } else {\n throw new Error(`Unable to parse battery data: '${data}'`);\n }\n });\n};\n\nhelpers.getMemoryInfo = async function getMemoryInfo (packageName, retries = 2) {\n return await retryInterval(retries, RETRY_PAUSE_MS, async () => {\n const cmd = [\n 'dumpsys', 'meminfo', `'${packageName}'`,\n '|', 'grep', '-E',\n `'${MEMINFO_TITLES.NATIVE}|${MEMINFO_TITLES.DALVIK}|${MEMINFO_TITLES.EGL}` +\n `|${MEMINFO_TITLES.GL}|${MEMINFO_TITLES.TOTAL}'`\n ];\n const data = await this.adb.shell(cmd);\n if (!data) {\n throw new Error('No data from dumpsys');\n }\n const valDict = {totalPrivateDirty: ''};\n const apiLevel = await this.adb.getApiLevel();\n for (const line of data.split('\\n')) {\n const entries = line.trim().split(/\\s+/).filter(Boolean);\n if (apiLevel >= 30) {\n parseMeminfoForApiAbove29(entries, valDict);\n } else if (apiLevel > 18 && apiLevel < 30) {\n parseMeminfoForApi19To29(entries, valDict);\n } else {\n parseMeminfoForApiBelow19(entries, valDict);\n }\n }\n if (valDict.totalPrivateDirty && valDict.totalPrivateDirty !== 'nodex') {\n const headers = _.clone(MEMORY_KEYS);\n const values = headers.map((header) => valDict[header]);\n return [headers, values];\n }\n\n throw new Error(`Unable to parse memory data: '${data}'`);\n });\n};\n\nhelpers.getNetworkTrafficInfo = async function getNetworkTrafficInfo (retries = 2) {\n return await retryInterval(retries, RETRY_PAUSE_MS, async () => {\n let returnValue = [];\n let bucketDuration, bucketStart, activeTime, rxBytes, rxPackets, txBytes, txPackets, operations;\n\n let cmd = ['dumpsys', 'netstats'];\n let data = await this.adb.shell(cmd);\n if (!data) throw new Error('No data from dumpsys'); //eslint-disable-line curly\n\n // In case of network traffic information, it is different for the return data between emulator and real device.\n // the return data of emulator\n // Xt stats:\n // Pending bytes: 39250\n // History since boot:\n // ident=[[type=WIFI, subType=COMBINED, networkId=\"WiredSSID\"]] uid=-1 set=ALL tag=0x0\n // NetworkStatsHistory: bucketDuration=3600000\n // bucketStart=1478098800000 activeTime=31824 rxBytes=21502 rxPackets=78 txBytes=17748 txPackets=90 operations=0\n //\n // 7.1\n // Xt stats:\n // Pending bytes: 481487\n // History since boot:\n // ident=[{type=MOBILE, subType=COMBINED, subscriberId=310260..., metered=true}] uid=-1 set=ALL tag=0x0\n // NetworkStatsHistory: bucketDuration=3600\n // st=1483984800 rb=0 rp=0 tb=12031 tp=184 op=0\n // st=1483988400 rb=0 rp=0 tb=38476 tp=587 op=0\n // st=1483999200 rb=315616 rp=400 tb=94800 tp=362 op=0\n // st=1484002800 rb=15826 rp=20 tb=4738 tp=16 op=0\n //\n // the return data of real device\n // Xt stats:\n // Pending bytes: 0\n // History since boot:\n // ident=[{type=MOBILE, subType=COMBINED, subscriberId=450050...}] uid=-1 set=ALL tag=0x0\n // NetworkStatsHistory: bucketDuration=3600\n // st=1478088000 rb=32115296 rp=34291 tb=2956805 tp=25705 op=0\n // st=1478091600 rb=2714683 rp=11821 tb=1420564 tp=12650 op=0\n // st=1478095200 rb=10079213 rp=19962 tb=2487705 tp=20015 op=0\n // st=1478098800 rb=4444433 rp=10227 tb=1430356 tp=10493 op=0\n let index = 0;\n let fromXtstats = data.indexOf('Xt stats:');\n\n let start = data.indexOf('Pending bytes:', fromXtstats);\n let delimiter = data.indexOf(':', start + 1);\n let end = data.indexOf('\\n', delimiter + 1);\n let pendingBytes = data.substring(delimiter + 1, end).trim();\n\n if (end > delimiter) {\n start = data.indexOf('bucketDuration', end + 1);\n delimiter = data.indexOf('=', start + 1);\n end = data.indexOf('\\n', delimiter + 1);\n bucketDuration = data.substring(delimiter + 1, end).trim();\n }\n\n if (start >= 0) {\n data = data.substring(end + 1, data.length);\n let arrayList = data.split('\\n');\n\n if (arrayList.length > 0) {\n start = -1;\n\n for (let j = 0; j < NETWORK_KEYS.length; ++j) {\n start = arrayList[0].indexOf(NETWORK_KEYS[j][0]);\n\n if (start >= 0) {\n index = j;\n returnValue[0] = [];\n\n for (let k = 0; k < NETWORK_KEYS[j].length; ++k) {\n returnValue[0][k] = NETWORK_KEYS[j][k];\n }\n break;\n }\n }\n\n let returnIndex = 1;\n for (let i = 0; i < arrayList.length; i++) {\n data = arrayList[i];\n start = data.indexOf(NETWORK_KEYS[index][0]);\n\n if (start >= 0) {\n delimiter = data.indexOf('=', start + 1);\n end = data.indexOf(' ', delimiter + 1);\n bucketStart = data.substring(delimiter + 1, end).trim();\n\n if (end > delimiter) {\n start = data.indexOf(NETWORK_KEYS[index][1], end + 1);\n if (start >= 0) {\n delimiter = data.indexOf('=', start + 1);\n end = data.indexOf(' ', delimiter + 1);\n activeTime = data.substring(delimiter + 1, end).trim();\n }\n }\n\n if (end > delimiter) {\n start = data.indexOf(NETWORK_KEYS[index][2], end + 1);\n if (start >= 0) {\n delimiter = data.indexOf('=', start + 1);\n end = data.indexOf(' ', delimiter + 1);\n rxBytes = data.substring(delimiter + 1, end).trim();\n }\n }\n\n if (end > delimiter) {\n start = data.indexOf(NETWORK_KEYS[index][3], end + 1);\n if (start >= 0) {\n delimiter = data.indexOf('=', start + 1);\n end = data.indexOf(' ', delimiter + 1);\n rxPackets = data.substring(delimiter + 1, end).trim();\n }\n }\n\n if (end > delimiter) {\n start = data.indexOf(NETWORK_KEYS[index][4], end + 1);\n if (start >= 0) {\n delimiter = data.indexOf('=', start + 1);\n end = data.indexOf(' ', delimiter + 1);\n txBytes = data.substring(delimiter + 1, end).trim();\n }\n }\n\n if (end > delimiter) {\n start = data.indexOf(NETWORK_KEYS[index][5], end + 1);\n if (start >= 0) {\n delimiter = data.indexOf('=', start + 1);\n end = data.indexOf(' ', delimiter + 1);\n txPackets = data.substring(delimiter + 1, end).trim();\n }\n }\n\n if (end > delimiter) {\n start = data.indexOf(NETWORK_KEYS[index][6], end + 1);\n if (start >= 0) {\n delimiter = data.indexOf('=', start + 1);\n end = data.length;\n operations = data.substring(delimiter + 1, end).trim();\n\n }\n }\n returnValue[returnIndex++] = [bucketStart, activeTime, rxBytes, rxPackets, txBytes, txPackets, operations, bucketDuration];\n }\n }\n }\n }\n\n if (!_.isEqual(pendingBytes, '') && !_.isUndefined(pendingBytes) && !_.isEqual(pendingBytes, 'nodex')) {\n return returnValue;\n } else {\n throw new Error(`Unable to parse network traffic data: '${data}'`);\n }\n });\n};\n\nObject.assign(extensions, commands, helpers);\nexport {\n commands, helpers, SUPPORTED_PERFORMANCE_DATA_TYPES, CPU_KEYS, MEMORY_KEYS,\n BATTERY_KEYS, NETWORK_KEYS,\n};\nexport default extensions;\n\n"],"mappings":"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"}
@@ -151,7 +151,6 @@ async function terminateBackgroundScreenRecording(adb, force = true) {
151
151
  throw new Error(`Unable to stop the background screen recording: ${err.message}`);
152
152
  }
153
153
  }
154
-
155
154
  commands.startRecordingScreen = async function startRecordingScreen(options = {}) {
156
155
  await verifyScreenRecordIsSupported(this.adb, this.isEmulator());
157
156
  let result = '';
@@ -192,7 +191,6 @@ commands.startRecordingScreen = async function startRecordingScreen(options = {}
192
191
  await scheduleScreenRecord(this.adb, this._screenRecordingProperties, this.log);
193
192
  return result;
194
193
  };
195
-
196
194
  commands.stopRecordingScreen = async function stopRecordingScreen(options = {}) {
197
195
  await verifyScreenRecordIsSupported(this.adb, this.isEmulator());
198
196
  if (!_lodash.default.isEmpty(this._screenRecordingProperties)) {
@@ -252,4 +250,4 @@ commands.stopRecordingScreen = async function stopRecordingScreen(options = {})
252
250
  };
253
251
  var _default = commands;
254
252
  exports.default = _default;
255
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjb21tYW5kcyIsIlJFVFJZX1BBVVNFIiwiUkVUUllfVElNRU9VVCIsIk1BWF9SRUNPUkRJTkdfVElNRV9TRUMiLCJNQVhfVElNRV9TRUMiLCJERUZBVUxUX1JFQ09SRElOR19USU1FX1NFQyIsIlBST0NFU1NfU0hVVERPV05fVElNRU9VVCIsIlNDUkVFTlJFQ09SRF9CSU5BUlkiLCJERUZBVUxUX0VYVCIsIk1JTl9FTVVMQVRPUl9BUElfTEVWRUwiLCJGRk1QRUdfQklOQVJZIiwic3lzdGVtIiwiaXNXaW5kb3dzIiwidXBsb2FkUmVjb3JkZWRNZWRpYSIsImxvY2FsRmlsZSIsInJlbW90ZVBhdGgiLCJ1cGxvYWRPcHRpb25zIiwiXyIsImlzRW1wdHkiLCJ1dGlsIiwidG9Jbk1lbW9yeUJhc2U2NCIsInRvU3RyaW5nIiwidXNlciIsInBhc3MiLCJtZXRob2QiLCJoZWFkZXJzIiwiZmlsZUZpZWxkTmFtZSIsImZvcm1GaWVsZHMiLCJvcHRpb25zIiwiYXV0aCIsIm5ldCIsInVwbG9hZEZpbGUiLCJ2ZXJpZnlTY3JlZW5SZWNvcmRJc1N1cHBvcnRlZCIsImFkYiIsImlzRW11bGF0b3IiLCJhcGlMZXZlbCIsImdldEFwaUxldmVsIiwiRXJyb3IiLCJzY2hlZHVsZVNjcmVlblJlY29yZCIsInJlY29yZGluZ1Byb3BlcnRpZXMiLCJsb2ciLCJzdG9wcGVkIiwidGltZXIiLCJ2aWRlb1NpemUiLCJiaXRSYXRlIiwidGltZUxpbWl0IiwiYnVnUmVwb3J0IiwiY3VycmVudFRpbWVMaW1pdCIsImhhc1ZhbHVlIiwiY3VycmVudFRpbWVMaW1pdEludCIsInBhcnNlSW50IiwiaXNOYU4iLCJwYXRoT25EZXZpY2UiLCJ1dWlkVjQiLCJzdWJzdHJpbmciLCJyZWNvcmRpbmdQcm9jIiwic2NyZWVucmVjb3JkIiwib24iLCJjdXJyZW50RHVyYXRpb24iLCJnZXREdXJhdGlvbiIsImFzU2Vjb25kcyIsInRvRml4ZWQiLCJkZWJ1ZyIsInRpbWVMaW1pdEludCIsImNodW5rRHVyYXRpb24iLCJlIiwiZXJyb3IiLCJzdGFjayIsInN0YXJ0Iiwid2FpdEZvckNvbmRpdGlvbiIsImZpbGVFeGlzdHMiLCJ3YWl0TXMiLCJpbnRlcnZhbE1zIiwicmVjb3JkcyIsInB1c2giLCJyZWNvcmRpbmdQcm9jZXNzIiwibWVyZ2VTY3JlZW5SZWNvcmRzIiwibWVkaWFGaWxlcyIsImZzIiwid2hpY2giLCJjb25maWdDb250ZW50IiwibWFwIiwieCIsImpvaW4iLCJjb25maWdGaWxlIiwicGF0aCIsInJlc29sdmUiLCJkaXJuYW1lIiwid3JpdGVGaWxlIiwicmVzdWx0IiwiTWF0aCIsImZsb29yIiwiRGF0ZSIsImFyZ3MiLCJpbmZvIiwiZXhlYyIsInRlcm1pbmF0ZUJhY2tncm91bmRTY3JlZW5SZWNvcmRpbmciLCJmb3JjZSIsInBpZHMiLCJnZXRQSURzQnlOYW1lIiwicCIsInNoZWxsIiwiZXJyIiwibWVzc2FnZSIsInN0YXJ0UmVjb3JkaW5nU2NyZWVuIiwiZm9yY2VSZXN0YXJ0Iiwic3RvcFJlY29yZGluZ1NjcmVlbiIsIndhcm4iLCJfc2NyZWVuUmVjb3JkaW5nUHJvcGVydGllcyIsInJlY29yZCIsInJpbXJhZiIsInRpbWVvdXQiLCJwYXJzZUZsb2F0IiwidGltaW5nIiwiVGltZXIiLCJpc1J1bm5pbmciLCJzdG9wIiwiZXJyb3JBbmRUaHJvdyIsInRtcFJvb3QiLCJ0ZW1wRGlyIiwib3BlbkRpciIsImxvY2FsUmVjb3JkcyIsInBvc2l4IiwiYmFzZW5hbWUiLCJwdWxsIiwibGFzdCIsInJlc3VsdEZpbGVQYXRoIiwibGVuZ3RoIiwic2l6ZSIsInN0YXQiLCJ0b1JlYWRhYmxlU2l6ZVN0cmluZyJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9jb21tYW5kcy9yZWNvcmRzY3JlZW4uanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IHdhaXRGb3JDb25kaXRpb24gfSBmcm9tICdhc3luY2JveCc7XG5pbXBvcnQgeyB1dGlsLCBmcywgbmV0LCB0ZW1wRGlyLCBzeXN0ZW0sIHRpbWluZyB9IGZyb20gJ0BhcHBpdW0vc3VwcG9ydCc7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuXG5cbmNvbnN0IGNvbW1hbmRzID0ge307XG5cbmNvbnN0IFJFVFJZX1BBVVNFID0gMzAwO1xuY29uc3QgUkVUUllfVElNRU9VVCA9IDUwMDA7XG5jb25zdCBNQVhfUkVDT1JESU5HX1RJTUVfU0VDID0gNjAgKiAzO1xuY29uc3QgTUFYX1RJTUVfU0VDID0gNjAgKiAzMDtcbmNvbnN0IERFRkFVTFRfUkVDT1JESU5HX1RJTUVfU0VDID0gTUFYX1JFQ09SRElOR19USU1FX1NFQztcbmNvbnN0IFBST0NFU1NfU0hVVERPV05fVElNRU9VVCA9IDEwICogMTAwMDtcbmNvbnN0IFNDUkVFTlJFQ09SRF9CSU5BUlkgPSAnc2NyZWVucmVjb3JkJztcbmNvbnN0IERFRkFVTFRfRVhUID0gJy5tcDQnO1xuY29uc3QgTUlOX0VNVUxBVE9SX0FQSV9MRVZFTCA9IDI3O1xuY29uc3QgRkZNUEVHX0JJTkFSWSA9IGBmZm1wZWcke3N5c3RlbS5pc1dpbmRvd3MoKSA/ICcuZXhlJyA6ICcnfWA7XG5cbmFzeW5jIGZ1bmN0aW9uIHVwbG9hZFJlY29yZGVkTWVkaWEgKGxvY2FsRmlsZSwgcmVtb3RlUGF0aCA9IG51bGwsIHVwbG9hZE9wdGlvbnMgPSB7fSkge1xuICBpZiAoXy5pc0VtcHR5KHJlbW90ZVBhdGgpKSB7XG4gICAgcmV0dXJuIChhd2FpdCB1dGlsLnRvSW5NZW1vcnlCYXNlNjQobG9jYWxGaWxlKSkudG9TdHJpbmcoKTtcbiAgfVxuXG4gIGNvbnN0IHt1c2VyLCBwYXNzLCBtZXRob2QsIGhlYWRlcnMsIGZpbGVGaWVsZE5hbWUsIGZvcm1GaWVsZHN9ID0gdXBsb2FkT3B0aW9ucztcbiAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICBtZXRob2Q6IG1ldGhvZCB8fCAnUFVUJyxcbiAgICBoZWFkZXJzLFxuICAgIGZpbGVGaWVsZE5hbWUsXG4gICAgZm9ybUZpZWxkcyxcbiAgfTtcbiAgaWYgKHVzZXIgJiYgcGFzcykge1xuICAgIG9wdGlvbnMuYXV0aCA9IHt1c2VyLCBwYXNzfTtcbiAgfVxuICBhd2FpdCBuZXQudXBsb2FkRmlsZShsb2NhbEZpbGUsIHJlbW90ZVBhdGgsIG9wdGlvbnMpO1xuICByZXR1cm4gJyc7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHZlcmlmeVNjcmVlblJlY29yZElzU3VwcG9ydGVkIChhZGIsIGlzRW11bGF0b3IpIHtcbiAgY29uc3QgYXBpTGV2ZWwgPSBhd2FpdCBhZGIuZ2V0QXBpTGV2ZWwoKTtcbiAgaWYgKGlzRW11bGF0b3IgJiYgYXBpTGV2ZWwgPCBNSU5fRU1VTEFUT1JfQVBJX0xFVkVMKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBTY3JlZW4gcmVjb3JkaW5nIGRvZXMgbm90IHdvcmsgb24gZW11bGF0b3JzIHJ1bm5pbmcgQW5kcm9pZCBBUEkgbGV2ZWwgbGVzcyB0aGFuICR7TUlOX0VNVUxBVE9SX0FQSV9MRVZFTH1gKTtcbiAgfVxuICBpZiAoYXBpTGV2ZWwgPCAxOSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgU2NyZWVuIHJlY29yZGluZyBub3QgYXZhaWxhYmxlIG9uIEFQSSBMZXZlbCAke2FwaUxldmVsfS4gTWluaW11bSBBUEkgTGV2ZWwgaXMgMTkuYCk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gc2NoZWR1bGVTY3JlZW5SZWNvcmQgKGFkYiwgcmVjb3JkaW5nUHJvcGVydGllcywgbG9nID0gbnVsbCkge1xuICBpZiAocmVjb3JkaW5nUHJvcGVydGllcy5zdG9wcGVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3Qge1xuICAgIHRpbWVyLFxuICAgIHZpZGVvU2l6ZSxcbiAgICBiaXRSYXRlLFxuICAgIHRpbWVMaW1pdCxcbiAgICBidWdSZXBvcnQsXG4gIH0gPSByZWNvcmRpbmdQcm9wZXJ0aWVzO1xuXG4gIGxldCBjdXJyZW50VGltZUxpbWl0ID0gTUFYX1JFQ09SRElOR19USU1FX1NFQztcbiAgaWYgKHV0aWwuaGFzVmFsdWUocmVjb3JkaW5nUHJvcGVydGllcy5jdXJyZW50VGltZUxpbWl0KSkge1xuICAgIGNvbnN0IGN1cnJlbnRUaW1lTGltaXRJbnQgPSBwYXJzZUludChyZWNvcmRpbmdQcm9wZXJ0aWVzLmN1cnJlbnRUaW1lTGltaXQsIDEwKTtcbiAgICBpZiAoIWlzTmFOKGN1cnJlbnRUaW1lTGltaXRJbnQpICYmIGN1cnJlbnRUaW1lTGltaXRJbnQgPCBNQVhfUkVDT1JESU5HX1RJTUVfU0VDKSB7XG4gICAgICBjdXJyZW50VGltZUxpbWl0ID0gY3VycmVudFRpbWVMaW1pdEludDtcbiAgICB9XG4gIH1cbiAgY29uc3QgcGF0aE9uRGV2aWNlID0gYC9zZGNhcmQvJHt1dGlsLnV1aWRWNCgpLnN1YnN0cmluZygwLCA4KX0ke0RFRkFVTFRfRVhUfWA7XG4gIGNvbnN0IHJlY29yZGluZ1Byb2MgPSBhZGIuc2NyZWVucmVjb3JkKHBhdGhPbkRldmljZSwge1xuICAgIHZpZGVvU2l6ZSxcbiAgICBiaXRSYXRlLFxuICAgIHRpbWVMaW1pdDogY3VycmVudFRpbWVMaW1pdCxcbiAgICBidWdSZXBvcnQsXG4gIH0pO1xuXG4gIHJlY29yZGluZ1Byb2Mub24oJ2VuZCcsICgpID0+IHtcbiAgICBpZiAocmVjb3JkaW5nUHJvcGVydGllcy5zdG9wcGVkIHx8ICF1dGlsLmhhc1ZhbHVlKHRpbWVMaW1pdCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY3VycmVudER1cmF0aW9uID0gdGltZXIuZ2V0RHVyYXRpb24oKS5hc1NlY29uZHMudG9GaXhlZCgwKTtcbiAgICBsb2c/LmRlYnVnKGBUaGUgb3ZlcmFsbCBzY3JlZW4gcmVjb3JkaW5nIGR1cmF0aW9uIGlzICR7Y3VycmVudER1cmF0aW9ufXMgc28gZmFyYCk7XG4gICAgY29uc3QgdGltZUxpbWl0SW50ID0gcGFyc2VJbnQodGltZUxpbWl0LCAxMCk7XG4gICAgaWYgKGlzTmFOKHRpbWVMaW1pdEludCkgfHwgY3VycmVudER1cmF0aW9uID49IHRpbWVMaW1pdEludCkge1xuICAgICAgbG9nPy5kZWJ1ZygnVGhlcmUgaXMgbm8gbmVlZCB0byBzdGFydCB0aGUgbmV4dCByZWNvcmRpbmcgY2h1bmsnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICByZWNvcmRpbmdQcm9wZXJ0aWVzLmN1cnJlbnRUaW1lTGltaXQgPSB0aW1lTGltaXRJbnQgLSBjdXJyZW50RHVyYXRpb247XG4gICAgY29uc3QgY2h1bmtEdXJhdGlvbiA9IHJlY29yZGluZ1Byb3BlcnRpZXMuY3VycmVudFRpbWVMaW1pdCA8IE1BWF9SRUNPUkRJTkdfVElNRV9TRUNcbiAgICAgID8gcmVjb3JkaW5nUHJvcGVydGllcy5jdXJyZW50VGltZUxpbWl0XG4gICAgICA6IE1BWF9SRUNPUkRJTkdfVElNRV9TRUM7XG4gICAgbG9nPy5kZWJ1ZyhgU3RhcnRpbmcgdGhlIG5leHQgJHtjaHVua0R1cmF0aW9ufXMtY2h1bmsgYCArXG4gICAgICBgb2Ygc2NyZWVuIHJlY29yZGluZyBpbiBvcmRlciB0byBhY2hpZXZlICR7dGltZUxpbWl0SW50fXMgdG90YWwgZHVyYXRpb25gKTtcbiAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2NoZWR1bGVTY3JlZW5SZWNvcmQoYWRiLCByZWNvcmRpbmdQcm9wZXJ0aWVzLCBsb2cpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsb2c/LmVycm9yKGUuc3RhY2spO1xuICAgICAgICByZWNvcmRpbmdQcm9wZXJ0aWVzLnN0b3BwZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0pKCk7XG4gIH0pO1xuXG4gIGF3YWl0IHJlY29yZGluZ1Byb2Muc3RhcnQoMCk7XG4gIHRyeSB7XG4gICAgYXdhaXQgd2FpdEZvckNvbmRpdGlvbihhc3luYyAoKSA9PiBhd2FpdCBhZGIuZmlsZUV4aXN0cyhwYXRoT25EZXZpY2UpLFxuICAgICAge3dhaXRNczogUkVUUllfVElNRU9VVCwgaW50ZXJ2YWxNczogUkVUUllfUEFVU0V9KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVGhlIGV4cGVjdGVkIHNjcmVlbiByZWNvcmQgZmlsZSAnJHtwYXRoT25EZXZpY2V9JyBkb2VzIG5vdCBleGlzdCBhZnRlciAke1JFVFJZX1RJTUVPVVR9bXMuIGAgK1xuICAgICAgYElzICR7U0NSRUVOUkVDT1JEX0JJTkFSWX0gdXRpbGl0eSBhdmFpbGFibGUgYW5kIG9wZXJhdGlvbmFsIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdD9gKTtcbiAgfVxuXG4gIHJlY29yZGluZ1Byb3BlcnRpZXMucmVjb3Jkcy5wdXNoKHBhdGhPbkRldmljZSk7XG4gIHJlY29yZGluZ1Byb3BlcnRpZXMucmVjb3JkaW5nUHJvY2VzcyA9IHJlY29yZGluZ1Byb2M7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIG1lcmdlU2NyZWVuUmVjb3JkcyAobWVkaWFGaWxlcywgbG9nID0gbnVsbCkge1xuICB0cnkge1xuICAgIGF3YWl0IGZzLndoaWNoKEZGTVBFR19CSU5BUlkpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke0ZGTVBFR19CSU5BUll9IHV0aWxpdHkgaXMgbm90IGF2YWlsYWJsZSBpbiBQQVRILiBQbGVhc2UgaW5zdGFsbCBpdCBmcm9tIGh0dHBzOi8vd3d3LmZmbXBlZy5vcmcvYCk7XG4gIH1cbiAgY29uc3QgY29uZmlnQ29udGVudCA9IG1lZGlhRmlsZXNcbiAgICAubWFwKCh4KSA9PiBgZmlsZSAnJHt4fSdgKVxuICAgIC5qb2luKCdcXG4nKTtcbiAgY29uc3QgY29uZmlnRmlsZSA9IHBhdGgucmVzb2x2ZShwYXRoLmRpcm5hbWUobWVkaWFGaWxlc1swXSksICdjb25maWcudHh0Jyk7XG4gIGF3YWl0IGZzLndyaXRlRmlsZShjb25maWdGaWxlLCBjb25maWdDb250ZW50LCAndXRmOCcpO1xuICBsb2c/LmRlYnVnKGBHZW5lcmF0ZWQgZmZtcGVnIG1lcmdpbmcgY29uZmlnICcke2NvbmZpZ0ZpbGV9JyB3aXRoIGl0ZW1zOlxcbiR7Y29uZmlnQ29udGVudH1gKTtcbiAgY29uc3QgcmVzdWx0ID0gcGF0aC5yZXNvbHZlKHBhdGguZGlybmFtZShtZWRpYUZpbGVzWzBdKSwgYG1lcmdlXyR7TWF0aC5mbG9vcihuZXcgRGF0ZSgpKX0ke0RFRkFVTFRfRVhUfWApO1xuICBjb25zdCBhcmdzID0gWyctc2FmZScsICcwJywgJy1mJywgJ2NvbmNhdCcsICctaScsIGNvbmZpZ0ZpbGUsICctYycsICdjb3B5JywgcmVzdWx0XTtcbiAgbG9nPy5pbmZvKGBJbml0aWF0aW5nIHNjcmVlbiByZWNvcmRzIG1lcmdpbmcgdXNpbmcgdGhlIGNvbW1hbmQgJyR7RkZNUEVHX0JJTkFSWX0gJHthcmdzLmpvaW4oJyAnKX0nYCk7XG4gIGF3YWl0IGV4ZWMoRkZNUEVHX0JJTkFSWSwgYXJncyk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHRlcm1pbmF0ZUJhY2tncm91bmRTY3JlZW5SZWNvcmRpbmcgKGFkYiwgZm9yY2UgPSB0cnVlKSB7XG4gIGNvbnN0IHBpZHMgPSAoYXdhaXQgYWRiLmdldFBJRHNCeU5hbWUoU0NSRUVOUkVDT1JEX0JJTkFSWSkpXG4gICAgLm1hcCgocCkgPT4gYCR7cH1gKTtcbiAgaWYgKF8uaXNFbXB0eShwaWRzKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgYXdhaXQgYWRiLnNoZWxsKFsna2lsbCcsIGZvcmNlID8gJy0xNScgOiAnLTInLCAuLi5waWRzXSk7XG4gICAgYXdhaXQgd2FpdEZvckNvbmRpdGlvbihhc3luYyAoKSA9PiBfLmlzRW1wdHkoYXdhaXQgYWRiLmdldFBJRHNCeU5hbWUoU0NSRUVOUkVDT1JEX0JJTkFSWSkpLCB7XG4gICAgICB3YWl0TXM6IFBST0NFU1NfU0hVVERPV05fVElNRU9VVCxcbiAgICAgIGludGVydmFsTXM6IDUwMCxcbiAgICB9KTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gc3RvcCB0aGUgYmFja2dyb3VuZCBzY3JlZW4gcmVjb3JkaW5nOiAke2Vyci5tZXNzYWdlfWApO1xuICB9XG59XG5cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTdGFydFJlY29yZGluZ09wdGlvbnNcbiAqXG4gKiBAcHJvcGVydHkgez9zdHJpbmd9IHJlbW90ZVBhdGggLSBUaGUgcGF0aCB0byB0aGUgcmVtb3RlIGxvY2F0aW9uLCB3aGVyZSB0aGUgY2FwdHVyZWQgdmlkZW8gc2hvdWxkIGJlIHVwbG9hZGVkLlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhlIGZvbGxvd2luZyBwcm90b2NvbHMgYXJlIHN1cHBvcnRlZDogaHR0cC9odHRwcywgZnRwLlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVsbCBvciBlbXB0eSBzdHJpbmcgdmFsdWUgKHRoZSBkZWZhdWx0IHNldHRpbmcpIG1lYW5zIHRoZSBjb250ZW50IG9mIHJlc3VsdGluZ1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZSBzaG91bGQgYmUgZW5jb2RlZCBhcyBCYXNlNjQgYW5kIHBhc3NlZCBhcyB0aGUgZW5kcG91bnQgcmVzcG9uc2UgdmFsdWUuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24gaWYgdGhlIGdlbmVyYXRlZCBtZWRpYSBmaWxlIGlzIHRvbyBiaWcgdG9cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpdCBpbnRvIHRoZSBhdmFpbGFibGUgcHJvY2VzcyBtZW1vcnkuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzIG9wdGlvbiBvbmx5IGhhcyBhbiBlZmZlY3QgaWYgdGhlcmUgaXMgc2NyZWVuIHJlY29yZGluZyBwcm9jZXNzIGluIHByb2dyZWVzc1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIGBmb3JjZVJlc3RhcnRgIHBhcmFtZXRlciBpcyBub3Qgc2V0IHRvIGB0cnVlYC5cbiAqIEBwcm9wZXJ0eSB7P3N0cmluZ30gdXNlciAtIFRoZSBuYW1lIG9mIHRoZSB1c2VyIGZvciB0aGUgcmVtb3RlIGF1dGhlbnRpY2F0aW9uLiBPbmx5IHdvcmtzIGlmIGByZW1vdGVQYXRoYCBpcyBwcm92aWRlZC5cbiAqIEBwcm9wZXJ0eSB7P3N0cmluZ30gcGFzcyAtIFRoZSBwYXNzd29yZCBmb3IgdGhlIHJlbW90ZSBhdXRoZW50aWNhdGlvbi4gT25seSB3b3JrcyBpZiBgcmVtb3RlUGF0aGAgaXMgcHJvdmlkZWQuXG4gKiBAcHJvcGVydHkgez9zdHJpbmd9IG1ldGhvZCBbUFVUXSAtIFRoZSBodHRwIG11bHRpcGFydCB1cGxvYWQgbWV0aG9kIG5hbWUuIE9ubHkgd29ya3MgaWYgYHJlbW90ZVBhdGhgIGlzIHByb3ZpZGVkLlxuICogQHByb3BlcnR5IHs/T2JqZWN0fSBoZWFkZXJzIC0gQWRkaXRpb25hbCBoZWFkZXJzIG1hcHBpbmcgZm9yIG11bHRpcGFydCBodHRwKHMpIHVwbG9hZHNcbiAqIEBwcm9wZXJ0eSB7P3N0cmluZ30gZmlsZUZpZWxkTmFtZSBbZmlsZV0gLSBUaGUgbmFtZSBvZiB0aGUgZm9ybSBmaWVsZCwgd2hlcmUgdGhlIGZpbGUgY29udGVudCBCTE9CIHNob3VsZCBiZSBzdG9yZWQgZm9yXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHR0cChzKSB1cGxvYWRzXG4gKiBAcHJvcGVydHkgez9PYmplY3R8QXJyYXk8UGFpcj59IGZvcm1GaWVsZHMgLSBBZGRpdGlvbmFsIGZvcm0gZmllbGRzIGZvciBtdWx0aXBhcnQgaHR0cChzKSB1cGxvYWRzXG4gKiBAcHJvcGVydHkgez9zdHJpbmd9IHZpZGVvU2l6ZSAtIFRoZSBmb3JtYXQgaXMgd2lkdGh4aGVpZ2h0LlxuICogICAgICAgICAgICAgICAgICBUaGUgZGVmYXVsdCB2YWx1ZSBpcyB0aGUgZGV2aWNlJ3MgbmF0aXZlIGRpc3BsYXkgcmVzb2x1dGlvbiAoaWYgc3VwcG9ydGVkKSxcbiAqICAgICAgICAgICAgICAgICAgMTI4MHg3MjAgaWYgbm90LiBGb3IgYmVzdCByZXN1bHRzLFxuICogICAgICAgICAgICAgICAgICB1c2UgYSBzaXplIHN1cHBvcnRlZCBieSB5b3VyIGRldmljZSdzIEFkdmFuY2VkIFZpZGVvIENvZGluZyAoQVZDKSBlbmNvZGVyLlxuICogICAgICAgICAgICAgICAgICBGb3IgZXhhbXBsZSwgXCIxMjgweDcyMFwiXG4gKiBAcHJvcGVydHkgez9ib29sZWFufSBidWdSZXBvcnQgLSBTZXQgaXQgdG8gYHRydWVgIGluIG9yZGVyIHRvIGRpc3BsYXkgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvbiB0aGUgdmlkZW8gb3ZlcmxheSxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2ggYXMgYSB0aW1lc3RhbXAsIHRoYXQgaXMgaGVscGZ1bCBpbiB2aWRlb3MgY2FwdHVyZWQgdG8gaWxsdXN0cmF0ZSBidWdzLlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyBvcHRpb24gaXMgb25seSBzdXBwb3J0ZWQgc2luY2UgQVBJIGxldmVsIDI3IChBbmRyb2lkIFApLlxuICogQHByb3BlcnR5IHs/c3RyaW5nfG51bWJlcn0gdGltZUxpbWl0IC0gVGhlIG1heGltdW0gcmVjb3JkaW5nIHRpbWUsIGluIHNlY29uZHMuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIDE4MCAoMyBtaW51dGVzKS5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoZSBtYXhpbXVtIHZhbHVlIGlzIDE4MDAgKDMwIG1pbnV0ZXMpLiBJZiB0aGUgcGFzc2VkIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiAxODAgdGhlblxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGFsZ29yaXRobSB3aWxsIHRyeSB0byBzY2hlZHVsZSBtdWx0aXBsZSBzY3JlZW4gcmVjb3JkaW5nIGNodW5rcyBhbmQgbWVyZ2UgdGhlXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRpbmcgdmlkZW9zIGludG8gYSBzaW5nbGUgbWVkaWEgZmlsZSB1c2luZyBgZmZtcGVnYCB1dGlsaXR5LlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYgdGhlIHV0aWxpdHkgaXMgbm90IGF2YWlsYWJsZSBpbiBQQVRIIHRoZW4gdGhlIG1vc3QgcmVjZW50IHNjcmVlbiByZWNvcmRpbmcgY2h1bmsgaXNcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvaW5nIHRvIGJlIHJldHVybmVkLlxuICogQHByb3BlcnR5IHs/c3RyaW5nfG51bWJlcn0gYml0UmF0ZSAtIFRoZSB2aWRlbyBiaXQgcmF0ZSBmb3IgdGhlIHZpZGVvLCBpbiBiaXRzIHBlciBzZWNvbmQuXG4gKiAgICAgICAgICAgICAgICBUaGUgZGVmYXVsdCB2YWx1ZSBpcyA0MDAwMDAwICg0IE1iaXQvcykuIFlvdSBjYW4gaW5jcmVhc2UgdGhlIGJpdCByYXRlIHRvIGltcHJvdmUgdmlkZW8gcXVhbGl0eSxcbiAqICAgICAgICAgICAgICAgIGJ1dCBkb2luZyBzbyByZXN1bHRzIGluIGxhcmdlciBtb3ZpZSBmaWxlcy5cbiAqIEBwcm9wZXJ0eSB7P2Jvb2xlYW59IGZvcmNlUmVzdGFydCAtIFdoZXRoZXIgdG8gdHJ5IHRvIGNhdGNoIGFuZCB1cGxvYWQvcmV0dXJuIHRoZSBjdXJyZW50bHkgcnVubmluZyBzY3JlZW4gcmVjb3JkaW5nXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYGZhbHNlYCwgdGhlIGRlZmF1bHQgc2V0dGluZykgb3IgaWdub3JlIHRoZSByZXN1bHQgb2YgaXQgYW5kIHN0YXJ0IGEgbmV3IHJlY29yZGluZ1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1tZWRpYXRlbHkgKGB0cnVlYCkuXG4gKi9cblxuLyoqXG4gKiBSZWNvcmQgdGhlIGRpc3BsYXkgb2YgYSByZWFsIGRldmljZXMgcnVubmluZyBBbmRyb2lkIDQuNCAoQVBJIGxldmVsIDE5KSBhbmQgaGlnaGVyLlxuICogRW11bGF0b3JzIGFyZSBzdXBwb3J0ZWQgc2luY2UgQVBJIGxldmVsIDI3IChBbmRyb2lkIFApLlxuICogSXQgcmVjb3JkcyBzY3JlZW4gYWN0aXZpdHkgdG8gYW4gTVBFRy00IGZpbGUuIEF1ZGlvIGlzIG5vdCByZWNvcmRlZCB3aXRoIHRoZSB2aWRlbyBmaWxlLlxuICogSWYgc2NyZWVuIHJlY29yZGluZyBoYXMgYmVlbiBhbHJlYWR5IHN0YXJ0ZWQgdGhlbiB0aGUgY29tbWFuZCB3aWxsIHN0b3AgaXQgZm9yY2VmdWxseSBhbmQgc3RhcnQgYSBuZXcgb25lLlxuICogVGhlIHByZXZpb3VzbHkgcmVjb3JkZWQgdmlkZW8gZmlsZSB3aWxsIGJlIGRlbGV0ZWQuXG4gKlxuICogQHBhcmFtIHs/U3RhcnRSZWNvcmRpbmdPcHRpb25zfSBvcHRpb25zIC0gVGhlIGF2YWlsYWJsZSBvcHRpb25zLlxuICogQHJldHVybnMge3N0cmluZ30gQmFzZTY0LWVuY29kZWQgY29udGVudCBvZiB0aGUgcmVjb3JkZWQgbWVkaWEgZmlsZSBpZlxuICogICAgICAgICAgICAgICAgICAgYW55IHNjcmVlbiByZWNvcmRpbmcgaXMgY3VycmVudGx5IHJ1bm5pbmcgb3IgYW4gZW1wdHkgc3RyaW5nLlxuICogQHRocm93cyB7RXJyb3J9IElmIHNjcmVlbiByZWNvcmRpbmcgaGFzIGZhaWxlZCB0byBzdGFydCBvciBpcyBub3Qgc3VwcG9ydGVkIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqL1xuY29tbWFuZHMuc3RhcnRSZWNvcmRpbmdTY3JlZW4gPSBhc3luYyBmdW5jdGlvbiBzdGFydFJlY29yZGluZ1NjcmVlbiAob3B0aW9ucyA9IHt9KSB7XG4gIGF3YWl0IHZlcmlmeVNjcmVlblJlY29yZElzU3VwcG9ydGVkKHRoaXMuYWRiLCB0aGlzLmlzRW11bGF0b3IoKSk7XG5cbiAgbGV0IHJlc3VsdCA9ICcnO1xuICBjb25zdCB7dmlkZW9TaXplLCB0aW1lTGltaXQgPSBERUZBVUxUX1JFQ09SRElOR19USU1FX1NFQywgYnVnUmVwb3J0LCBiaXRSYXRlLCBmb3JjZVJlc3RhcnR9ID0gb3B0aW9ucztcbiAgaWYgKCFmb3JjZVJlc3RhcnQpIHtcbiAgICByZXN1bHQgPSBhd2FpdCB0aGlzLnN0b3BSZWNvcmRpbmdTY3JlZW4ob3B0aW9ucyk7XG4gIH1cblxuICBpZiAoYXdhaXQgdGVybWluYXRlQmFja2dyb3VuZFNjcmVlblJlY29yZGluZyh0aGlzLmFkYiwgdHJ1ZSkpIHtcbiAgICB0aGlzLmxvZy53YXJuKGBUaGVyZSB3ZXJlIHNvbWUgJHtTQ1JFRU5SRUNPUkRfQklOQVJZfSBwcm9jZXNzIGxlZnRvdmVycyBydW5uaW5nIGAgK1xuICAgICAgYGluIHRoZSBiYWNrZ3JvdW5kLiBNYWtlIHN1cmUgeW91IHN0b3Agc2NyZWVuIHJlY29yZGluZyBlYWNoIHRpbWUgYWZ0ZXIgaXQgaXMgc3RhcnRlZCwgYCArXG4gICAgICBgb3RoZXJ3aXNlIHRoZSByZWNvcmRlZCBtZWRpYSBtaWdodCBxdWlja2x5IGV4Y2VlZCBhbGwgdGhlIGZyZWUgc3BhY2Ugb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LmApO1xuICB9XG5cbiAgaWYgKCFfLmlzRW1wdHkodGhpcy5fc2NyZWVuUmVjb3JkaW5nUHJvcGVydGllcykpIHtcbiAgICBmb3IgKGNvbnN0IHJlY29yZCBvZiAodGhpcy5fc2NyZWVuUmVjb3JkaW5nUHJvcGVydGllcy5yZWNvcmRzIHx8IFtdKSkge1xuICAgICAgYXdhaXQgdGhpcy5hZGIucmltcmFmKHJlY29yZCk7XG4gICAgfVxuICAgIHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMgPSBudWxsO1xuICB9XG5cbiAgY29uc3QgdGltZW91dCA9IHBhcnNlRmxvYXQodGltZUxpbWl0KTtcbiAgaWYgKGlzTmFOKHRpbWVvdXQpIHx8IHRpbWVvdXQgPiBNQVhfVElNRV9TRUMgfHwgdGltZW91dCA8PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgdGltZUxpbWl0IHZhbHVlIG11c3QgYmUgaW4gcmFuZ2UgWzEsICR7TUFYX1RJTUVfU0VDfV0gc2Vjb25kcy4gYCArXG4gICAgICBgVGhlIHZhbHVlIG9mICcke3RpbWVMaW1pdH0nIGhhcyBiZWVuIHBhc3NlZCBpbnN0ZWFkLmApO1xuICB9XG5cbiAgdGhpcy5fc2NyZWVuUmVjb3JkaW5nUHJvcGVydGllcyA9IHtcbiAgICB0aW1lcjogbmV3IHRpbWluZy5UaW1lcigpLnN0YXJ0KCksXG4gICAgdmlkZW9TaXplLFxuICAgIHRpbWVMaW1pdCxcbiAgICBjdXJyZW50VGltZUxpbWl0OiB0aW1lTGltaXQsXG4gICAgYml0UmF0ZSxcbiAgICBidWdSZXBvcnQsXG4gICAgcmVjb3JkczogW10sXG4gICAgcmVjb3JkaW5nUHJvY2VzczogbnVsbCxcbiAgICBzdG9wcGVkOiBmYWxzZSxcbiAgfTtcbiAgYXdhaXQgc2NoZWR1bGVTY3JlZW5SZWNvcmQodGhpcy5hZGIsIHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMsIHRoaXMubG9nKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gU3RvcFJlY29yZGluZ09wdGlvbnNcbiAqXG4gKiBAcHJvcGVydHkgez9zdHJpbmd9IHJlbW90ZVBhdGggLSBUaGUgcGF0aCB0byB0aGUgcmVtb3RlIGxvY2F0aW9uLCB3aGVyZSB0aGUgcmVzdWx0aW5nIHZpZGVvIHNob3VsZCBiZSB1cGxvYWRlZC5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoZSBmb2xsb3dpbmcgcHJvdG9jb2xzIGFyZSBzdXBwb3J0ZWQ6IGh0dHAvaHR0cHMsIGZ0cC5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE51bGwgb3IgZW1wdHkgc3RyaW5nIHZhbHVlICh0aGUgZGVmYXVsdCBzZXR0aW5nKSBtZWFucyB0aGUgY29udGVudCBvZiByZXN1bHRpbmdcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUgc2hvdWxkIGJlIGVuY29kZWQgYXMgQmFzZTY0IGFuZCBwYXNzZWQgYXMgdGhlIGVuZHBvdW50IHJlc3BvbnNlIHZhbHVlLlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQW4gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duIGlmIHRoZSBnZW5lcmF0ZWQgbWVkaWEgZmlsZSBpcyB0b28gYmlnIHRvXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXQgaW50byB0aGUgYXZhaWxhYmxlIHByb2Nlc3MgbWVtb3J5LlxuICogQHByb3BlcnR5IHs/c3RyaW5nfSB1c2VyIC0gVGhlIG5hbWUgb2YgdGhlIHVzZXIgZm9yIHRoZSByZW1vdGUgYXV0aGVudGljYXRpb24uXG4gKiBAcHJvcGVydHkgez9zdHJpbmd9IHBhc3MgLSBUaGUgcGFzc3dvcmQgZm9yIHRoZSByZW1vdGUgYXV0aGVudGljYXRpb24uXG4gKiBAcHJvcGVydHkgez9zdHJpbmd9IG1ldGhvZCAtIFRoZSBodHRwIG11bHRpcGFydCB1cGxvYWQgbWV0aG9kIG5hbWUuIFRoZSAnUFVUJyBvbmUgaXMgdXNlZCBieSBkZWZhdWx0LlxuICogQHByb3BlcnR5IHs/T2JqZWN0fSBoZWFkZXJzIC0gQWRkaXRpb25hbCBoZWFkZXJzIG1hcHBpbmcgZm9yIG11bHRpcGFydCBodHRwKHMpIHVwbG9hZHNcbiAqIEBwcm9wZXJ0eSB7P3N0cmluZ30gZmlsZUZpZWxkTmFtZSBbZmlsZV0gLSBUaGUgbmFtZSBvZiB0aGUgZm9ybSBmaWVsZCwgd2hlcmUgdGhlIGZpbGUgY29udGVudCBCTE9CIHNob3VsZCBiZSBzdG9yZWQgZm9yXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHR0cChzKSB1cGxvYWRzXG4gKiBAcHJvcGVydHkgez9PYmplY3R8QXJyYXk8UGFpcj59IGZvcm1GaWVsZHMgLSBBZGRpdGlvbmFsIGZvcm0gZmllbGRzIGZvciBtdWx0aXBhcnQgaHR0cChzKSB1cGxvYWRzXG4gKi9cblxuLyoqXG4gKiBTdG9wIHJlY29yZGluZyB0aGUgc2NyZWVuLlxuICogSWYgbm8gc2NyZWVuIHJlY29yZGluZyBoYXMgYmVlbiBzdGFydGVkIGJlZm9yZSB0aGVuIHRoZSBtZXRob2QgcmV0dXJucyBhbiBlbXB0eSBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHs/U3RvcFJlY29yZGluZ09wdGlvbnN9IG9wdGlvbnMgLSBUaGUgYXZhaWxhYmxlIG9wdGlvbnMuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBCYXNlNjQtZW5jb2RlZCBjb250ZW50IG9mIHRoZSByZWNvcmRlZCBtZWRpYSBmaWxlIGlmICdyZW1vdGVQYXRoJ1xuICogICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyIGlzIGZhbHN5IG9yIGFuIGVtcHR5IHN0cmluZy5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGVyZSB3YXMgYW4gZXJyb3Igd2hpbGUgZ2V0dGluZyB0aGUgbmFtZSBvZiBhIG1lZGlhIGZpbGVcbiAqICAgICAgICAgICAgICAgICBvciB0aGUgZmlsZSBjb250ZW50IGNhbm5vdCBiZSB1cGxvYWRlZCB0byB0aGUgcmVtb3RlIGxvY2F0aW9uXG4gKiAgICAgICAgICAgICAgICAgb3Igc2NyZWVuIHJlY29yZGluZyBpcyBub3Qgc3VwcG9ydGVkIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqL1xuY29tbWFuZHMuc3RvcFJlY29yZGluZ1NjcmVlbiA9IGFzeW5jIGZ1bmN0aW9uIHN0b3BSZWNvcmRpbmdTY3JlZW4gKG9wdGlvbnMgPSB7fSkge1xuICBhd2FpdCB2ZXJpZnlTY3JlZW5SZWNvcmRJc1N1cHBvcnRlZCh0aGlzLmFkYiwgdGhpcy5pc0VtdWxhdG9yKCkpO1xuXG4gIGlmICghXy5pc0VtcHR5KHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMpKSB7XG4gICAgdGhpcy5fc2NyZWVuUmVjb3JkaW5nUHJvcGVydGllcy5zdG9wcGVkID0gdHJ1ZTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgYXdhaXQgdGVybWluYXRlQmFja2dyb3VuZFNjcmVlblJlY29yZGluZyh0aGlzLmFkYiwgZmFsc2UpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aGlzLmxvZy53YXJuKGVyci5tZXNzYWdlKTtcbiAgICBpZiAoIV8uaXNFbXB0eSh0aGlzLl9zY3JlZW5SZWNvcmRpbmdQcm9wZXJ0aWVzKSkge1xuICAgICAgdGhpcy5sb2cud2FybignVGhlIHJlc3VsdGluZyB2aWRlbyBtaWdodCBiZSBjb3JydXB0ZWQnKTtcbiAgICB9XG4gIH1cblxuICBpZiAoXy5pc0VtcHR5KHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMpKSB7XG4gICAgdGhpcy5sb2cuaW5mbyhgU2NyZWVuIHJlY29yZGluZyBoYXMgbm90IGJlZW4gcHJldmlvdXNseSBzdGFydGVkIGJ5IEFwcGl1bS4gVGhlcmUgaXMgbm90aGluZyB0byBzdG9wYCk7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgaWYgKHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMucmVjb3JkaW5nUHJvY2VzcyAmJiB0aGlzLl9zY3JlZW5SZWNvcmRpbmdQcm9wZXJ0aWVzLnJlY29yZGluZ1Byb2Nlc3MuaXNSdW5uaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMucmVjb3JkaW5nUHJvY2Vzcy5zdG9wKCdTSUdJTlQnLCBQUk9DRVNTX1NIVVRET1dOX1RJTUVPVVQpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMubG9nLmVycm9yQW5kVGhyb3coYFVuYWJsZSB0byBzdG9wIHNjcmVlbiByZWNvcmRpbmcgd2l0aGluICR7UFJPQ0VTU19TSFVURE9XTl9USU1FT1VUfW1zYCk7XG4gICAgfVxuICAgIHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMucmVjb3JkaW5nUHJvY2VzcyA9IG51bGw7XG4gIH1cblxuICBpZiAoXy5pc0VtcHR5KHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMucmVjb3JkcykpIHtcbiAgICB0aGlzLmxvZy5lcnJvckFuZFRocm93KGBObyBzY3JlZW4gcmVjb3JkaW5ncyBoYXZlIGJlZW4gc3RvcmVkIG9uIHRoZSBkZXZpY2Ugc28gZmFyLiBgICtcbiAgICAgIGBBcmUgeW91IHN1cmUgdGhlICR7U0NSRUVOUkVDT1JEX0JJTkFSWX0gdXRpbGl0eSB3b3JrcyBhcyBleHBlY3RlZD9gKTtcbiAgfVxuXG4gIGNvbnN0IHRtcFJvb3QgPSBhd2FpdCB0ZW1wRGlyLm9wZW5EaXIoKTtcbiAgdHJ5IHtcbiAgICBjb25zdCBsb2NhbFJlY29yZHMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IHBhdGhPbkRldmljZSBvZiB0aGlzLl9zY3JlZW5SZWNvcmRpbmdQcm9wZXJ0aWVzLnJlY29yZHMpIHtcbiAgICAgIGxvY2FsUmVjb3Jkcy5wdXNoKHBhdGgucmVzb2x2ZSh0bXBSb290LCBwYXRoLnBvc2l4LmJhc2VuYW1lKHBhdGhPbkRldmljZSkpKTtcbiAgICAgIGF3YWl0IHRoaXMuYWRiLnB1bGwocGF0aE9uRGV2aWNlLCBfLmxhc3QobG9jYWxSZWNvcmRzKSk7XG4gICAgICBhd2FpdCB0aGlzLmFkYi5yaW1yYWYocGF0aE9uRGV2aWNlKTtcbiAgICB9XG4gICAgbGV0IHJlc3VsdEZpbGVQYXRoID0gXy5sYXN0KGxvY2FsUmVjb3Jkcyk7XG4gICAgaWYgKGxvY2FsUmVjb3Jkcy5sZW5ndGggPiAxKSB7XG4gICAgICB0aGlzLmxvZy5pbmZvKGBHb3QgJHtsb2NhbFJlY29yZHMubGVuZ3RofSBzY3JlZW4gcmVjb3JkaW5ncy4gVHJ5aW5nIHRvIG1lcmdlIHRoZW1gKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlc3VsdEZpbGVQYXRoID0gYXdhaXQgbWVyZ2VTY3JlZW5SZWNvcmRzKGxvY2FsUmVjb3JkcywgdGhpcy5sb2cpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aGlzLmxvZy53YXJuKGBDYW5ub3QgbWVyZ2UgdGhlIHJlY29yZGVkIGZpbGVzLiBUaGUgbW9zdCByZWNlbnQgc2NyZWVuIHJlY29yZGluZyBpcyBnb2luZyB0byBiZSByZXR1cm5lZCBhcyB0aGUgcmVzdWx0LiBgICtcbiAgICAgICAgICBgT3JpZ2luYWwgZXJyb3I6ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoXy5pc0VtcHR5KG9wdGlvbnMucmVtb3RlUGF0aCkpIHtcbiAgICAgIGNvbnN0IHtzaXplfSA9IGF3YWl0IGZzLnN0YXQocmVzdWx0RmlsZVBhdGgpO1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFRoZSBzaXplIG9mIHRoZSByZXN1bHRpbmcgc2NyZWVuIHJlY29yZGluZyBpcyAke3V0aWwudG9SZWFkYWJsZVNpemVTdHJpbmcoc2l6ZSl9YCk7XG4gICAgfVxuICAgIHJldHVybiBhd2FpdCB1cGxvYWRSZWNvcmRlZE1lZGlhKHJlc3VsdEZpbGVQYXRoLCBvcHRpb25zLnJlbW90ZVBhdGgsIG9wdGlvbnMpO1xuICB9IGZpbmFsbHkge1xuICAgIGF3YWl0IGZzLnJpbXJhZih0bXBSb290KTtcbiAgICB0aGlzLl9zY3JlZW5SZWNvcmRpbmdQcm9wZXJ0aWVzID0gbnVsbDtcbiAgfVxufTtcblxuXG5leHBvcnQgeyBjb21tYW5kcyB9O1xuZXhwb3J0IGRlZmF1bHQgY29tbWFuZHM7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBLE1BQU1BLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFBQztBQUVwQixNQUFNQyxXQUFXLEdBQUcsR0FBRztBQUN2QixNQUFNQyxhQUFhLEdBQUcsSUFBSTtBQUMxQixNQUFNQyxzQkFBc0IsR0FBRyxFQUFF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
253
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjb21tYW5kcyIsIlJFVFJZX1BBVVNFIiwiUkVUUllfVElNRU9VVCIsIk1BWF9SRUNPUkRJTkdfVElNRV9TRUMiLCJNQVhfVElNRV9TRUMiLCJERUZBVUxUX1JFQ09SRElOR19USU1FX1NFQyIsIlBST0NFU1NfU0hVVERPV05fVElNRU9VVCIsIlNDUkVFTlJFQ09SRF9CSU5BUlkiLCJERUZBVUxUX0VYVCIsIk1JTl9FTVVMQVRPUl9BUElfTEVWRUwiLCJGRk1QRUdfQklOQVJZIiwic3lzdGVtIiwiaXNXaW5kb3dzIiwidXBsb2FkUmVjb3JkZWRNZWRpYSIsImxvY2FsRmlsZSIsInJlbW90ZVBhdGgiLCJ1cGxvYWRPcHRpb25zIiwiXyIsImlzRW1wdHkiLCJ1dGlsIiwidG9Jbk1lbW9yeUJhc2U2NCIsInRvU3RyaW5nIiwidXNlciIsInBhc3MiLCJtZXRob2QiLCJoZWFkZXJzIiwiZmlsZUZpZWxkTmFtZSIsImZvcm1GaWVsZHMiLCJvcHRpb25zIiwiYXV0aCIsIm5ldCIsInVwbG9hZEZpbGUiLCJ2ZXJpZnlTY3JlZW5SZWNvcmRJc1N1cHBvcnRlZCIsImFkYiIsImlzRW11bGF0b3IiLCJhcGlMZXZlbCIsImdldEFwaUxldmVsIiwiRXJyb3IiLCJzY2hlZHVsZVNjcmVlblJlY29yZCIsInJlY29yZGluZ1Byb3BlcnRpZXMiLCJsb2ciLCJzdG9wcGVkIiwidGltZXIiLCJ2aWRlb1NpemUiLCJiaXRSYXRlIiwidGltZUxpbWl0IiwiYnVnUmVwb3J0IiwiY3VycmVudFRpbWVMaW1pdCIsImhhc1ZhbHVlIiwiY3VycmVudFRpbWVMaW1pdEludCIsInBhcnNlSW50IiwiaXNOYU4iLCJwYXRoT25EZXZpY2UiLCJ1dWlkVjQiLCJzdWJzdHJpbmciLCJyZWNvcmRpbmdQcm9jIiwic2NyZWVucmVjb3JkIiwib24iLCJjdXJyZW50RHVyYXRpb24iLCJnZXREdXJhdGlvbiIsImFzU2Vjb25kcyIsInRvRml4ZWQiLCJkZWJ1ZyIsInRpbWVMaW1pdEludCIsImNodW5rRHVyYXRpb24iLCJlIiwiZXJyb3IiLCJzdGFjayIsInN0YXJ0Iiwid2FpdEZvckNvbmRpdGlvbiIsImZpbGVFeGlzdHMiLCJ3YWl0TXMiLCJpbnRlcnZhbE1zIiwicmVjb3JkcyIsInB1c2giLCJyZWNvcmRpbmdQcm9jZXNzIiwibWVyZ2VTY3JlZW5SZWNvcmRzIiwibWVkaWFGaWxlcyIsImZzIiwid2hpY2giLCJjb25maWdDb250ZW50IiwibWFwIiwieCIsImpvaW4iLCJjb25maWdGaWxlIiwicGF0aCIsInJlc29sdmUiLCJkaXJuYW1lIiwid3JpdGVGaWxlIiwicmVzdWx0IiwiTWF0aCIsImZsb29yIiwiRGF0ZSIsImFyZ3MiLCJpbmZvIiwiZXhlYyIsInRlcm1pbmF0ZUJhY2tncm91bmRTY3JlZW5SZWNvcmRpbmciLCJmb3JjZSIsInBpZHMiLCJnZXRQSURzQnlOYW1lIiwicCIsInNoZWxsIiwiZXJyIiwibWVzc2FnZSIsInN0YXJ0UmVjb3JkaW5nU2NyZWVuIiwiZm9yY2VSZXN0YXJ0Iiwic3RvcFJlY29yZGluZ1NjcmVlbiIsIndhcm4iLCJfc2NyZWVuUmVjb3JkaW5nUHJvcGVydGllcyIsInJlY29yZCIsInJpbXJhZiIsInRpbWVvdXQiLCJwYXJzZUZsb2F0IiwidGltaW5nIiwiVGltZXIiLCJpc1J1bm5pbmciLCJzdG9wIiwiZXJyb3JBbmRUaHJvdyIsInRtcFJvb3QiLCJ0ZW1wRGlyIiwib3BlbkRpciIsImxvY2FsUmVjb3JkcyIsInBvc2l4IiwiYmFzZW5hbWUiLCJwdWxsIiwibGFzdCIsInJlc3VsdEZpbGVQYXRoIiwibGVuZ3RoIiwic2l6ZSIsInN0YXQiLCJ0b1JlYWRhYmxlU2l6ZVN0cmluZyJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9jb21tYW5kcy9yZWNvcmRzY3JlZW4uanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IHdhaXRGb3JDb25kaXRpb24gfSBmcm9tICdhc3luY2JveCc7XG5pbXBvcnQgeyB1dGlsLCBmcywgbmV0LCB0ZW1wRGlyLCBzeXN0ZW0sIHRpbWluZyB9IGZyb20gJ0BhcHBpdW0vc3VwcG9ydCc7XG5pbXBvcnQgeyBleGVjIH0gZnJvbSAndGVlbl9wcm9jZXNzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuXG5cbmNvbnN0IGNvbW1hbmRzID0ge307XG5cbmNvbnN0IFJFVFJZX1BBVVNFID0gMzAwO1xuY29uc3QgUkVUUllfVElNRU9VVCA9IDUwMDA7XG5jb25zdCBNQVhfUkVDT1JESU5HX1RJTUVfU0VDID0gNjAgKiAzO1xuY29uc3QgTUFYX1RJTUVfU0VDID0gNjAgKiAzMDtcbmNvbnN0IERFRkFVTFRfUkVDT1JESU5HX1RJTUVfU0VDID0gTUFYX1JFQ09SRElOR19USU1FX1NFQztcbmNvbnN0IFBST0NFU1NfU0hVVERPV05fVElNRU9VVCA9IDEwICogMTAwMDtcbmNvbnN0IFNDUkVFTlJFQ09SRF9CSU5BUlkgPSAnc2NyZWVucmVjb3JkJztcbmNvbnN0IERFRkFVTFRfRVhUID0gJy5tcDQnO1xuY29uc3QgTUlOX0VNVUxBVE9SX0FQSV9MRVZFTCA9IDI3O1xuY29uc3QgRkZNUEVHX0JJTkFSWSA9IGBmZm1wZWcke3N5c3RlbS5pc1dpbmRvd3MoKSA/ICcuZXhlJyA6ICcnfWA7XG5cbmFzeW5jIGZ1bmN0aW9uIHVwbG9hZFJlY29yZGVkTWVkaWEgKGxvY2FsRmlsZSwgcmVtb3RlUGF0aCA9IG51bGwsIHVwbG9hZE9wdGlvbnMgPSB7fSkge1xuICBpZiAoXy5pc0VtcHR5KHJlbW90ZVBhdGgpKSB7XG4gICAgcmV0dXJuIChhd2FpdCB1dGlsLnRvSW5NZW1vcnlCYXNlNjQobG9jYWxGaWxlKSkudG9TdHJpbmcoKTtcbiAgfVxuXG4gIGNvbnN0IHt1c2VyLCBwYXNzLCBtZXRob2QsIGhlYWRlcnMsIGZpbGVGaWVsZE5hbWUsIGZvcm1GaWVsZHN9ID0gdXBsb2FkT3B0aW9ucztcbiAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICBtZXRob2Q6IG1ldGhvZCB8fCAnUFVUJyxcbiAgICBoZWFkZXJzLFxuICAgIGZpbGVGaWVsZE5hbWUsXG4gICAgZm9ybUZpZWxkcyxcbiAgfTtcbiAgaWYgKHVzZXIgJiYgcGFzcykge1xuICAgIG9wdGlvbnMuYXV0aCA9IHt1c2VyLCBwYXNzfTtcbiAgfVxuICBhd2FpdCBuZXQudXBsb2FkRmlsZShsb2NhbEZpbGUsIHJlbW90ZVBhdGgsIG9wdGlvbnMpO1xuICByZXR1cm4gJyc7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHZlcmlmeVNjcmVlblJlY29yZElzU3VwcG9ydGVkIChhZGIsIGlzRW11bGF0b3IpIHtcbiAgY29uc3QgYXBpTGV2ZWwgPSBhd2FpdCBhZGIuZ2V0QXBpTGV2ZWwoKTtcbiAgaWYgKGlzRW11bGF0b3IgJiYgYXBpTGV2ZWwgPCBNSU5fRU1VTEFUT1JfQVBJX0xFVkVMKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBTY3JlZW4gcmVjb3JkaW5nIGRvZXMgbm90IHdvcmsgb24gZW11bGF0b3JzIHJ1bm5pbmcgQW5kcm9pZCBBUEkgbGV2ZWwgbGVzcyB0aGFuICR7TUlOX0VNVUxBVE9SX0FQSV9MRVZFTH1gKTtcbiAgfVxuICBpZiAoYXBpTGV2ZWwgPCAxOSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgU2NyZWVuIHJlY29yZGluZyBub3QgYXZhaWxhYmxlIG9uIEFQSSBMZXZlbCAke2FwaUxldmVsfS4gTWluaW11bSBBUEkgTGV2ZWwgaXMgMTkuYCk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gc2NoZWR1bGVTY3JlZW5SZWNvcmQgKGFkYiwgcmVjb3JkaW5nUHJvcGVydGllcywgbG9nID0gbnVsbCkge1xuICBpZiAocmVjb3JkaW5nUHJvcGVydGllcy5zdG9wcGVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3Qge1xuICAgIHRpbWVyLFxuICAgIHZpZGVvU2l6ZSxcbiAgICBiaXRSYXRlLFxuICAgIHRpbWVMaW1pdCxcbiAgICBidWdSZXBvcnQsXG4gIH0gPSByZWNvcmRpbmdQcm9wZXJ0aWVzO1xuXG4gIGxldCBjdXJyZW50VGltZUxpbWl0ID0gTUFYX1JFQ09SRElOR19USU1FX1NFQztcbiAgaWYgKHV0aWwuaGFzVmFsdWUocmVjb3JkaW5nUHJvcGVydGllcy5jdXJyZW50VGltZUxpbWl0KSkge1xuICAgIGNvbnN0IGN1cnJlbnRUaW1lTGltaXRJbnQgPSBwYXJzZUludChyZWNvcmRpbmdQcm9wZXJ0aWVzLmN1cnJlbnRUaW1lTGltaXQsIDEwKTtcbiAgICBpZiAoIWlzTmFOKGN1cnJlbnRUaW1lTGltaXRJbnQpICYmIGN1cnJlbnRUaW1lTGltaXRJbnQgPCBNQVhfUkVDT1JESU5HX1RJTUVfU0VDKSB7XG4gICAgICBjdXJyZW50VGltZUxpbWl0ID0gY3VycmVudFRpbWVMaW1pdEludDtcbiAgICB9XG4gIH1cbiAgY29uc3QgcGF0aE9uRGV2aWNlID0gYC9zZGNhcmQvJHt1dGlsLnV1aWRWNCgpLnN1YnN0cmluZygwLCA4KX0ke0RFRkFVTFRfRVhUfWA7XG4gIGNvbnN0IHJlY29yZGluZ1Byb2MgPSBhZGIuc2NyZWVucmVjb3JkKHBhdGhPbkRldmljZSwge1xuICAgIHZpZGVvU2l6ZSxcbiAgICBiaXRSYXRlLFxuICAgIHRpbWVMaW1pdDogY3VycmVudFRpbWVMaW1pdCxcbiAgICBidWdSZXBvcnQsXG4gIH0pO1xuXG4gIHJlY29yZGluZ1Byb2Mub24oJ2VuZCcsICgpID0+IHtcbiAgICBpZiAocmVjb3JkaW5nUHJvcGVydGllcy5zdG9wcGVkIHx8ICF1dGlsLmhhc1ZhbHVlKHRpbWVMaW1pdCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY3VycmVudER1cmF0aW9uID0gdGltZXIuZ2V0RHVyYXRpb24oKS5hc1NlY29uZHMudG9GaXhlZCgwKTtcbiAgICBsb2c/LmRlYnVnKGBUaGUgb3ZlcmFsbCBzY3JlZW4gcmVjb3JkaW5nIGR1cmF0aW9uIGlzICR7Y3VycmVudER1cmF0aW9ufXMgc28gZmFyYCk7XG4gICAgY29uc3QgdGltZUxpbWl0SW50ID0gcGFyc2VJbnQodGltZUxpbWl0LCAxMCk7XG4gICAgaWYgKGlzTmFOKHRpbWVMaW1pdEludCkgfHwgY3VycmVudER1cmF0aW9uID49IHRpbWVMaW1pdEludCkge1xuICAgICAgbG9nPy5kZWJ1ZygnVGhlcmUgaXMgbm8gbmVlZCB0byBzdGFydCB0aGUgbmV4dCByZWNvcmRpbmcgY2h1bmsnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICByZWNvcmRpbmdQcm9wZXJ0aWVzLmN1cnJlbnRUaW1lTGltaXQgPSB0aW1lTGltaXRJbnQgLSBjdXJyZW50RHVyYXRpb247XG4gICAgY29uc3QgY2h1bmtEdXJhdGlvbiA9IHJlY29yZGluZ1Byb3BlcnRpZXMuY3VycmVudFRpbWVMaW1pdCA8IE1BWF9SRUNPUkRJTkdfVElNRV9TRUNcbiAgICAgID8gcmVjb3JkaW5nUHJvcGVydGllcy5jdXJyZW50VGltZUxpbWl0XG4gICAgICA6IE1BWF9SRUNPUkRJTkdfVElNRV9TRUM7XG4gICAgbG9nPy5kZWJ1ZyhgU3RhcnRpbmcgdGhlIG5leHQgJHtjaHVua0R1cmF0aW9ufXMtY2h1bmsgYCArXG4gICAgICBgb2Ygc2NyZWVuIHJlY29yZGluZyBpbiBvcmRlciB0byBhY2hpZXZlICR7dGltZUxpbWl0SW50fXMgdG90YWwgZHVyYXRpb25gKTtcbiAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2NoZWR1bGVTY3JlZW5SZWNvcmQoYWRiLCByZWNvcmRpbmdQcm9wZXJ0aWVzLCBsb2cpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsb2c/LmVycm9yKGUuc3RhY2spO1xuICAgICAgICByZWNvcmRpbmdQcm9wZXJ0aWVzLnN0b3BwZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH0pKCk7XG4gIH0pO1xuXG4gIGF3YWl0IHJlY29yZGluZ1Byb2Muc3RhcnQoMCk7XG4gIHRyeSB7XG4gICAgYXdhaXQgd2FpdEZvckNvbmRpdGlvbihhc3luYyAoKSA9PiBhd2FpdCBhZGIuZmlsZUV4aXN0cyhwYXRoT25EZXZpY2UpLFxuICAgICAge3dhaXRNczogUkVUUllfVElNRU9VVCwgaW50ZXJ2YWxNczogUkVUUllfUEFVU0V9KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVGhlIGV4cGVjdGVkIHNjcmVlbiByZWNvcmQgZmlsZSAnJHtwYXRoT25EZXZpY2V9JyBkb2VzIG5vdCBleGlzdCBhZnRlciAke1JFVFJZX1RJTUVPVVR9bXMuIGAgK1xuICAgICAgYElzICR7U0NSRUVOUkVDT1JEX0JJTkFSWX0gdXRpbGl0eSBhdmFpbGFibGUgYW5kIG9wZXJhdGlvbmFsIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdD9gKTtcbiAgfVxuXG4gIHJlY29yZGluZ1Byb3BlcnRpZXMucmVjb3Jkcy5wdXNoKHBhdGhPbkRldmljZSk7XG4gIHJlY29yZGluZ1Byb3BlcnRpZXMucmVjb3JkaW5nUHJvY2VzcyA9IHJlY29yZGluZ1Byb2M7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIG1lcmdlU2NyZWVuUmVjb3JkcyAobWVkaWFGaWxlcywgbG9nID0gbnVsbCkge1xuICB0cnkge1xuICAgIGF3YWl0IGZzLndoaWNoKEZGTVBFR19CSU5BUlkpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke0ZGTVBFR19CSU5BUll9IHV0aWxpdHkgaXMgbm90IGF2YWlsYWJsZSBpbiBQQVRILiBQbGVhc2UgaW5zdGFsbCBpdCBmcm9tIGh0dHBzOi8vd3d3LmZmbXBlZy5vcmcvYCk7XG4gIH1cbiAgY29uc3QgY29uZmlnQ29udGVudCA9IG1lZGlhRmlsZXNcbiAgICAubWFwKCh4KSA9PiBgZmlsZSAnJHt4fSdgKVxuICAgIC5qb2luKCdcXG4nKTtcbiAgY29uc3QgY29uZmlnRmlsZSA9IHBhdGgucmVzb2x2ZShwYXRoLmRpcm5hbWUobWVkaWFGaWxlc1swXSksICdjb25maWcudHh0Jyk7XG4gIGF3YWl0IGZzLndyaXRlRmlsZShjb25maWdGaWxlLCBjb25maWdDb250ZW50LCAndXRmOCcpO1xuICBsb2c/LmRlYnVnKGBHZW5lcmF0ZWQgZmZtcGVnIG1lcmdpbmcgY29uZmlnICcke2NvbmZpZ0ZpbGV9JyB3aXRoIGl0ZW1zOlxcbiR7Y29uZmlnQ29udGVudH1gKTtcbiAgY29uc3QgcmVzdWx0ID0gcGF0aC5yZXNvbHZlKHBhdGguZGlybmFtZShtZWRpYUZpbGVzWzBdKSwgYG1lcmdlXyR7TWF0aC5mbG9vcihuZXcgRGF0ZSgpKX0ke0RFRkFVTFRfRVhUfWApO1xuICBjb25zdCBhcmdzID0gWyctc2FmZScsICcwJywgJy1mJywgJ2NvbmNhdCcsICctaScsIGNvbmZpZ0ZpbGUsICctYycsICdjb3B5JywgcmVzdWx0XTtcbiAgbG9nPy5pbmZvKGBJbml0aWF0aW5nIHNjcmVlbiByZWNvcmRzIG1lcmdpbmcgdXNpbmcgdGhlIGNvbW1hbmQgJyR7RkZNUEVHX0JJTkFSWX0gJHthcmdzLmpvaW4oJyAnKX0nYCk7XG4gIGF3YWl0IGV4ZWMoRkZNUEVHX0JJTkFSWSwgYXJncyk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHRlcm1pbmF0ZUJhY2tncm91bmRTY3JlZW5SZWNvcmRpbmcgKGFkYiwgZm9yY2UgPSB0cnVlKSB7XG4gIGNvbnN0IHBpZHMgPSAoYXdhaXQgYWRiLmdldFBJRHNCeU5hbWUoU0NSRUVOUkVDT1JEX0JJTkFSWSkpXG4gICAgLm1hcCgocCkgPT4gYCR7cH1gKTtcbiAgaWYgKF8uaXNFbXB0eShwaWRzKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgYXdhaXQgYWRiLnNoZWxsKFsna2lsbCcsIGZvcmNlID8gJy0xNScgOiAnLTInLCAuLi5waWRzXSk7XG4gICAgYXdhaXQgd2FpdEZvckNvbmRpdGlvbihhc3luYyAoKSA9PiBfLmlzRW1wdHkoYXdhaXQgYWRiLmdldFBJRHNCeU5hbWUoU0NSRUVOUkVDT1JEX0JJTkFSWSkpLCB7XG4gICAgICB3YWl0TXM6IFBST0NFU1NfU0hVVERPV05fVElNRU9VVCxcbiAgICAgIGludGVydmFsTXM6IDUwMCxcbiAgICB9KTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gc3RvcCB0aGUgYmFja2dyb3VuZCBzY3JlZW4gcmVjb3JkaW5nOiAke2Vyci5tZXNzYWdlfWApO1xuICB9XG59XG5cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTdGFydFJlY29yZGluZ09wdGlvbnNcbiAqXG4gKiBAcHJvcGVydHkgez9zdHJpbmd9IHJlbW90ZVBhdGggLSBUaGUgcGF0aCB0byB0aGUgcmVtb3RlIGxvY2F0aW9uLCB3aGVyZSB0aGUgY2FwdHVyZWQgdmlkZW8gc2hvdWxkIGJlIHVwbG9hZGVkLlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhlIGZvbGxvd2luZyBwcm90b2NvbHMgYXJlIHN1cHBvcnRlZDogaHR0cC9odHRwcywgZnRwLlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVsbCBvciBlbXB0eSBzdHJpbmcgdmFsdWUgKHRoZSBkZWZhdWx0IHNldHRpbmcpIG1lYW5zIHRoZSBjb250ZW50IG9mIHJlc3VsdGluZ1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZSBzaG91bGQgYmUgZW5jb2RlZCBhcyBCYXNlNjQgYW5kIHBhc3NlZCBhcyB0aGUgZW5kcG91bnQgcmVzcG9uc2UgdmFsdWUuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24gaWYgdGhlIGdlbmVyYXRlZCBtZWRpYSBmaWxlIGlzIHRvbyBiaWcgdG9cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpdCBpbnRvIHRoZSBhdmFpbGFibGUgcHJvY2VzcyBtZW1vcnkuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzIG9wdGlvbiBvbmx5IGhhcyBhbiBlZmZlY3QgaWYgdGhlcmUgaXMgc2NyZWVuIHJlY29yZGluZyBwcm9jZXNzIGluIHByb2dyZWVzc1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5kIGBmb3JjZVJlc3RhcnRgIHBhcmFtZXRlciBpcyBub3Qgc2V0IHRvIGB0cnVlYC5cbiAqIEBwcm9wZXJ0eSB7P3N0cmluZ30gdXNlciAtIFRoZSBuYW1lIG9mIHRoZSB1c2VyIGZvciB0aGUgcmVtb3RlIGF1dGhlbnRpY2F0aW9uLiBPbmx5IHdvcmtzIGlmIGByZW1vdGVQYXRoYCBpcyBwcm92aWRlZC5cbiAqIEBwcm9wZXJ0eSB7P3N0cmluZ30gcGFzcyAtIFRoZSBwYXNzd29yZCBmb3IgdGhlIHJlbW90ZSBhdXRoZW50aWNhdGlvbi4gT25seSB3b3JrcyBpZiBgcmVtb3RlUGF0aGAgaXMgcHJvdmlkZWQuXG4gKiBAcHJvcGVydHkgez9zdHJpbmd9IG1ldGhvZCBbUFVUXSAtIFRoZSBodHRwIG11bHRpcGFydCB1cGxvYWQgbWV0aG9kIG5hbWUuIE9ubHkgd29ya3MgaWYgYHJlbW90ZVBhdGhgIGlzIHByb3ZpZGVkLlxuICogQHByb3BlcnR5IHs/T2JqZWN0fSBoZWFkZXJzIC0gQWRkaXRpb25hbCBoZWFkZXJzIG1hcHBpbmcgZm9yIG11bHRpcGFydCBodHRwKHMpIHVwbG9hZHNcbiAqIEBwcm9wZXJ0eSB7P3N0cmluZ30gZmlsZUZpZWxkTmFtZSBbZmlsZV0gLSBUaGUgbmFtZSBvZiB0aGUgZm9ybSBmaWVsZCwgd2hlcmUgdGhlIGZpbGUgY29udGVudCBCTE9CIHNob3VsZCBiZSBzdG9yZWQgZm9yXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHR0cChzKSB1cGxvYWRzXG4gKiBAcHJvcGVydHkgez9PYmplY3R8QXJyYXk8UGFpcj59IGZvcm1GaWVsZHMgLSBBZGRpdGlvbmFsIGZvcm0gZmllbGRzIGZvciBtdWx0aXBhcnQgaHR0cChzKSB1cGxvYWRzXG4gKiBAcHJvcGVydHkgez9zdHJpbmd9IHZpZGVvU2l6ZSAtIFRoZSBmb3JtYXQgaXMgd2lkdGh4aGVpZ2h0LlxuICogICAgICAgICAgICAgICAgICBUaGUgZGVmYXVsdCB2YWx1ZSBpcyB0aGUgZGV2aWNlJ3MgbmF0aXZlIGRpc3BsYXkgcmVzb2x1dGlvbiAoaWYgc3VwcG9ydGVkKSxcbiAqICAgICAgICAgICAgICAgICAgMTI4MHg3MjAgaWYgbm90LiBGb3IgYmVzdCByZXN1bHRzLFxuICogICAgICAgICAgICAgICAgICB1c2UgYSBzaXplIHN1cHBvcnRlZCBieSB5b3VyIGRldmljZSdzIEFkdmFuY2VkIFZpZGVvIENvZGluZyAoQVZDKSBlbmNvZGVyLlxuICogICAgICAgICAgICAgICAgICBGb3IgZXhhbXBsZSwgXCIxMjgweDcyMFwiXG4gKiBAcHJvcGVydHkgez9ib29sZWFufSBidWdSZXBvcnQgLSBTZXQgaXQgdG8gYHRydWVgIGluIG9yZGVyIHRvIGRpc3BsYXkgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvbiB0aGUgdmlkZW8gb3ZlcmxheSxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2ggYXMgYSB0aW1lc3RhbXAsIHRoYXQgaXMgaGVscGZ1bCBpbiB2aWRlb3MgY2FwdHVyZWQgdG8gaWxsdXN0cmF0ZSBidWdzLlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyBvcHRpb24gaXMgb25seSBzdXBwb3J0ZWQgc2luY2UgQVBJIGxldmVsIDI3IChBbmRyb2lkIFApLlxuICogQHByb3BlcnR5IHs/c3RyaW5nfG51bWJlcn0gdGltZUxpbWl0IC0gVGhlIG1heGltdW0gcmVjb3JkaW5nIHRpbWUsIGluIHNlY29uZHMuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIDE4MCAoMyBtaW51dGVzKS5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoZSBtYXhpbXVtIHZhbHVlIGlzIDE4MDAgKDMwIG1pbnV0ZXMpLiBJZiB0aGUgcGFzc2VkIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiAxODAgdGhlblxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGFsZ29yaXRobSB3aWxsIHRyeSB0byBzY2hlZHVsZSBtdWx0aXBsZSBzY3JlZW4gcmVjb3JkaW5nIGNodW5rcyBhbmQgbWVyZ2UgdGhlXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRpbmcgdmlkZW9zIGludG8gYSBzaW5nbGUgbWVkaWEgZmlsZSB1c2luZyBgZmZtcGVnYCB1dGlsaXR5LlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYgdGhlIHV0aWxpdHkgaXMgbm90IGF2YWlsYWJsZSBpbiBQQVRIIHRoZW4gdGhlIG1vc3QgcmVjZW50IHNjcmVlbiByZWNvcmRpbmcgY2h1bmsgaXNcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvaW5nIHRvIGJlIHJldHVybmVkLlxuICogQHByb3BlcnR5IHs/c3RyaW5nfG51bWJlcn0gYml0UmF0ZSAtIFRoZSB2aWRlbyBiaXQgcmF0ZSBmb3IgdGhlIHZpZGVvLCBpbiBiaXRzIHBlciBzZWNvbmQuXG4gKiAgICAgICAgICAgICAgICBUaGUgZGVmYXVsdCB2YWx1ZSBpcyA0MDAwMDAwICg0IE1iaXQvcykuIFlvdSBjYW4gaW5jcmVhc2UgdGhlIGJpdCByYXRlIHRvIGltcHJvdmUgdmlkZW8gcXVhbGl0eSxcbiAqICAgICAgICAgICAgICAgIGJ1dCBkb2luZyBzbyByZXN1bHRzIGluIGxhcmdlciBtb3ZpZSBmaWxlcy5cbiAqIEBwcm9wZXJ0eSB7P2Jvb2xlYW59IGZvcmNlUmVzdGFydCAtIFdoZXRoZXIgdG8gdHJ5IHRvIGNhdGNoIGFuZCB1cGxvYWQvcmV0dXJuIHRoZSBjdXJyZW50bHkgcnVubmluZyBzY3JlZW4gcmVjb3JkaW5nXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYGZhbHNlYCwgdGhlIGRlZmF1bHQgc2V0dGluZykgb3IgaWdub3JlIHRoZSByZXN1bHQgb2YgaXQgYW5kIHN0YXJ0IGEgbmV3IHJlY29yZGluZ1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1tZWRpYXRlbHkgKGB0cnVlYCkuXG4gKi9cblxuLyoqXG4gKiBSZWNvcmQgdGhlIGRpc3BsYXkgb2YgYSByZWFsIGRldmljZXMgcnVubmluZyBBbmRyb2lkIDQuNCAoQVBJIGxldmVsIDE5KSBhbmQgaGlnaGVyLlxuICogRW11bGF0b3JzIGFyZSBzdXBwb3J0ZWQgc2luY2UgQVBJIGxldmVsIDI3IChBbmRyb2lkIFApLlxuICogSXQgcmVjb3JkcyBzY3JlZW4gYWN0aXZpdHkgdG8gYW4gTVBFRy00IGZpbGUuIEF1ZGlvIGlzIG5vdCByZWNvcmRlZCB3aXRoIHRoZSB2aWRlbyBmaWxlLlxuICogSWYgc2NyZWVuIHJlY29yZGluZyBoYXMgYmVlbiBhbHJlYWR5IHN0YXJ0ZWQgdGhlbiB0aGUgY29tbWFuZCB3aWxsIHN0b3AgaXQgZm9yY2VmdWxseSBhbmQgc3RhcnQgYSBuZXcgb25lLlxuICogVGhlIHByZXZpb3VzbHkgcmVjb3JkZWQgdmlkZW8gZmlsZSB3aWxsIGJlIGRlbGV0ZWQuXG4gKlxuICogQHBhcmFtIHs/U3RhcnRSZWNvcmRpbmdPcHRpb25zfSBvcHRpb25zIC0gVGhlIGF2YWlsYWJsZSBvcHRpb25zLlxuICogQHJldHVybnMge3N0cmluZ30gQmFzZTY0LWVuY29kZWQgY29udGVudCBvZiB0aGUgcmVjb3JkZWQgbWVkaWEgZmlsZSBpZlxuICogICAgICAgICAgICAgICAgICAgYW55IHNjcmVlbiByZWNvcmRpbmcgaXMgY3VycmVudGx5IHJ1bm5pbmcgb3IgYW4gZW1wdHkgc3RyaW5nLlxuICogQHRocm93cyB7RXJyb3J9IElmIHNjcmVlbiByZWNvcmRpbmcgaGFzIGZhaWxlZCB0byBzdGFydCBvciBpcyBub3Qgc3VwcG9ydGVkIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqL1xuY29tbWFuZHMuc3RhcnRSZWNvcmRpbmdTY3JlZW4gPSBhc3luYyBmdW5jdGlvbiBzdGFydFJlY29yZGluZ1NjcmVlbiAob3B0aW9ucyA9IHt9KSB7XG4gIGF3YWl0IHZlcmlmeVNjcmVlblJlY29yZElzU3VwcG9ydGVkKHRoaXMuYWRiLCB0aGlzLmlzRW11bGF0b3IoKSk7XG5cbiAgbGV0IHJlc3VsdCA9ICcnO1xuICBjb25zdCB7dmlkZW9TaXplLCB0aW1lTGltaXQgPSBERUZBVUxUX1JFQ09SRElOR19USU1FX1NFQywgYnVnUmVwb3J0LCBiaXRSYXRlLCBmb3JjZVJlc3RhcnR9ID0gb3B0aW9ucztcbiAgaWYgKCFmb3JjZVJlc3RhcnQpIHtcbiAgICByZXN1bHQgPSBhd2FpdCB0aGlzLnN0b3BSZWNvcmRpbmdTY3JlZW4ob3B0aW9ucyk7XG4gIH1cblxuICBpZiAoYXdhaXQgdGVybWluYXRlQmFja2dyb3VuZFNjcmVlblJlY29yZGluZyh0aGlzLmFkYiwgdHJ1ZSkpIHtcbiAgICB0aGlzLmxvZy53YXJuKGBUaGVyZSB3ZXJlIHNvbWUgJHtTQ1JFRU5SRUNPUkRfQklOQVJZfSBwcm9jZXNzIGxlZnRvdmVycyBydW5uaW5nIGAgK1xuICAgICAgYGluIHRoZSBiYWNrZ3JvdW5kLiBNYWtlIHN1cmUgeW91IHN0b3Agc2NyZWVuIHJlY29yZGluZyBlYWNoIHRpbWUgYWZ0ZXIgaXQgaXMgc3RhcnRlZCwgYCArXG4gICAgICBgb3RoZXJ3aXNlIHRoZSByZWNvcmRlZCBtZWRpYSBtaWdodCBxdWlja2x5IGV4Y2VlZCBhbGwgdGhlIGZyZWUgc3BhY2Ugb24gdGhlIGRldmljZSB1bmRlciB0ZXN0LmApO1xuICB9XG5cbiAgaWYgKCFfLmlzRW1wdHkodGhpcy5fc2NyZWVuUmVjb3JkaW5nUHJvcGVydGllcykpIHtcbiAgICBmb3IgKGNvbnN0IHJlY29yZCBvZiAodGhpcy5fc2NyZWVuUmVjb3JkaW5nUHJvcGVydGllcy5yZWNvcmRzIHx8IFtdKSkge1xuICAgICAgYXdhaXQgdGhpcy5hZGIucmltcmFmKHJlY29yZCk7XG4gICAgfVxuICAgIHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMgPSBudWxsO1xuICB9XG5cbiAgY29uc3QgdGltZW91dCA9IHBhcnNlRmxvYXQodGltZUxpbWl0KTtcbiAgaWYgKGlzTmFOKHRpbWVvdXQpIHx8IHRpbWVvdXQgPiBNQVhfVElNRV9TRUMgfHwgdGltZW91dCA8PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgdGltZUxpbWl0IHZhbHVlIG11c3QgYmUgaW4gcmFuZ2UgWzEsICR7TUFYX1RJTUVfU0VDfV0gc2Vjb25kcy4gYCArXG4gICAgICBgVGhlIHZhbHVlIG9mICcke3RpbWVMaW1pdH0nIGhhcyBiZWVuIHBhc3NlZCBpbnN0ZWFkLmApO1xuICB9XG5cbiAgdGhpcy5fc2NyZWVuUmVjb3JkaW5nUHJvcGVydGllcyA9IHtcbiAgICB0aW1lcjogbmV3IHRpbWluZy5UaW1lcigpLnN0YXJ0KCksXG4gICAgdmlkZW9TaXplLFxuICAgIHRpbWVMaW1pdCxcbiAgICBjdXJyZW50VGltZUxpbWl0OiB0aW1lTGltaXQsXG4gICAgYml0UmF0ZSxcbiAgICBidWdSZXBvcnQsXG4gICAgcmVjb3JkczogW10sXG4gICAgcmVjb3JkaW5nUHJvY2VzczogbnVsbCxcbiAgICBzdG9wcGVkOiBmYWxzZSxcbiAgfTtcbiAgYXdhaXQgc2NoZWR1bGVTY3JlZW5SZWNvcmQodGhpcy5hZGIsIHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMsIHRoaXMubG9nKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gU3RvcFJlY29yZGluZ09wdGlvbnNcbiAqXG4gKiBAcHJvcGVydHkgez9zdHJpbmd9IHJlbW90ZVBhdGggLSBUaGUgcGF0aCB0byB0aGUgcmVtb3RlIGxvY2F0aW9uLCB3aGVyZSB0aGUgcmVzdWx0aW5nIHZpZGVvIHNob3VsZCBiZSB1cGxvYWRlZC5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoZSBmb2xsb3dpbmcgcHJvdG9jb2xzIGFyZSBzdXBwb3J0ZWQ6IGh0dHAvaHR0cHMsIGZ0cC5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE51bGwgb3IgZW1wdHkgc3RyaW5nIHZhbHVlICh0aGUgZGVmYXVsdCBzZXR0aW5nKSBtZWFucyB0aGUgY29udGVudCBvZiByZXN1bHRpbmdcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUgc2hvdWxkIGJlIGVuY29kZWQgYXMgQmFzZTY0IGFuZCBwYXNzZWQgYXMgdGhlIGVuZHBvdW50IHJlc3BvbnNlIHZhbHVlLlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQW4gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duIGlmIHRoZSBnZW5lcmF0ZWQgbWVkaWEgZmlsZSBpcyB0b28gYmlnIHRvXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXQgaW50byB0aGUgYXZhaWxhYmxlIHByb2Nlc3MgbWVtb3J5LlxuICogQHByb3BlcnR5IHs/c3RyaW5nfSB1c2VyIC0gVGhlIG5hbWUgb2YgdGhlIHVzZXIgZm9yIHRoZSByZW1vdGUgYXV0aGVudGljYXRpb24uXG4gKiBAcHJvcGVydHkgez9zdHJpbmd9IHBhc3MgLSBUaGUgcGFzc3dvcmQgZm9yIHRoZSByZW1vdGUgYXV0aGVudGljYXRpb24uXG4gKiBAcHJvcGVydHkgez9zdHJpbmd9IG1ldGhvZCAtIFRoZSBodHRwIG11bHRpcGFydCB1cGxvYWQgbWV0aG9kIG5hbWUuIFRoZSAnUFVUJyBvbmUgaXMgdXNlZCBieSBkZWZhdWx0LlxuICogQHByb3BlcnR5IHs/T2JqZWN0fSBoZWFkZXJzIC0gQWRkaXRpb25hbCBoZWFkZXJzIG1hcHBpbmcgZm9yIG11bHRpcGFydCBodHRwKHMpIHVwbG9hZHNcbiAqIEBwcm9wZXJ0eSB7P3N0cmluZ30gZmlsZUZpZWxkTmFtZSBbZmlsZV0gLSBUaGUgbmFtZSBvZiB0aGUgZm9ybSBmaWVsZCwgd2hlcmUgdGhlIGZpbGUgY29udGVudCBCTE9CIHNob3VsZCBiZSBzdG9yZWQgZm9yXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHR0cChzKSB1cGxvYWRzXG4gKiBAcHJvcGVydHkgez9PYmplY3R8QXJyYXk8UGFpcj59IGZvcm1GaWVsZHMgLSBBZGRpdGlvbmFsIGZvcm0gZmllbGRzIGZvciBtdWx0aXBhcnQgaHR0cChzKSB1cGxvYWRzXG4gKi9cblxuLyoqXG4gKiBTdG9wIHJlY29yZGluZyB0aGUgc2NyZWVuLlxuICogSWYgbm8gc2NyZWVuIHJlY29yZGluZyBoYXMgYmVlbiBzdGFydGVkIGJlZm9yZSB0aGVuIHRoZSBtZXRob2QgcmV0dXJucyBhbiBlbXB0eSBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHs/U3RvcFJlY29yZGluZ09wdGlvbnN9IG9wdGlvbnMgLSBUaGUgYXZhaWxhYmxlIG9wdGlvbnMuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBCYXNlNjQtZW5jb2RlZCBjb250ZW50IG9mIHRoZSByZWNvcmRlZCBtZWRpYSBmaWxlIGlmICdyZW1vdGVQYXRoJ1xuICogICAgICAgICAgICAgICAgICAgcGFyYW1ldGVyIGlzIGZhbHN5IG9yIGFuIGVtcHR5IHN0cmluZy5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGVyZSB3YXMgYW4gZXJyb3Igd2hpbGUgZ2V0dGluZyB0aGUgbmFtZSBvZiBhIG1lZGlhIGZpbGVcbiAqICAgICAgICAgICAgICAgICBvciB0aGUgZmlsZSBjb250ZW50IGNhbm5vdCBiZSB1cGxvYWRlZCB0byB0aGUgcmVtb3RlIGxvY2F0aW9uXG4gKiAgICAgICAgICAgICAgICAgb3Igc2NyZWVuIHJlY29yZGluZyBpcyBub3Qgc3VwcG9ydGVkIG9uIHRoZSBkZXZpY2UgdW5kZXIgdGVzdC5cbiAqL1xuY29tbWFuZHMuc3RvcFJlY29yZGluZ1NjcmVlbiA9IGFzeW5jIGZ1bmN0aW9uIHN0b3BSZWNvcmRpbmdTY3JlZW4gKG9wdGlvbnMgPSB7fSkge1xuICBhd2FpdCB2ZXJpZnlTY3JlZW5SZWNvcmRJc1N1cHBvcnRlZCh0aGlzLmFkYiwgdGhpcy5pc0VtdWxhdG9yKCkpO1xuXG4gIGlmICghXy5pc0VtcHR5KHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMpKSB7XG4gICAgdGhpcy5fc2NyZWVuUmVjb3JkaW5nUHJvcGVydGllcy5zdG9wcGVkID0gdHJ1ZTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgYXdhaXQgdGVybWluYXRlQmFja2dyb3VuZFNjcmVlblJlY29yZGluZyh0aGlzLmFkYiwgZmFsc2UpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICB0aGlzLmxvZy53YXJuKGVyci5tZXNzYWdlKTtcbiAgICBpZiAoIV8uaXNFbXB0eSh0aGlzLl9zY3JlZW5SZWNvcmRpbmdQcm9wZXJ0aWVzKSkge1xuICAgICAgdGhpcy5sb2cud2FybignVGhlIHJlc3VsdGluZyB2aWRlbyBtaWdodCBiZSBjb3JydXB0ZWQnKTtcbiAgICB9XG4gIH1cblxuICBpZiAoXy5pc0VtcHR5KHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMpKSB7XG4gICAgdGhpcy5sb2cuaW5mbyhgU2NyZWVuIHJlY29yZGluZyBoYXMgbm90IGJlZW4gcHJldmlvdXNseSBzdGFydGVkIGJ5IEFwcGl1bS4gVGhlcmUgaXMgbm90aGluZyB0byBzdG9wYCk7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgaWYgKHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMucmVjb3JkaW5nUHJvY2VzcyAmJiB0aGlzLl9zY3JlZW5SZWNvcmRpbmdQcm9wZXJ0aWVzLnJlY29yZGluZ1Byb2Nlc3MuaXNSdW5uaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMucmVjb3JkaW5nUHJvY2Vzcy5zdG9wKCdTSUdJTlQnLCBQUk9DRVNTX1NIVVRET1dOX1RJTUVPVVQpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMubG9nLmVycm9yQW5kVGhyb3coYFVuYWJsZSB0byBzdG9wIHNjcmVlbiByZWNvcmRpbmcgd2l0aGluICR7UFJPQ0VTU19TSFVURE9XTl9USU1FT1VUfW1zYCk7XG4gICAgfVxuICAgIHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMucmVjb3JkaW5nUHJvY2VzcyA9IG51bGw7XG4gIH1cblxuICBpZiAoXy5pc0VtcHR5KHRoaXMuX3NjcmVlblJlY29yZGluZ1Byb3BlcnRpZXMucmVjb3JkcykpIHtcbiAgICB0aGlzLmxvZy5lcnJvckFuZFRocm93KGBObyBzY3JlZW4gcmVjb3JkaW5ncyBoYXZlIGJlZW4gc3RvcmVkIG9uIHRoZSBkZXZpY2Ugc28gZmFyLiBgICtcbiAgICAgIGBBcmUgeW91IHN1cmUgdGhlICR7U0NSRUVOUkVDT1JEX0JJTkFSWX0gdXRpbGl0eSB3b3JrcyBhcyBleHBlY3RlZD9gKTtcbiAgfVxuXG4gIGNvbnN0IHRtcFJvb3QgPSBhd2FpdCB0ZW1wRGlyLm9wZW5EaXIoKTtcbiAgdHJ5IHtcbiAgICBjb25zdCBsb2NhbFJlY29yZHMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IHBhdGhPbkRldmljZSBvZiB0aGlzLl9zY3JlZW5SZWNvcmRpbmdQcm9wZXJ0aWVzLnJlY29yZHMpIHtcbiAgICAgIGxvY2FsUmVjb3Jkcy5wdXNoKHBhdGgucmVzb2x2ZSh0bXBSb290LCBwYXRoLnBvc2l4LmJhc2VuYW1lKHBhdGhPbkRldmljZSkpKTtcbiAgICAgIGF3YWl0IHRoaXMuYWRiLnB1bGwocGF0aE9uRGV2aWNlLCBfLmxhc3QobG9jYWxSZWNvcmRzKSk7XG4gICAgICBhd2FpdCB0aGlzLmFkYi5yaW1yYWYocGF0aE9uRGV2aWNlKTtcbiAgICB9XG4gICAgbGV0IHJlc3VsdEZpbGVQYXRoID0gXy5sYXN0KGxvY2FsUmVjb3Jkcyk7XG4gICAgaWYgKGxvY2FsUmVjb3Jkcy5sZW5ndGggPiAxKSB7XG4gICAgICB0aGlzLmxvZy5pbmZvKGBHb3QgJHtsb2NhbFJlY29yZHMubGVuZ3RofSBzY3JlZW4gcmVjb3JkaW5ncy4gVHJ5aW5nIHRvIG1lcmdlIHRoZW1gKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlc3VsdEZpbGVQYXRoID0gYXdhaXQgbWVyZ2VTY3JlZW5SZWNvcmRzKGxvY2FsUmVjb3JkcywgdGhpcy5sb2cpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aGlzLmxvZy53YXJuKGBDYW5ub3QgbWVyZ2UgdGhlIHJlY29yZGVkIGZpbGVzLiBUaGUgbW9zdCByZWNlbnQgc2NyZWVuIHJlY29yZGluZyBpcyBnb2luZyB0byBiZSByZXR1cm5lZCBhcyB0aGUgcmVzdWx0LiBgICtcbiAgICAgICAgICBgT3JpZ2luYWwgZXJyb3I6ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoXy5pc0VtcHR5KG9wdGlvbnMucmVtb3RlUGF0aCkpIHtcbiAgICAgIGNvbnN0IHtzaXplfSA9IGF3YWl0IGZzLnN0YXQocmVzdWx0RmlsZVBhdGgpO1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFRoZSBzaXplIG9mIHRoZSByZXN1bHRpbmcgc2NyZWVuIHJlY29yZGluZyBpcyAke3V0aWwudG9SZWFkYWJsZVNpemVTdHJpbmcoc2l6ZSl9YCk7XG4gICAgfVxuICAgIHJldHVybiBhd2FpdCB1cGxvYWRSZWNvcmRlZE1lZGlhKHJlc3VsdEZpbGVQYXRoLCBvcHRpb25zLnJlbW90ZVBhdGgsIG9wdGlvbnMpO1xuICB9IGZpbmFsbHkge1xuICAgIGF3YWl0IGZzLnJpbXJhZih0bXBSb290KTtcbiAgICB0aGlzLl9zY3JlZW5SZWNvcmRpbmdQcm9wZXJ0aWVzID0gbnVsbDtcbiAgfVxufTtcblxuXG5leHBvcnQgeyBjb21tYW5kcyB9O1xuZXhwb3J0IGRlZmF1bHQgY29tbWFuZHM7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBLE1BQU1BLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFBQztBQUVwQixNQUFNQyxXQUFXLEdBQUcsR0FBRztBQUN2QixNQUFNQyxhQUFhLEdBQUcsSUFBSTtBQUMxQixNQUFNQyxzQkFBc0IsR0FBRyxFQUFF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
@@ -1 +1 @@
1
- {"version":3,"file":"recordscreen.js","names":["commands","RETRY_PAUSE","RETRY_TIMEOUT","MAX_RECORDING_TIME_SEC","MAX_TIME_SEC","DEFAULT_RECORDING_TIME_SEC","PROCESS_SHUTDOWN_TIMEOUT","SCREENRECORD_BINARY","DEFAULT_EXT","MIN_EMULATOR_API_LEVEL","FFMPEG_BINARY","system","isWindows","uploadRecordedMedia","localFile","remotePath","uploadOptions","_","isEmpty","util","toInMemoryBase64","toString","user","pass","method","headers","fileFieldName","formFields","options","auth","net","uploadFile","verifyScreenRecordIsSupported","adb","isEmulator","apiLevel","getApiLevel","Error","scheduleScreenRecord","recordingProperties","log","stopped","timer","videoSize","bitRate","timeLimit","bugReport","currentTimeLimit","hasValue","currentTimeLimitInt","parseInt","isNaN","pathOnDevice","uuidV4","substring","recordingProc","screenrecord","on","currentDuration","getDuration","asSeconds","toFixed","debug","timeLimitInt","chunkDuration","e","error","stack","start","waitForCondition","fileExists","waitMs","intervalMs","records","push","recordingProcess","mergeScreenRecords","mediaFiles","fs","which","configContent","map","x","join","configFile","path","resolve","dirname","writeFile","result","Math","floor","Date","args","info","exec","terminateBackgroundScreenRecording","force","pids","getPIDsByName","p","shell","err","message","startRecordingScreen","forceRestart","stopRecordingScreen","warn","_screenRecordingProperties","record","rimraf","timeout","parseFloat","timing","Timer","isRunning","stop","errorAndThrow","tmpRoot","tempDir","openDir","localRecords","posix","basename","pull","last","resultFilePath","length","size","stat","toReadableSizeString"],"sources":["../../../lib/commands/recordscreen.js"],"sourcesContent":["import _ from 'lodash';\nimport { waitForCondition } from 'asyncbox';\nimport { util, fs, net, tempDir, system, timing } from '@appium/support';\nimport { exec } from 'teen_process';\nimport path from 'path';\n\n\nconst commands = {};\n\nconst RETRY_PAUSE = 300;\nconst RETRY_TIMEOUT = 5000;\nconst MAX_RECORDING_TIME_SEC = 60 * 3;\nconst MAX_TIME_SEC = 60 * 30;\nconst DEFAULT_RECORDING_TIME_SEC = MAX_RECORDING_TIME_SEC;\nconst PROCESS_SHUTDOWN_TIMEOUT = 10 * 1000;\nconst SCREENRECORD_BINARY = 'screenrecord';\nconst DEFAULT_EXT = '.mp4';\nconst MIN_EMULATOR_API_LEVEL = 27;\nconst FFMPEG_BINARY = `ffmpeg${system.isWindows() ? '.exe' : ''}`;\n\nasync function uploadRecordedMedia (localFile, remotePath = null, uploadOptions = {}) {\n if (_.isEmpty(remotePath)) {\n return (await util.toInMemoryBase64(localFile)).toString();\n }\n\n const {user, pass, method, headers, fileFieldName, formFields} = uploadOptions;\n const options = {\n method: method || 'PUT',\n headers,\n fileFieldName,\n formFields,\n };\n if (user && pass) {\n options.auth = {user, pass};\n }\n await net.uploadFile(localFile, remotePath, options);\n return '';\n}\n\nasync function verifyScreenRecordIsSupported (adb, isEmulator) {\n const apiLevel = await adb.getApiLevel();\n if (isEmulator && apiLevel < MIN_EMULATOR_API_LEVEL) {\n throw new Error(`Screen recording does not work on emulators running Android API level less than ${MIN_EMULATOR_API_LEVEL}`);\n }\n if (apiLevel < 19) {\n throw new Error(`Screen recording not available on API Level ${apiLevel}. Minimum API Level is 19.`);\n }\n}\n\nasync function scheduleScreenRecord (adb, recordingProperties, log = null) {\n if (recordingProperties.stopped) {\n return;\n }\n\n const {\n timer,\n videoSize,\n bitRate,\n timeLimit,\n bugReport,\n } = recordingProperties;\n\n let currentTimeLimit = MAX_RECORDING_TIME_SEC;\n if (util.hasValue(recordingProperties.currentTimeLimit)) {\n const currentTimeLimitInt = parseInt(recordingProperties.currentTimeLimit, 10);\n if (!isNaN(currentTimeLimitInt) && currentTimeLimitInt < MAX_RECORDING_TIME_SEC) {\n currentTimeLimit = currentTimeLimitInt;\n }\n }\n const pathOnDevice = `/sdcard/${util.uuidV4().substring(0, 8)}${DEFAULT_EXT}`;\n const recordingProc = adb.screenrecord(pathOnDevice, {\n videoSize,\n bitRate,\n timeLimit: currentTimeLimit,\n bugReport,\n });\n\n recordingProc.on('end', () => {\n if (recordingProperties.stopped || !util.hasValue(timeLimit)) {\n return;\n }\n const currentDuration = timer.getDuration().asSeconds.toFixed(0);\n log?.debug(`The overall screen recording duration is ${currentDuration}s so far`);\n const timeLimitInt = parseInt(timeLimit, 10);\n if (isNaN(timeLimitInt) || currentDuration >= timeLimitInt) {\n log?.debug('There is no need to start the next recording chunk');\n return;\n }\n\n recordingProperties.currentTimeLimit = timeLimitInt - currentDuration;\n const chunkDuration = recordingProperties.currentTimeLimit < MAX_RECORDING_TIME_SEC\n ? recordingProperties.currentTimeLimit\n : MAX_RECORDING_TIME_SEC;\n log?.debug(`Starting the next ${chunkDuration}s-chunk ` +\n `of screen recording in order to achieve ${timeLimitInt}s total duration`);\n (async () => {\n try {\n await scheduleScreenRecord(adb, recordingProperties, log);\n } catch (e) {\n log?.error(e.stack);\n recordingProperties.stopped = true;\n }\n })();\n });\n\n await recordingProc.start(0);\n try {\n await waitForCondition(async () => await adb.fileExists(pathOnDevice),\n {waitMs: RETRY_TIMEOUT, intervalMs: RETRY_PAUSE});\n } catch (e) {\n throw new Error(`The expected screen record file '${pathOnDevice}' does not exist after ${RETRY_TIMEOUT}ms. ` +\n `Is ${SCREENRECORD_BINARY} utility available and operational on the device under test?`);\n }\n\n recordingProperties.records.push(pathOnDevice);\n recordingProperties.recordingProcess = recordingProc;\n}\n\nasync function mergeScreenRecords (mediaFiles, log = null) {\n try {\n await fs.which(FFMPEG_BINARY);\n } catch (e) {\n throw new Error(`${FFMPEG_BINARY} utility is not available in PATH. Please install it from https://www.ffmpeg.org/`);\n }\n const configContent = mediaFiles\n .map((x) => `file '${x}'`)\n .join('\\n');\n const configFile = path.resolve(path.dirname(mediaFiles[0]), 'config.txt');\n await fs.writeFile(configFile, configContent, 'utf8');\n log?.debug(`Generated ffmpeg merging config '${configFile}' with items:\\n${configContent}`);\n const result = path.resolve(path.dirname(mediaFiles[0]), `merge_${Math.floor(new Date())}${DEFAULT_EXT}`);\n const args = ['-safe', '0', '-f', 'concat', '-i', configFile, '-c', 'copy', result];\n log?.info(`Initiating screen records merging using the command '${FFMPEG_BINARY} ${args.join(' ')}'`);\n await exec(FFMPEG_BINARY, args);\n return result;\n}\n\nasync function terminateBackgroundScreenRecording (adb, force = true) {\n const pids = (await adb.getPIDsByName(SCREENRECORD_BINARY))\n .map((p) => `${p}`);\n if (_.isEmpty(pids)) {\n return false;\n }\n\n try {\n await adb.shell(['kill', force ? '-15' : '-2', ...pids]);\n await waitForCondition(async () => _.isEmpty(await adb.getPIDsByName(SCREENRECORD_BINARY)), {\n waitMs: PROCESS_SHUTDOWN_TIMEOUT,\n intervalMs: 500,\n });\n return true;\n } catch (err) {\n throw new Error(`Unable to stop the background screen recording: ${err.message}`);\n }\n}\n\n\n/**\n * @typedef {Object} StartRecordingOptions\n *\n * @property {?string} remotePath - The path to the remote location, where the captured video should be uploaded.\n * The following protocols are supported: http/https, ftp.\n * Null or empty string value (the default setting) means the content of resulting\n * file should be encoded as Base64 and passed as the endpount response value.\n * An exception will be thrown if the generated media file is too big to\n * fit into the available process memory.\n * This option only has an effect if there is screen recording process in progreess\n * and `forceRestart` parameter is not set to `true`.\n * @property {?string} user - The name of the user for the remote authentication. Only works if `remotePath` is provided.\n * @property {?string} pass - The password for the remote authentication. Only works if `remotePath` is provided.\n * @property {?string} method [PUT] - The http multipart upload method name. Only works if `remotePath` is provided.\n * @property {?Object} headers - Additional headers mapping for multipart http(s) uploads\n * @property {?string} fileFieldName [file] - The name of the form field, where the file content BLOB should be stored for\n * http(s) uploads\n * @property {?Object|Array<Pair>} formFields - Additional form fields for multipart http(s) uploads\n * @property {?string} videoSize - The format is widthxheight.\n * The default value is the device's native display resolution (if supported),\n * 1280x720 if not. For best results,\n * use a size supported by your device's Advanced Video Coding (AVC) encoder.\n * For example, \"1280x720\"\n * @property {?boolean} bugReport - Set it to `true` in order to display additional information on the video overlay,\n * such as a timestamp, that is helpful in videos captured to illustrate bugs.\n * This option is only supported since API level 27 (Android P).\n * @property {?string|number} timeLimit - The maximum recording time, in seconds. The default value is 180 (3 minutes).\n * The maximum value is 1800 (30 minutes). If the passed value is greater than 180 then\n * the algorithm will try to schedule multiple screen recording chunks and merge the\n * resulting videos into a single media file using `ffmpeg` utility.\n * If the utility is not available in PATH then the most recent screen recording chunk is\n * going to be returned.\n * @property {?string|number} bitRate - The video bit rate for the video, in bits per second.\n * The default value is 4000000 (4 Mbit/s). You can increase the bit rate to improve video quality,\n * but doing so results in larger movie files.\n * @property {?boolean} forceRestart - Whether to try to catch and upload/return the currently running screen recording\n * (`false`, the default setting) or ignore the result of it and start a new recording\n * immediately (`true`).\n */\n\n/**\n * Record the display of a real devices running Android 4.4 (API level 19) and higher.\n * Emulators are supported since API level 27 (Android P).\n * It records screen activity to an MPEG-4 file. Audio is not recorded with the video file.\n * If screen recording has been already started then the command will stop it forcefully and start a new one.\n * The previously recorded video file will be deleted.\n *\n * @param {?StartRecordingOptions} options - The available options.\n * @returns {string} Base64-encoded content of the recorded media file if\n * any screen recording is currently running or an empty string.\n * @throws {Error} If screen recording has failed to start or is not supported on the device under test.\n */\ncommands.startRecordingScreen = async function startRecordingScreen (options = {}) {\n await verifyScreenRecordIsSupported(this.adb, this.isEmulator());\n\n let result = '';\n const {videoSize, timeLimit = DEFAULT_RECORDING_TIME_SEC, bugReport, bitRate, forceRestart} = options;\n if (!forceRestart) {\n result = await this.stopRecordingScreen(options);\n }\n\n if (await terminateBackgroundScreenRecording(this.adb, true)) {\n this.log.warn(`There were some ${SCREENRECORD_BINARY} process leftovers running ` +\n `in the background. Make sure you stop screen recording each time after it is started, ` +\n `otherwise the recorded media might quickly exceed all the free space on the device under test.`);\n }\n\n if (!_.isEmpty(this._screenRecordingProperties)) {\n for (const record of (this._screenRecordingProperties.records || [])) {\n await this.adb.rimraf(record);\n }\n this._screenRecordingProperties = null;\n }\n\n const timeout = parseFloat(timeLimit);\n if (isNaN(timeout) || timeout > MAX_TIME_SEC || timeout <= 0) {\n throw new Error(`The timeLimit value must be in range [1, ${MAX_TIME_SEC}] seconds. ` +\n `The value of '${timeLimit}' has been passed instead.`);\n }\n\n this._screenRecordingProperties = {\n timer: new timing.Timer().start(),\n videoSize,\n timeLimit,\n currentTimeLimit: timeLimit,\n bitRate,\n bugReport,\n records: [],\n recordingProcess: null,\n stopped: false,\n };\n await scheduleScreenRecord(this.adb, this._screenRecordingProperties, this.log);\n return result;\n};\n\n/**\n * @typedef {Object} StopRecordingOptions\n *\n * @property {?string} remotePath - The path to the remote location, where the resulting video should be uploaded.\n * The following protocols are supported: http/https, ftp.\n * Null or empty string value (the default setting) means the content of resulting\n * file should be encoded as Base64 and passed as the endpount response value.\n * An exception will be thrown if the generated media file is too big to\n * fit into the available process memory.\n * @property {?string} user - The name of the user for the remote authentication.\n * @property {?string} pass - The password for the remote authentication.\n * @property {?string} method - The http multipart upload method name. The 'PUT' one is used by default.\n * @property {?Object} headers - Additional headers mapping for multipart http(s) uploads\n * @property {?string} fileFieldName [file] - The name of the form field, where the file content BLOB should be stored for\n * http(s) uploads\n * @property {?Object|Array<Pair>} formFields - Additional form fields for multipart http(s) uploads\n */\n\n/**\n * Stop recording the screen.\n * If no screen recording has been started before then the method returns an empty string.\n *\n * @param {?StopRecordingOptions} options - The available options.\n * @returns {string} Base64-encoded content of the recorded media file if 'remotePath'\n * parameter is falsy or an empty string.\n * @throws {Error} If there was an error while getting the name of a media file\n * or the file content cannot be uploaded to the remote location\n * or screen recording is not supported on the device under test.\n */\ncommands.stopRecordingScreen = async function stopRecordingScreen (options = {}) {\n await verifyScreenRecordIsSupported(this.adb, this.isEmulator());\n\n if (!_.isEmpty(this._screenRecordingProperties)) {\n this._screenRecordingProperties.stopped = true;\n }\n\n try {\n await terminateBackgroundScreenRecording(this.adb, false);\n } catch (err) {\n this.log.warn(err.message);\n if (!_.isEmpty(this._screenRecordingProperties)) {\n this.log.warn('The resulting video might be corrupted');\n }\n }\n\n if (_.isEmpty(this._screenRecordingProperties)) {\n this.log.info(`Screen recording has not been previously started by Appium. There is nothing to stop`);\n return '';\n }\n\n if (this._screenRecordingProperties.recordingProcess && this._screenRecordingProperties.recordingProcess.isRunning) {\n try {\n await this._screenRecordingProperties.recordingProcess.stop('SIGINT', PROCESS_SHUTDOWN_TIMEOUT);\n } catch (e) {\n this.log.errorAndThrow(`Unable to stop screen recording within ${PROCESS_SHUTDOWN_TIMEOUT}ms`);\n }\n this._screenRecordingProperties.recordingProcess = null;\n }\n\n if (_.isEmpty(this._screenRecordingProperties.records)) {\n this.log.errorAndThrow(`No screen recordings have been stored on the device so far. ` +\n `Are you sure the ${SCREENRECORD_BINARY} utility works as expected?`);\n }\n\n const tmpRoot = await tempDir.openDir();\n try {\n const localRecords = [];\n for (const pathOnDevice of this._screenRecordingProperties.records) {\n localRecords.push(path.resolve(tmpRoot, path.posix.basename(pathOnDevice)));\n await this.adb.pull(pathOnDevice, _.last(localRecords));\n await this.adb.rimraf(pathOnDevice);\n }\n let resultFilePath = _.last(localRecords);\n if (localRecords.length > 1) {\n this.log.info(`Got ${localRecords.length} screen recordings. Trying to merge them`);\n try {\n resultFilePath = await mergeScreenRecords(localRecords, this.log);\n } catch (e) {\n this.log.warn(`Cannot merge the recorded files. The most recent screen recording is going to be returned as the result. ` +\n `Original error: ${e.message}`);\n }\n }\n if (_.isEmpty(options.remotePath)) {\n const {size} = await fs.stat(resultFilePath);\n this.log.debug(`The size of the resulting screen recording is ${util.toReadableSizeString(size)}`);\n }\n return await uploadRecordedMedia(resultFilePath, options.remotePath, options);\n } finally {\n await fs.rimraf(tmpRoot);\n this._screenRecordingProperties = null;\n }\n};\n\n\nexport { commands };\nexport default commands;\n"],"mappings":"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"}
1
+ {"version":3,"file":"recordscreen.js","names":["commands","RETRY_PAUSE","RETRY_TIMEOUT","MAX_RECORDING_TIME_SEC","MAX_TIME_SEC","DEFAULT_RECORDING_TIME_SEC","PROCESS_SHUTDOWN_TIMEOUT","SCREENRECORD_BINARY","DEFAULT_EXT","MIN_EMULATOR_API_LEVEL","FFMPEG_BINARY","system","isWindows","uploadRecordedMedia","localFile","remotePath","uploadOptions","_","isEmpty","util","toInMemoryBase64","toString","user","pass","method","headers","fileFieldName","formFields","options","auth","net","uploadFile","verifyScreenRecordIsSupported","adb","isEmulator","apiLevel","getApiLevel","Error","scheduleScreenRecord","recordingProperties","log","stopped","timer","videoSize","bitRate","timeLimit","bugReport","currentTimeLimit","hasValue","currentTimeLimitInt","parseInt","isNaN","pathOnDevice","uuidV4","substring","recordingProc","screenrecord","on","currentDuration","getDuration","asSeconds","toFixed","debug","timeLimitInt","chunkDuration","e","error","stack","start","waitForCondition","fileExists","waitMs","intervalMs","records","push","recordingProcess","mergeScreenRecords","mediaFiles","fs","which","configContent","map","x","join","configFile","path","resolve","dirname","writeFile","result","Math","floor","Date","args","info","exec","terminateBackgroundScreenRecording","force","pids","getPIDsByName","p","shell","err","message","startRecordingScreen","forceRestart","stopRecordingScreen","warn","_screenRecordingProperties","record","rimraf","timeout","parseFloat","timing","Timer","isRunning","stop","errorAndThrow","tmpRoot","tempDir","openDir","localRecords","posix","basename","pull","last","resultFilePath","length","size","stat","toReadableSizeString"],"sources":["../../../lib/commands/recordscreen.js"],"sourcesContent":["import _ from 'lodash';\nimport { waitForCondition } from 'asyncbox';\nimport { util, fs, net, tempDir, system, timing } from '@appium/support';\nimport { exec } from 'teen_process';\nimport path from 'path';\n\n\nconst commands = {};\n\nconst RETRY_PAUSE = 300;\nconst RETRY_TIMEOUT = 5000;\nconst MAX_RECORDING_TIME_SEC = 60 * 3;\nconst MAX_TIME_SEC = 60 * 30;\nconst DEFAULT_RECORDING_TIME_SEC = MAX_RECORDING_TIME_SEC;\nconst PROCESS_SHUTDOWN_TIMEOUT = 10 * 1000;\nconst SCREENRECORD_BINARY = 'screenrecord';\nconst DEFAULT_EXT = '.mp4';\nconst MIN_EMULATOR_API_LEVEL = 27;\nconst FFMPEG_BINARY = `ffmpeg${system.isWindows() ? '.exe' : ''}`;\n\nasync function uploadRecordedMedia (localFile, remotePath = null, uploadOptions = {}) {\n if (_.isEmpty(remotePath)) {\n return (await util.toInMemoryBase64(localFile)).toString();\n }\n\n const {user, pass, method, headers, fileFieldName, formFields} = uploadOptions;\n const options = {\n method: method || 'PUT',\n headers,\n fileFieldName,\n formFields,\n };\n if (user && pass) {\n options.auth = {user, pass};\n }\n await net.uploadFile(localFile, remotePath, options);\n return '';\n}\n\nasync function verifyScreenRecordIsSupported (adb, isEmulator) {\n const apiLevel = await adb.getApiLevel();\n if (isEmulator && apiLevel < MIN_EMULATOR_API_LEVEL) {\n throw new Error(`Screen recording does not work on emulators running Android API level less than ${MIN_EMULATOR_API_LEVEL}`);\n }\n if (apiLevel < 19) {\n throw new Error(`Screen recording not available on API Level ${apiLevel}. Minimum API Level is 19.`);\n }\n}\n\nasync function scheduleScreenRecord (adb, recordingProperties, log = null) {\n if (recordingProperties.stopped) {\n return;\n }\n\n const {\n timer,\n videoSize,\n bitRate,\n timeLimit,\n bugReport,\n } = recordingProperties;\n\n let currentTimeLimit = MAX_RECORDING_TIME_SEC;\n if (util.hasValue(recordingProperties.currentTimeLimit)) {\n const currentTimeLimitInt = parseInt(recordingProperties.currentTimeLimit, 10);\n if (!isNaN(currentTimeLimitInt) && currentTimeLimitInt < MAX_RECORDING_TIME_SEC) {\n currentTimeLimit = currentTimeLimitInt;\n }\n }\n const pathOnDevice = `/sdcard/${util.uuidV4().substring(0, 8)}${DEFAULT_EXT}`;\n const recordingProc = adb.screenrecord(pathOnDevice, {\n videoSize,\n bitRate,\n timeLimit: currentTimeLimit,\n bugReport,\n });\n\n recordingProc.on('end', () => {\n if (recordingProperties.stopped || !util.hasValue(timeLimit)) {\n return;\n }\n const currentDuration = timer.getDuration().asSeconds.toFixed(0);\n log?.debug(`The overall screen recording duration is ${currentDuration}s so far`);\n const timeLimitInt = parseInt(timeLimit, 10);\n if (isNaN(timeLimitInt) || currentDuration >= timeLimitInt) {\n log?.debug('There is no need to start the next recording chunk');\n return;\n }\n\n recordingProperties.currentTimeLimit = timeLimitInt - currentDuration;\n const chunkDuration = recordingProperties.currentTimeLimit < MAX_RECORDING_TIME_SEC\n ? recordingProperties.currentTimeLimit\n : MAX_RECORDING_TIME_SEC;\n log?.debug(`Starting the next ${chunkDuration}s-chunk ` +\n `of screen recording in order to achieve ${timeLimitInt}s total duration`);\n (async () => {\n try {\n await scheduleScreenRecord(adb, recordingProperties, log);\n } catch (e) {\n log?.error(e.stack);\n recordingProperties.stopped = true;\n }\n })();\n });\n\n await recordingProc.start(0);\n try {\n await waitForCondition(async () => await adb.fileExists(pathOnDevice),\n {waitMs: RETRY_TIMEOUT, intervalMs: RETRY_PAUSE});\n } catch (e) {\n throw new Error(`The expected screen record file '${pathOnDevice}' does not exist after ${RETRY_TIMEOUT}ms. ` +\n `Is ${SCREENRECORD_BINARY} utility available and operational on the device under test?`);\n }\n\n recordingProperties.records.push(pathOnDevice);\n recordingProperties.recordingProcess = recordingProc;\n}\n\nasync function mergeScreenRecords (mediaFiles, log = null) {\n try {\n await fs.which(FFMPEG_BINARY);\n } catch (e) {\n throw new Error(`${FFMPEG_BINARY} utility is not available in PATH. Please install it from https://www.ffmpeg.org/`);\n }\n const configContent = mediaFiles\n .map((x) => `file '${x}'`)\n .join('\\n');\n const configFile = path.resolve(path.dirname(mediaFiles[0]), 'config.txt');\n await fs.writeFile(configFile, configContent, 'utf8');\n log?.debug(`Generated ffmpeg merging config '${configFile}' with items:\\n${configContent}`);\n const result = path.resolve(path.dirname(mediaFiles[0]), `merge_${Math.floor(new Date())}${DEFAULT_EXT}`);\n const args = ['-safe', '0', '-f', 'concat', '-i', configFile, '-c', 'copy', result];\n log?.info(`Initiating screen records merging using the command '${FFMPEG_BINARY} ${args.join(' ')}'`);\n await exec(FFMPEG_BINARY, args);\n return result;\n}\n\nasync function terminateBackgroundScreenRecording (adb, force = true) {\n const pids = (await adb.getPIDsByName(SCREENRECORD_BINARY))\n .map((p) => `${p}`);\n if (_.isEmpty(pids)) {\n return false;\n }\n\n try {\n await adb.shell(['kill', force ? '-15' : '-2', ...pids]);\n await waitForCondition(async () => _.isEmpty(await adb.getPIDsByName(SCREENRECORD_BINARY)), {\n waitMs: PROCESS_SHUTDOWN_TIMEOUT,\n intervalMs: 500,\n });\n return true;\n } catch (err) {\n throw new Error(`Unable to stop the background screen recording: ${err.message}`);\n }\n}\n\n\n/**\n * @typedef {Object} StartRecordingOptions\n *\n * @property {?string} remotePath - The path to the remote location, where the captured video should be uploaded.\n * The following protocols are supported: http/https, ftp.\n * Null or empty string value (the default setting) means the content of resulting\n * file should be encoded as Base64 and passed as the endpount response value.\n * An exception will be thrown if the generated media file is too big to\n * fit into the available process memory.\n * This option only has an effect if there is screen recording process in progreess\n * and `forceRestart` parameter is not set to `true`.\n * @property {?string} user - The name of the user for the remote authentication. Only works if `remotePath` is provided.\n * @property {?string} pass - The password for the remote authentication. Only works if `remotePath` is provided.\n * @property {?string} method [PUT] - The http multipart upload method name. Only works if `remotePath` is provided.\n * @property {?Object} headers - Additional headers mapping for multipart http(s) uploads\n * @property {?string} fileFieldName [file] - The name of the form field, where the file content BLOB should be stored for\n * http(s) uploads\n * @property {?Object|Array<Pair>} formFields - Additional form fields for multipart http(s) uploads\n * @property {?string} videoSize - The format is widthxheight.\n * The default value is the device's native display resolution (if supported),\n * 1280x720 if not. For best results,\n * use a size supported by your device's Advanced Video Coding (AVC) encoder.\n * For example, \"1280x720\"\n * @property {?boolean} bugReport - Set it to `true` in order to display additional information on the video overlay,\n * such as a timestamp, that is helpful in videos captured to illustrate bugs.\n * This option is only supported since API level 27 (Android P).\n * @property {?string|number} timeLimit - The maximum recording time, in seconds. The default value is 180 (3 minutes).\n * The maximum value is 1800 (30 minutes). If the passed value is greater than 180 then\n * the algorithm will try to schedule multiple screen recording chunks and merge the\n * resulting videos into a single media file using `ffmpeg` utility.\n * If the utility is not available in PATH then the most recent screen recording chunk is\n * going to be returned.\n * @property {?string|number} bitRate - The video bit rate for the video, in bits per second.\n * The default value is 4000000 (4 Mbit/s). You can increase the bit rate to improve video quality,\n * but doing so results in larger movie files.\n * @property {?boolean} forceRestart - Whether to try to catch and upload/return the currently running screen recording\n * (`false`, the default setting) or ignore the result of it and start a new recording\n * immediately (`true`).\n */\n\n/**\n * Record the display of a real devices running Android 4.4 (API level 19) and higher.\n * Emulators are supported since API level 27 (Android P).\n * It records screen activity to an MPEG-4 file. Audio is not recorded with the video file.\n * If screen recording has been already started then the command will stop it forcefully and start a new one.\n * The previously recorded video file will be deleted.\n *\n * @param {?StartRecordingOptions} options - The available options.\n * @returns {string} Base64-encoded content of the recorded media file if\n * any screen recording is currently running or an empty string.\n * @throws {Error} If screen recording has failed to start or is not supported on the device under test.\n */\ncommands.startRecordingScreen = async function startRecordingScreen (options = {}) {\n await verifyScreenRecordIsSupported(this.adb, this.isEmulator());\n\n let result = '';\n const {videoSize, timeLimit = DEFAULT_RECORDING_TIME_SEC, bugReport, bitRate, forceRestart} = options;\n if (!forceRestart) {\n result = await this.stopRecordingScreen(options);\n }\n\n if (await terminateBackgroundScreenRecording(this.adb, true)) {\n this.log.warn(`There were some ${SCREENRECORD_BINARY} process leftovers running ` +\n `in the background. Make sure you stop screen recording each time after it is started, ` +\n `otherwise the recorded media might quickly exceed all the free space on the device under test.`);\n }\n\n if (!_.isEmpty(this._screenRecordingProperties)) {\n for (const record of (this._screenRecordingProperties.records || [])) {\n await this.adb.rimraf(record);\n }\n this._screenRecordingProperties = null;\n }\n\n const timeout = parseFloat(timeLimit);\n if (isNaN(timeout) || timeout > MAX_TIME_SEC || timeout <= 0) {\n throw new Error(`The timeLimit value must be in range [1, ${MAX_TIME_SEC}] seconds. ` +\n `The value of '${timeLimit}' has been passed instead.`);\n }\n\n this._screenRecordingProperties = {\n timer: new timing.Timer().start(),\n videoSize,\n timeLimit,\n currentTimeLimit: timeLimit,\n bitRate,\n bugReport,\n records: [],\n recordingProcess: null,\n stopped: false,\n };\n await scheduleScreenRecord(this.adb, this._screenRecordingProperties, this.log);\n return result;\n};\n\n/**\n * @typedef {Object} StopRecordingOptions\n *\n * @property {?string} remotePath - The path to the remote location, where the resulting video should be uploaded.\n * The following protocols are supported: http/https, ftp.\n * Null or empty string value (the default setting) means the content of resulting\n * file should be encoded as Base64 and passed as the endpount response value.\n * An exception will be thrown if the generated media file is too big to\n * fit into the available process memory.\n * @property {?string} user - The name of the user for the remote authentication.\n * @property {?string} pass - The password for the remote authentication.\n * @property {?string} method - The http multipart upload method name. The 'PUT' one is used by default.\n * @property {?Object} headers - Additional headers mapping for multipart http(s) uploads\n * @property {?string} fileFieldName [file] - The name of the form field, where the file content BLOB should be stored for\n * http(s) uploads\n * @property {?Object|Array<Pair>} formFields - Additional form fields for multipart http(s) uploads\n */\n\n/**\n * Stop recording the screen.\n * If no screen recording has been started before then the method returns an empty string.\n *\n * @param {?StopRecordingOptions} options - The available options.\n * @returns {string} Base64-encoded content of the recorded media file if 'remotePath'\n * parameter is falsy or an empty string.\n * @throws {Error} If there was an error while getting the name of a media file\n * or the file content cannot be uploaded to the remote location\n * or screen recording is not supported on the device under test.\n */\ncommands.stopRecordingScreen = async function stopRecordingScreen (options = {}) {\n await verifyScreenRecordIsSupported(this.adb, this.isEmulator());\n\n if (!_.isEmpty(this._screenRecordingProperties)) {\n this._screenRecordingProperties.stopped = true;\n }\n\n try {\n await terminateBackgroundScreenRecording(this.adb, false);\n } catch (err) {\n this.log.warn(err.message);\n if (!_.isEmpty(this._screenRecordingProperties)) {\n this.log.warn('The resulting video might be corrupted');\n }\n }\n\n if (_.isEmpty(this._screenRecordingProperties)) {\n this.log.info(`Screen recording has not been previously started by Appium. There is nothing to stop`);\n return '';\n }\n\n if (this._screenRecordingProperties.recordingProcess && this._screenRecordingProperties.recordingProcess.isRunning) {\n try {\n await this._screenRecordingProperties.recordingProcess.stop('SIGINT', PROCESS_SHUTDOWN_TIMEOUT);\n } catch (e) {\n this.log.errorAndThrow(`Unable to stop screen recording within ${PROCESS_SHUTDOWN_TIMEOUT}ms`);\n }\n this._screenRecordingProperties.recordingProcess = null;\n }\n\n if (_.isEmpty(this._screenRecordingProperties.records)) {\n this.log.errorAndThrow(`No screen recordings have been stored on the device so far. ` +\n `Are you sure the ${SCREENRECORD_BINARY} utility works as expected?`);\n }\n\n const tmpRoot = await tempDir.openDir();\n try {\n const localRecords = [];\n for (const pathOnDevice of this._screenRecordingProperties.records) {\n localRecords.push(path.resolve(tmpRoot, path.posix.basename(pathOnDevice)));\n await this.adb.pull(pathOnDevice, _.last(localRecords));\n await this.adb.rimraf(pathOnDevice);\n }\n let resultFilePath = _.last(localRecords);\n if (localRecords.length > 1) {\n this.log.info(`Got ${localRecords.length} screen recordings. Trying to merge them`);\n try {\n resultFilePath = await mergeScreenRecords(localRecords, this.log);\n } catch (e) {\n this.log.warn(`Cannot merge the recorded files. The most recent screen recording is going to be returned as the result. ` +\n `Original error: ${e.message}`);\n }\n }\n if (_.isEmpty(options.remotePath)) {\n const {size} = await fs.stat(resultFilePath);\n this.log.debug(`The size of the resulting screen recording is ${util.toReadableSizeString(size)}`);\n }\n return await uploadRecordedMedia(resultFilePath, options.remotePath, options);\n } finally {\n await fs.rimraf(tmpRoot);\n this._screenRecordingProperties = null;\n }\n};\n\n\nexport { commands };\nexport default commands;\n"],"mappings":";;;;;;;;AAAA;AACA;AACA;AACA;AACA;AAGA,MAAMA,QAAQ,GAAG,CAAC,CAAC;AAAC;AAEpB,MAAMC,WAAW,GAAG,GAAG;AACvB,MAAMC,aAAa,GAAG,IAAI;AAC1B,MAAMC,sBAAsB,GAAG,EAAE,GAAG,CAAC;AACrC,MAAMC,YAAY,GAAG,EAAE,GAAG,EAAE;AAC5B,MAAMC,0BAA0B,GAAGF,sBAAsB;AACzD,MAAMG,wBAAwB,GAAG,EAAE,GAAG,IAAI;AAC1C,MAAMC,mBAAmB,GAAG,cAAc;AAC1C,MAAMC,WAAW,GAAG,MAAM;AAC1B,MAAMC,sBAAsB,GAAG,EAAE;AACjC,MAAMC,aAAa,GAAI,SAAQC,eAAM,CAACC,SAAS,EAAE,GAAG,MAAM,GAAG,EAAG,EAAC;AAEjE,eAAeC,mBAAmB,CAAEC,SAAS,EAAEC,UAAU,GAAG,IAAI,EAAEC,aAAa,GAAG,CAAC,CAAC,EAAE;EACpF,IAAIC,eAAC,CAACC,OAAO,CAACH,UAAU,CAAC,EAAE;IACzB,OAAO,CAAC,MAAMI,aAAI,CAACC,gBAAgB,CAACN,SAAS,CAAC,EAAEO,QAAQ,EAAE;EAC5D;EAEA,MAAM;IAACC,IAAI;IAAEC,IAAI;IAAEC,MAAM;IAAEC,OAAO;IAAEC,aAAa;IAAEC;EAAU,CAAC,GAAGX,aAAa;EAC9E,MAAMY,OAAO,GAAG;IACdJ,MAAM,EAAEA,MAAM,IAAI,KAAK;IACvBC,OAAO;IACPC,aAAa;IACbC;EACF,CAAC;EACD,IAAIL,IAAI,IAAIC,IAAI,EAAE;IAChBK,OAAO,CAACC,IAAI,GAAG;MAACP,IAAI;MAAEC;IAAI,CAAC;EAC7B;EACA,MAAMO,YAAG,CAACC,UAAU,CAACjB,SAAS,EAAEC,UAAU,EAAEa,OAAO,CAAC;EACpD,OAAO,EAAE;AACX;AAEA,eAAeI,6BAA6B,CAAEC,GAAG,EAAEC,UAAU,EAAE;EAC7D,MAAMC,QAAQ,GAAG,MAAMF,GAAG,CAACG,WAAW,EAAE;EACxC,IAAIF,UAAU,IAAIC,QAAQ,GAAG1B,sBAAsB,EAAE;IACnD,MAAM,IAAI4B,KAAK,CAAE,mFAAkF5B,sBAAuB,EAAC,CAAC;EAC9H;EACA,IAAI0B,QAAQ,GAAG,EAAE,EAAE;IACjB,MAAM,IAAIE,KAAK,CAAE,+CAA8CF,QAAS,4BAA2B,CAAC;EACtG;AACF;AAEA,eAAeG,oBAAoB,CAAEL,GAAG,EAAEM,mBAAmB,EAAEC,GAAG,GAAG,IAAI,EAAE;EACzE,IAAID,mBAAmB,CAACE,OAAO,EAAE;IAC/B;EACF;EAEA,MAAM;IACJC,KAAK;IACLC,SAAS;IACTC,OAAO;IACPC,SAAS;IACTC;EACF,CAAC,GAAGP,mBAAmB;EAEvB,IAAIQ,gBAAgB,GAAG5C,sBAAsB;EAC7C,IAAIgB,aAAI,CAAC6B,QAAQ,CAACT,mBAAmB,CAACQ,gBAAgB,CAAC,EAAE;IACvD,MAAME,mBAAmB,GAAGC,QAAQ,CAACX,mBAAmB,CAACQ,gBAAgB,EAAE,EAAE,CAAC;IAC9E,IAAI,CAACI,KAAK,CAACF,mBAAmB,CAAC,IAAIA,mBAAmB,GAAG9C,sBAAsB,EAAE;MAC/E4C,gBAAgB,GAAGE,mBAAmB;IACxC;EACF;EACA,MAAMG,YAAY,GAAI,WAAUjC,aAAI,CAACkC,MAAM,EAAE,CAACC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAE,GAAE9C,WAAY,EAAC;EAC7E,MAAM+C,aAAa,GAAGtB,GAAG,CAACuB,YAAY,CAACJ,YAAY,EAAE;IACnDT,SAAS;IACTC,OAAO;IACPC,SAAS,EAAEE,gBAAgB;IAC3BD;EACF,CAAC,CAAC;EAEFS,aAAa,CAACE,EAAE,CAAC,KAAK,EAAE,MAAM;IAC5B,IAAIlB,mBAAmB,CAACE,OAAO,IAAI,CAACtB,aAAI,CAAC6B,QAAQ,CAACH,SAAS,CAAC,EAAE;MAC5D;IACF;IACA,MAAMa,eAAe,GAAGhB,KAAK,CAACiB,WAAW,EAAE,CAACC,SAAS,CAACC,OAAO,CAAC,CAAC,CAAC;IAChErB,GAAG,aAAHA,GAAG,uBAAHA,GAAG,CAAEsB,KAAK,CAAE,4CAA2CJ,eAAgB,UAAS,CAAC;IACjF,MAAMK,YAAY,GAAGb,QAAQ,CAACL,SAAS,EAAE,EAAE,CAAC;IAC5C,IAAIM,KAAK,CAACY,YAAY,CAAC,IAAIL,eAAe,IAAIK,YAAY,EAAE;MAC1DvB,GAAG,aAAHA,GAAG,uBAAHA,GAAG,CAAEsB,KAAK,CAAC,oDAAoD,CAAC;MAChE;IACF;IAEAvB,mBAAmB,CAACQ,gBAAgB,GAAGgB,YAAY,GAAGL,eAAe;IACrE,MAAMM,aAAa,GAAGzB,mBAAmB,CAACQ,gBAAgB,GAAG5C,sBAAsB,GAC/EoC,mBAAmB,CAACQ,gBAAgB,GACpC5C,sBAAsB;IAC1BqC,GAAG,aAAHA,GAAG,uBAAHA,GAAG,CAAEsB,KAAK,CAAE,qBAAoBE,aAAc,UAAS,GACpD,2CAA0CD,YAAa,kBAAiB,CAAC;IAC5E,CAAC,YAAY;MACX,IAAI;QACF,MAAMzB,oBAAoB,CAACL,GAAG,EAAEM,mBAAmB,EAAEC,GAAG,CAAC;MAC3D,CAAC,CAAC,OAAOyB,CAAC,EAAE;QACVzB,GAAG,aAAHA,GAAG,uBAAHA,GAAG,CAAE0B,KAAK,CAACD,CAAC,CAACE,KAAK,CAAC;QACnB5B,mBAAmB,CAACE,OAAO,GAAG,IAAI;MACpC;IACF,CAAC,GAAG;EACN,CAAC,CAAC;EAEF,MAAMc,aAAa,CAACa,KAAK,CAAC,CAAC,CAAC;EAC5B,IAAI;IACF,MAAM,IAAAC,0BAAgB,EAAC,YAAY,MAAMpC,GAAG,CAACqC,UAAU,CAAClB,YAAY,CAAC,EACnE;MAACmB,MAAM,EAAErE,aAAa;MAAEsE,UAAU,EAAEvE;IAAW,CAAC,CAAC;EACrD,CAAC,CAAC,OAAOgE,CAAC,EAAE;IACV,MAAM,IAAI5B,KAAK,CAAE,oCAAmCe,YAAa,0BAAyBlD,aAAc,MAAK,GAC1G,MAAKK,mBAAoB,8DAA6D,CAAC;EAC5F;EAEAgC,mBAAmB,CAACkC,OAAO,CAACC,IAAI,CAACtB,YAAY,CAAC;EAC9Cb,mBAAmB,CAACoC,gBAAgB,GAAGpB,aAAa;AACtD;AAEA,eAAeqB,kBAAkB,CAAEC,UAAU,EAAErC,GAAG,GAAG,IAAI,EAAE;EACzD,IAAI;IACF,MAAMsC,WAAE,CAACC,KAAK,CAACrE,aAAa,CAAC;EAC/B,CAAC,CAAC,OAAOuD,CAAC,EAAE;IACV,MAAM,IAAI5B,KAAK,CAAE,GAAE3B,aAAc,mFAAkF,CAAC;EACtH;EACA,MAAMsE,aAAa,GAAGH,UAAU,CAC7BI,GAAG,CAAEC,CAAC,IAAM,SAAQA,CAAE,GAAE,CAAC,CACzBC,IAAI,CAAC,IAAI,CAAC;EACb,MAAMC,UAAU,GAAGC,aAAI,CAACC,OAAO,CAACD,aAAI,CAACE,OAAO,CAACV,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC;EAC1E,MAAMC,WAAE,CAACU,SAAS,CAACJ,UAAU,EAAEJ,aAAa,EAAE,MAAM,CAAC;EACrDxC,GAAG,aAAHA,GAAG,uBAAHA,GAAG,CAAEsB,KAAK,CAAE,oCAAmCsB,UAAW,kBAAiBJ,aAAc,EAAC,CAAC;EAC3F,MAAMS,MAAM,GAAGJ,aAAI,CAACC,OAAO,CAACD,aAAI,CAACE,OAAO,CAACV,UAAU,CAAC,CAAC,CAAC,CAAC,EAAG,SAAQa,IAAI,CAACC,KAAK,CAAC,IAAIC,IAAI,EAAE,CAAE,GAAEpF,WAAY,EAAC,CAAC;EACzG,MAAMqF,IAAI,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAET,UAAU,EAAE,IAAI,EAAE,MAAM,EAAEK,MAAM,CAAC;EACnFjD,GAAG,aAAHA,GAAG,uBAAHA,GAAG,CAAEsD,IAAI,CAAE,wDAAuDpF,aAAc,IAAGmF,IAAI,CAACV,IAAI,CAAC,GAAG,CAAE,GAAE,CAAC;EACrG,MAAM,IAAAY,kBAAI,EAACrF,aAAa,EAAEmF,IAAI,CAAC;EAC/B,OAAOJ,MAAM;AACf;AAEA,eAAeO,kCAAkC,CAAE/D,GAAG,EAAEgE,KAAK,GAAG,IAAI,EAAE;EACpE,MAAMC,IAAI,GAAG,CAAC,MAAMjE,GAAG,CAACkE,aAAa,CAAC5F,mBAAmB,CAAC,EACvD0E,GAAG,CAAEmB,CAAC,IAAM,GAAEA,CAAE,EAAC,CAAC;EACrB,IAAInF,eAAC,CAACC,OAAO,CAACgF,IAAI,CAAC,EAAE;IACnB,OAAO,KAAK;EACd;EAEA,IAAI;IACF,MAAMjE,GAAG,CAACoE,KAAK,CAAC,CAAC,MAAM,EAAEJ,KAAK,GAAG,KAAK,GAAG,IAAI,EAAE,GAAGC,IAAI,CAAC,CAAC;IACxD,MAAM,IAAA7B,0BAAgB,EAAC,YAAYpD,eAAC,CAACC,OAAO,CAAC,MAAMe,GAAG,CAACkE,aAAa,CAAC5F,mBAAmB,CAAC,CAAC,EAAE;MAC1FgE,MAAM,EAAEjE,wBAAwB;MAChCkE,UAAU,EAAE;IACd,CAAC,CAAC;IACF,OAAO,IAAI;EACb,CAAC,CAAC,OAAO8B,GAAG,EAAE;IACZ,MAAM,IAAIjE,KAAK,CAAE,mDAAkDiE,GAAG,CAACC,OAAQ,EAAC,CAAC;EACnF;AACF;AAuDAvG,QAAQ,CAACwG,oBAAoB,GAAG,eAAeA,oBAAoB,CAAE5E,OAAO,GAAG,CAAC,CAAC,EAAE;EACjF,MAAMI,6BAA6B,CAAC,IAAI,CAACC,GAAG,EAAE,IAAI,CAACC,UAAU,EAAE,CAAC;EAEhE,IAAIuD,MAAM,GAAG,EAAE;EACf,MAAM;IAAC9C,SAAS;IAAEE,SAAS,GAAGxC,0BAA0B;IAAEyC,SAAS;IAAEF,OAAO;IAAE6D;EAAY,CAAC,GAAG7E,OAAO;EACrG,IAAI,CAAC6E,YAAY,EAAE;IACjBhB,MAAM,GAAG,MAAM,IAAI,CAACiB,mBAAmB,CAAC9E,OAAO,CAAC;EAClD;EAEA,IAAI,MAAMoE,kCAAkC,CAAC,IAAI,CAAC/D,GAAG,EAAE,IAAI,CAAC,EAAE;IAC5D,IAAI,CAACO,GAAG,CAACmE,IAAI,CAAE,mBAAkBpG,mBAAoB,6BAA4B,GAC9E,wFAAuF,GACvF,gGAA+F,CAAC;EACrG;EAEA,IAAI,CAACU,eAAC,CAACC,OAAO,CAAC,IAAI,CAAC0F,0BAA0B,CAAC,EAAE;IAC/C,KAAK,MAAMC,MAAM,IAAK,IAAI,CAACD,0BAA0B,CAACnC,OAAO,IAAI,EAAE,EAAG;MACpE,MAAM,IAAI,CAACxC,GAAG,CAAC6E,MAAM,CAACD,MAAM,CAAC;IAC/B;IACA,IAAI,CAACD,0BAA0B,GAAG,IAAI;EACxC;EAEA,MAAMG,OAAO,GAAGC,UAAU,CAACnE,SAAS,CAAC;EACrC,IAAIM,KAAK,CAAC4D,OAAO,CAAC,IAAIA,OAAO,GAAG3G,YAAY,IAAI2G,OAAO,IAAI,CAAC,EAAE;IAC5D,MAAM,IAAI1E,KAAK,CAAE,4CAA2CjC,YAAa,aAAY,GAClF,iBAAgByC,SAAU,4BAA2B,CAAC;EAC3D;EAEA,IAAI,CAAC+D,0BAA0B,GAAG;IAChClE,KAAK,EAAE,IAAIuE,eAAM,CAACC,KAAK,EAAE,CAAC9C,KAAK,EAAE;IACjCzB,SAAS;IACTE,SAAS;IACTE,gBAAgB,EAAEF,SAAS;IAC3BD,OAAO;IACPE,SAAS;IACT2B,OAAO,EAAE,EAAE;IACXE,gBAAgB,EAAE,IAAI;IACtBlC,OAAO,EAAE;EACX,CAAC;EACD,MAAMH,oBAAoB,CAAC,IAAI,CAACL,GAAG,EAAE,IAAI,CAAC2E,0BAA0B,EAAE,IAAI,CAACpE,GAAG,CAAC;EAC/E,OAAOiD,MAAM;AACf,CAAC;AA+BDzF,QAAQ,CAAC0G,mBAAmB,GAAG,eAAeA,mBAAmB,CAAE9E,OAAO,GAAG,CAAC,CAAC,EAAE;EAC/E,MAAMI,6BAA6B,CAAC,IAAI,CAACC,GAAG,EAAE,IAAI,CAACC,UAAU,EAAE,CAAC;EAEhE,IAAI,CAACjB,eAAC,CAACC,OAAO,CAAC,IAAI,CAAC0F,0BAA0B,CAAC,EAAE;IAC/C,IAAI,CAACA,0BAA0B,CAACnE,OAAO,GAAG,IAAI;EAChD;EAEA,IAAI;IACF,MAAMuD,kCAAkC,CAAC,IAAI,CAAC/D,GAAG,EAAE,KAAK,CAAC;EAC3D,CAAC,CAAC,OAAOqE,GAAG,EAAE;IACZ,IAAI,CAAC9D,GAAG,CAACmE,IAAI,CAACL,GAAG,CAACC,OAAO,CAAC;IAC1B,IAAI,CAACtF,eAAC,CAACC,OAAO,CAAC,IAAI,CAAC0F,0BAA0B,CAAC,EAAE;MAC/C,IAAI,CAACpE,GAAG,CAACmE,IAAI,CAAC,wCAAwC,CAAC;IACzD;EACF;EAEA,IAAI1F,eAAC,CAACC,OAAO,CAAC,IAAI,CAAC0F,0BAA0B,CAAC,EAAE;IAC9C,IAAI,CAACpE,GAAG,CAACsD,IAAI,CAAE,sFAAqF,CAAC;IACrG,OAAO,EAAE;EACX;EAEA,IAAI,IAAI,CAACc,0BAA0B,CAACjC,gBAAgB,IAAI,IAAI,CAACiC,0BAA0B,CAACjC,gBAAgB,CAACwC,SAAS,EAAE;IAClH,IAAI;MACF,MAAM,IAAI,CAACP,0BAA0B,CAACjC,gBAAgB,CAACyC,IAAI,CAAC,QAAQ,EAAE9G,wBAAwB,CAAC;IACjG,CAAC,CAAC,OAAO2D,CAAC,EAAE;MACV,IAAI,CAACzB,GAAG,CAAC6E,aAAa,CAAE,0CAAyC/G,wBAAyB,IAAG,CAAC;IAChG;IACA,IAAI,CAACsG,0BAA0B,CAACjC,gBAAgB,GAAG,IAAI;EACzD;EAEA,IAAI1D,eAAC,CAACC,OAAO,CAAC,IAAI,CAAC0F,0BAA0B,CAACnC,OAAO,CAAC,EAAE;IACtD,IAAI,CAACjC,GAAG,CAAC6E,aAAa,CAAE,8DAA6D,GAClF,oBAAmB9G,mBAAoB,6BAA4B,CAAC;EACzE;EAEA,MAAM+G,OAAO,GAAG,MAAMC,gBAAO,CAACC,OAAO,EAAE;EACvC,IAAI;IACF,MAAMC,YAAY,GAAG,EAAE;IACvB,KAAK,MAAMrE,YAAY,IAAI,IAAI,CAACwD,0BAA0B,CAACnC,OAAO,EAAE;MAClEgD,YAAY,CAAC/C,IAAI,CAACW,aAAI,CAACC,OAAO,CAACgC,OAAO,EAAEjC,aAAI,CAACqC,KAAK,CAACC,QAAQ,CAACvE,YAAY,CAAC,CAAC,CAAC;MAC3E,MAAM,IAAI,CAACnB,GAAG,CAAC2F,IAAI,CAACxE,YAAY,EAAEnC,eAAC,CAAC4G,IAAI,CAACJ,YAAY,CAAC,CAAC;MACvD,MAAM,IAAI,CAACxF,GAAG,CAAC6E,MAAM,CAAC1D,YAAY,CAAC;IACrC;IACA,IAAI0E,cAAc,GAAG7G,eAAC,CAAC4G,IAAI,CAACJ,YAAY,CAAC;IACzC,IAAIA,YAAY,CAACM,MAAM,GAAG,CAAC,EAAE;MAC3B,IAAI,CAACvF,GAAG,CAACsD,IAAI,CAAE,OAAM2B,YAAY,CAACM,MAAO,0CAAyC,CAAC;MACnF,IAAI;QACFD,cAAc,GAAG,MAAMlD,kBAAkB,CAAC6C,YAAY,EAAE,IAAI,CAACjF,GAAG,CAAC;MACnE,CAAC,CAAC,OAAOyB,CAAC,EAAE;QACV,IAAI,CAACzB,GAAG,CAACmE,IAAI,CAAE,2GAA0G,GACtH,mBAAkB1C,CAAC,CAACsC,OAAQ,EAAC,CAAC;MACnC;IACF;IACA,IAAItF,eAAC,CAACC,OAAO,CAACU,OAAO,CAACb,UAAU,CAAC,EAAE;MACjC,MAAM;QAACiH;MAAI,CAAC,GAAG,MAAMlD,WAAE,CAACmD,IAAI,CAACH,cAAc,CAAC;MAC5C,IAAI,CAACtF,GAAG,CAACsB,KAAK,CAAE,iDAAgD3C,aAAI,CAAC+G,oBAAoB,CAACF,IAAI,CAAE,EAAC,CAAC;IACpG;IACA,OAAO,MAAMnH,mBAAmB,CAACiH,cAAc,EAAElG,OAAO,CAACb,UAAU,EAAEa,OAAO,CAAC;EAC/E,CAAC,SAAS;IACR,MAAMkD,WAAE,CAACgC,MAAM,CAACQ,OAAO,CAAC;IACxB,IAAI,CAACV,0BAA0B,GAAG,IAAI;EACxC;AACF,CAAC;AAAC,eAIa5G,QAAQ;AAAA"}