barsa-novin-ray-core 2.2.73 → 2.2.74

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 (232) hide show
  1. package/fesm2022/barsa-novin-ray-core.mjs +628 -649
  2. package/fesm2022/barsa-novin-ray-core.mjs.map +1 -1
  3. package/lib/abstract-classes/field-base.d.ts +1 -1
  4. package/lib/abstract-classes/number-base.d.ts +1 -1
  5. package/lib/date-services/date.service.d.ts +1 -1
  6. package/lib/directives/base.directive.d.ts +1 -1
  7. package/lib/dynamic-component/base-view-item-props.d.ts +4 -4
  8. package/lib/resolvers/login-settings.resolver.d.ts +1 -1
  9. package/lib/resolvers/tile-group-breadcrumb.resolver.d.ts +1 -1
  10. package/lib/services/notification.service.d.ts +2 -2
  11. package/lib/services/portal.service.d.ts +1 -1
  12. package/package.json +3 -5
  13. package/esm2022/barsa-novin-ray-core.mjs +0 -5
  14. package/esm2022/lib/abstract-classes/application-base.mjs +0 -25
  15. package/esm2022/lib/abstract-classes/barsa-api.mjs +0 -43
  16. package/esm2022/lib/abstract-classes/base-column-props.mjs +0 -89
  17. package/esm2022/lib/abstract-classes/base.component.mjs +0 -60
  18. package/esm2022/lib/abstract-classes/field-base.mjs +0 -244
  19. package/esm2022/lib/abstract-classes/files-validation-helper.mjs +0 -75
  20. package/esm2022/lib/abstract-classes/form-base.mjs +0 -164
  21. package/esm2022/lib/abstract-classes/form-field-report-page.component.mjs +0 -54
  22. package/esm2022/lib/abstract-classes/form-page-base.mjs +0 -132
  23. package/esm2022/lib/abstract-classes/form-page.component.mjs +0 -53
  24. package/esm2022/lib/abstract-classes/form-props.base.mjs +0 -100
  25. package/esm2022/lib/abstract-classes/form-toolbar-base.mjs +0 -57
  26. package/esm2022/lib/abstract-classes/index.mjs +0 -25
  27. package/esm2022/lib/abstract-classes/layout-item-base.mjs +0 -49
  28. package/esm2022/lib/abstract-classes/layout-panel-base.mjs +0 -68
  29. package/esm2022/lib/abstract-classes/linear-list-helper.mjs +0 -135
  30. package/esm2022/lib/abstract-classes/models.mjs +0 -184
  31. package/esm2022/lib/abstract-classes/module-with-dynamic-components.mjs +0 -2
  32. package/esm2022/lib/abstract-classes/number-base.mjs +0 -201
  33. package/esm2022/lib/abstract-classes/page-base.mjs +0 -98
  34. package/esm2022/lib/abstract-classes/page-with-form-handler-base.mjs +0 -41
  35. package/esm2022/lib/abstract-classes/report-base.mjs +0 -266
  36. package/esm2022/lib/abstract-classes/report-item-base.mjs +0 -54
  37. package/esm2022/lib/abstract-classes/report-view-base.component.mjs +0 -450
  38. package/esm2022/lib/abstract-classes/system-base.mjs +0 -25
  39. package/esm2022/lib/abstract-classes/tile-props.mjs +0 -49
  40. package/esm2022/lib/auth-guard.mjs +0 -48
  41. package/esm2022/lib/barsa-novin-ray-core-routing.module.mjs +0 -311
  42. package/esm2022/lib/barsa-novin-ray-core.module.mjs +0 -522
  43. package/esm2022/lib/base-ulv-setting.component.mjs +0 -46
  44. package/esm2022/lib/base.module.mjs +0 -28
  45. package/esm2022/lib/button-loading/button-loading.component.mjs +0 -20
  46. package/esm2022/lib/constants.mjs +0 -963
  47. package/esm2022/lib/container.component.mjs +0 -100
  48. package/esm2022/lib/controllers/base-controller.mjs +0 -9
  49. package/esm2022/lib/controllers/base-view.mjs +0 -24
  50. package/esm2022/lib/controllers/index.mjs +0 -4
  51. package/esm2022/lib/controllers/models.mjs +0 -2
  52. package/esm2022/lib/custom-route-reuse-strategy.mjs +0 -32
  53. package/esm2022/lib/date-services/date-hijri.service.mjs +0 -146
  54. package/esm2022/lib/date-services/date-info.mjs +0 -2
  55. package/esm2022/lib/date-services/date-miladi.service.mjs +0 -124
  56. package/esm2022/lib/date-services/date-shamsi.service.mjs +0 -148
  57. package/esm2022/lib/date-services/date.service.mjs +0 -149
  58. package/esm2022/lib/date-services/index.mjs +0 -6
  59. package/esm2022/lib/device.mjs +0 -663
  60. package/esm2022/lib/directives/absolute-div-body.directive.mjs +0 -46
  61. package/esm2022/lib/directives/anchor-scroll.directive.mjs +0 -25
  62. package/esm2022/lib/directives/attr-rtl.directive.mjs +0 -36
  63. package/esm2022/lib/directives/base.directive.mjs +0 -55
  64. package/esm2022/lib/directives/body-click.directive.mjs +0 -36
  65. package/esm2022/lib/directives/column-resizer.directive.mjs +0 -40
  66. package/esm2022/lib/directives/copy.directive.mjs +0 -60
  67. package/esm2022/lib/directives/count-down.directive.mjs +0 -109
  68. package/esm2022/lib/directives/dynamic-command.directive.mjs +0 -43
  69. package/esm2022/lib/directives/dynamic-style.directive.mjs +0 -66
  70. package/esm2022/lib/directives/ellapsis-text.directive.mjs +0 -70
  71. package/esm2022/lib/directives/ellipsify.directive.mjs +0 -73
  72. package/esm2022/lib/directives/field-binding.directive.mjs +0 -18
  73. package/esm2022/lib/directives/fill-empty-space.mjs +0 -89
  74. package/esm2022/lib/directives/form-close.directive.mjs +0 -33
  75. package/esm2022/lib/directives/img-lazy.directive.mjs +0 -82
  76. package/esm2022/lib/directives/index.mjs +0 -42
  77. package/esm2022/lib/directives/intersection-observer.directive.mjs +0 -52
  78. package/esm2022/lib/directives/items-renderer.directive.mjs +0 -60
  79. package/esm2022/lib/directives/label-mandatory.directive.mjs +0 -49
  80. package/esm2022/lib/directives/load-external-files.directive.mjs +0 -38
  81. package/esm2022/lib/directives/mobile.directive.mjs +0 -30
  82. package/esm2022/lib/directives/nowraptext.directive.mjs +0 -27
  83. package/esm2022/lib/directives/numbers-only-input.directive.mjs +0 -27
  84. package/esm2022/lib/directives/placeHolder.directive.mjs +0 -16
  85. package/esm2022/lib/directives/prevent-default.directive.mjs +0 -21
  86. package/esm2022/lib/directives/print-files.directive.mjs +0 -39
  87. package/esm2022/lib/directives/render-ulv-paging.directive.mjs +0 -81
  88. package/esm2022/lib/directives/render-ulv-viewer.directive.mjs +0 -76
  89. package/esm2022/lib/directives/render-ulv.directive.mjs +0 -52
  90. package/esm2022/lib/directives/route-form-change.directive.mjs +0 -38
  91. package/esm2022/lib/directives/save-image.directive.mjs +0 -28
  92. package/esm2022/lib/directives/splide-slider.directive.mjs +0 -113
  93. package/esm2022/lib/directives/stop-propagation.directive.mjs +0 -21
  94. package/esm2022/lib/directives/table-resizer.directive.mjs +0 -236
  95. package/esm2022/lib/directives/ulv-command.directive.mjs +0 -43
  96. package/esm2022/lib/directives/until-inview.directive.mjs +0 -53
  97. package/esm2022/lib/directives/webotp.directive.mjs +0 -49
  98. package/esm2022/lib/directives/workflow-choice-command.directive.mjs +0 -61
  99. package/esm2022/lib/dynamic-component/base-dynamic.component.mjs +0 -97
  100. package/esm2022/lib/dynamic-component/base-form-toolbaritem-props.mjs +0 -53
  101. package/esm2022/lib/dynamic-component/base-item-content-props.mjs +0 -83
  102. package/esm2022/lib/dynamic-component/base-view-content-props.mjs +0 -27
  103. package/esm2022/lib/dynamic-component/base-view-item-props.mjs +0 -552
  104. package/esm2022/lib/dynamic-component/base-view-props.mjs +0 -163
  105. package/esm2022/lib/dynamic-component/dynamic-form-toolbar-item.component.mjs +0 -38
  106. package/esm2022/lib/dynamic-component/dynamic-form.component.mjs +0 -69
  107. package/esm2022/lib/dynamic-component/dynamic-item.component.mjs +0 -78
  108. package/esm2022/lib/dynamic-component/dynamic-layout.component.mjs +0 -64
  109. package/esm2022/lib/dynamic-component/index.mjs +0 -11
  110. package/esm2022/lib/empty-page/empty-page.component.mjs +0 -49
  111. package/esm2022/lib/empty-page-with-router-and-router-outlet/empty-page-with-router-and-router-outlet.component.mjs +0 -16
  112. package/esm2022/lib/field-ui/field-ui.component.mjs +0 -149
  113. package/esm2022/lib/form/form.component.mjs +0 -212
  114. package/esm2022/lib/form-new/form-new.component.mjs +0 -31
  115. package/esm2022/lib/form-page-routing/barsa-sap-ui-form-page-routing.module.mjs +0 -54
  116. package/esm2022/lib/form-page-routing/barsa-sap-ui-form-page.module.mjs +0 -29
  117. package/esm2022/lib/form-page-routing/constants.mjs +0 -9
  118. package/esm2022/lib/form-page-routing/index.mjs +0 -3
  119. package/esm2022/lib/from-intersection-observer.mjs +0 -53
  120. package/esm2022/lib/global-error-handler.mjs +0 -26
  121. package/esm2022/lib/injdection-tokens.mjs +0 -8
  122. package/esm2022/lib/modal-root.component.mjs +0 -34
  123. package/esm2022/lib/not-found/not-found.component.mjs +0 -16
  124. package/esm2022/lib/not-internet/not-internet.component.mjs +0 -21
  125. package/esm2022/lib/pipes/barsa-icon-dict.pipe.mjs +0 -20
  126. package/esm2022/lib/pipes/bbb-translate.pipe.mjs +0 -36
  127. package/esm2022/lib/pipes/can-upload.pipe.mjs +0 -27
  128. package/esm2022/lib/pipes/card-media-size.pipe.mjs +0 -21
  129. package/esm2022/lib/pipes/column-custom-component.pipe.mjs +0 -41
  130. package/esm2022/lib/pipes/column-customui.pipe.mjs +0 -33
  131. package/esm2022/lib/pipes/column-icon.pipe.mjs +0 -23
  132. package/esm2022/lib/pipes/column-value.pipe.mjs +0 -35
  133. package/esm2022/lib/pipes/column-valueof-parameters.pipe.mjs +0 -34
  134. package/esm2022/lib/pipes/combo-row-img.pipe.mjs +0 -17
  135. package/esm2022/lib/pipes/context-menu.pipe.mjs +0 -41
  136. package/esm2022/lib/pipes/control-ui.pipe.mjs +0 -32
  137. package/esm2022/lib/pipes/convert-to-style.pipe.mjs +0 -33
  138. package/esm2022/lib/pipes/date-time-to-caption.pipe.mjs +0 -35
  139. package/esm2022/lib/pipes/fileinfo-count.pipe.mjs +0 -21
  140. package/esm2022/lib/pipes/filter-columns-by-details.pipe.mjs +0 -23
  141. package/esm2022/lib/pipes/filter-inline-action-list.pipe.mjs +0 -19
  142. package/esm2022/lib/pipes/filter-string.pipe.mjs +0 -45
  143. package/esm2022/lib/pipes/filter-tab.pipe.mjs +0 -20
  144. package/esm2022/lib/pipes/filter-toolbar-control.pipe.mjs +0 -17
  145. package/esm2022/lib/pipes/filter-workflow-mobile.pipe.mjs +0 -25
  146. package/esm2022/lib/pipes/filter.pipe.mjs +0 -34
  147. package/esm2022/lib/pipes/find-column-by-db-name.pipe.mjs +0 -28
  148. package/esm2022/lib/pipes/find-preview-column.pipe.mjs +0 -20
  149. package/esm2022/lib/pipes/fiori-icon.pipe.mjs +0 -43
  150. package/esm2022/lib/pipes/groupby.pipe.mjs +0 -64
  151. package/esm2022/lib/pipes/header-facet-value.pipe.mjs +0 -23
  152. package/esm2022/lib/pipes/hide-accept-cancel-buttons.pipe.mjs +0 -24
  153. package/esm2022/lib/pipes/hide-columns-inmobile.pipe.mjs +0 -23
  154. package/esm2022/lib/pipes/index.mjs +0 -55
  155. package/esm2022/lib/pipes/isimage.pipe.mjs +0 -20
  156. package/esm2022/lib/pipes/list-count.pipe.mjs +0 -18
  157. package/esm2022/lib/pipes/merge-fields-to-columns.pipe.mjs +0 -43
  158. package/esm2022/lib/pipes/mo-info-ulv-data.pipe.mjs +0 -59
  159. package/esm2022/lib/pipes/mo-info-ulv-paging.pipe.mjs +0 -17
  160. package/esm2022/lib/pipes/mo-report-value-concat.pipe.mjs +0 -36
  161. package/esm2022/lib/pipes/mo-report-value.pipe.mjs +0 -18
  162. package/esm2022/lib/pipes/mo-value.pipe.mjs +0 -19
  163. package/esm2022/lib/pipes/multiple-groupby.pipe.mjs +0 -91
  164. package/esm2022/lib/pipes/numeral.pipe.mjs +0 -44
  165. package/esm2022/lib/pipes/picture-field-source.pipe.mjs +0 -23
  166. package/esm2022/lib/pipes/remove-newline.pipe.mjs +0 -21
  167. package/esm2022/lib/pipes/replace.pipe.mjs +0 -18
  168. package/esm2022/lib/pipes/reverse.pipe.mjs +0 -23
  169. package/esm2022/lib/pipes/rownumber.pipe.mjs +0 -26
  170. package/esm2022/lib/pipes/sanitize-text.pipe.mjs +0 -21
  171. package/esm2022/lib/pipes/seperator-fix.pipe.mjs +0 -24
  172. package/esm2022/lib/pipes/sort.pipe.mjs +0 -49
  173. package/esm2022/lib/pipes/string-to-number.pipe.mjs +0 -26
  174. package/esm2022/lib/pipes/th-image-icon.pipe.mjs +0 -22
  175. package/esm2022/lib/pipes/tlbButtons.pipe.mjs +0 -60
  176. package/esm2022/lib/pipes/toolbar-settings.pipe.mjs +0 -27
  177. package/esm2022/lib/pipes/total-summary.pipe.mjs +0 -17
  178. package/esm2022/lib/pipes/tree-item-isexpanded.pipe.mjs +0 -26
  179. package/esm2022/lib/pipes/visible-value.pipe.mjs +0 -19
  180. package/esm2022/lib/portal-page/portal-page.component.mjs +0 -24
  181. package/esm2022/lib/portal-page/portal-sidebar.component.mjs +0 -37
  182. package/esm2022/lib/redirect-home-guard.mjs +0 -51
  183. package/esm2022/lib/redirect-report-navigator-command/redirect-report-navigator-command.component.mjs +0 -12
  184. package/esm2022/lib/report-container/report-container.component.mjs +0 -63
  185. package/esm2022/lib/resizable-module/resizable.component.mjs +0 -31
  186. package/esm2022/lib/resizable-module/resizable.directive.mjs +0 -42
  187. package/esm2022/lib/resizable-module/resizable.module.mjs +0 -17
  188. package/esm2022/lib/resolvers/index.mjs +0 -7
  189. package/esm2022/lib/resolvers/login-settings.resolver.mjs +0 -18
  190. package/esm2022/lib/resolvers/portal-dynamic-page.resolver.mjs +0 -49
  191. package/esm2022/lib/resolvers/portal-form-page.resolver.mjs +0 -18
  192. package/esm2022/lib/resolvers/portal-page.resolver.mjs +0 -30
  193. package/esm2022/lib/resolvers/portal-report-page.resolver.mjs +0 -37
  194. package/esm2022/lib/resolvers/tile-group-breadcrumb.resolver.mjs +0 -30
  195. package/esm2022/lib/root-page/root-page.component.mjs +0 -21
  196. package/esm2022/lib/root-portal/root-portal.component.mjs +0 -236
  197. package/esm2022/lib/server-connection-error/server-connection-error.component.mjs +0 -19
  198. package/esm2022/lib/services/api.service.mjs +0 -63
  199. package/esm2022/lib/services/audio-recording.service.mjs +0 -95
  200. package/esm2022/lib/services/barsa-dialog.service.mjs +0 -80
  201. package/esm2022/lib/services/barsa-storage.service.mjs +0 -78
  202. package/esm2022/lib/services/breadcrumb.service.mjs +0 -64
  203. package/esm2022/lib/services/column.service.mjs +0 -20
  204. package/esm2022/lib/services/container.service.mjs +0 -69
  205. package/esm2022/lib/services/dynamic-component.service.mjs +0 -55
  206. package/esm2022/lib/services/form-panel.service.mjs +0 -394
  207. package/esm2022/lib/services/form.service.mjs +0 -14
  208. package/esm2022/lib/services/groupby.service.mjs +0 -21
  209. package/esm2022/lib/services/horizontal-layout.service.mjs +0 -16
  210. package/esm2022/lib/services/index.mjs +0 -32
  211. package/esm2022/lib/services/indexeddb.service.mjs +0 -34
  212. package/esm2022/lib/services/layout-main-content.service.mjs +0 -19
  213. package/esm2022/lib/services/layout.service.mjs +0 -42
  214. package/esm2022/lib/services/local-storage.service.mjs +0 -32
  215. package/esm2022/lib/services/log.service.mjs +0 -50
  216. package/esm2022/lib/services/network-status.service.mjs +0 -15
  217. package/esm2022/lib/services/notification-popup.service.mjs +0 -2
  218. package/esm2022/lib/services/notification-sw.service.mjs +0 -180
  219. package/esm2022/lib/services/notification.service.mjs +0 -189
  220. package/esm2022/lib/services/portal.service.mjs +0 -950
  221. package/esm2022/lib/services/prompt-update.service.mjs +0 -56
  222. package/esm2022/lib/services/routing.service.mjs +0 -60
  223. package/esm2022/lib/services/save-scoll-position.service.mjs +0 -29
  224. package/esm2022/lib/services/service-worker-communication.service.mjs +0 -120
  225. package/esm2022/lib/services/tabpage.service.mjs +0 -13
  226. package/esm2022/lib/services/toast.service.mjs +0 -2
  227. package/esm2022/lib/services/ui.service.mjs +0 -23
  228. package/esm2022/lib/services/ulvmain.service.mjs +0 -824
  229. package/esm2022/lib/services/upload.service.mjs +0 -166
  230. package/esm2022/lib/services/video-recording.service.mjs +0 -115
  231. package/esm2022/lib/unlimit-session/unlimit-session.component.mjs +0 -40
  232. package/esm2022/public-api.mjs +0 -42
@@ -1,663 +0,0 @@
1
- /* eslint-disable */
2
- const Device = {};
3
- // * ******* OS Detection ********
4
- /**
5
- * Contains information about the operating system of the Device.
6
- * @name Device.os
7
- */
8
- /**
9
- * Enumeration containing the names of known operating systems.
10
- * @name Device.os.OS
11
- */
12
- /**
13
- * The name of the operating system.
14
- * @name Device.os.name
15
- * @type String
16
- */
17
- /**
18
- * The version of the operating system as <code>string</code>. Might be empty if no version can be determined.
19
- * @name Device.os.versionStr
20
- * @type String
21
- */
22
- /**
23
- * The version of the operating system as <code>float</code>. Might be <code>-1</code> if no version can be determined.
24
- * @name Device.os.version
25
- * @type float
26
- */
27
- /**
28
- * If this flag is set to <code>true</code>, a Windows operating system is used.
29
- * @name Device.os.windows
30
- * @type boolean
31
- */
32
- /**
33
- * If this flag is set to <code>true</code>, a Mac operating system is used.
34
- * @name Device.os.macintosh
35
- * @type boolean
36
- */
37
- /*
38
- * If this flag is set to <code>true</code>, an iOS operating system is used.
39
- * @name Device.os.ios
40
- * @type boolean
41
- */
42
- /**
43
- * If this flag is set to <code>true</code>, an Android operating system is used.
44
- * @name Device.os.android
45
- * @type boolean
46
- */
47
- /*
48
- * Windows operating system name.
49
- * @see Device.os.name
50
- * @name Device.os.OS.WINDOWS
51
- */
52
- /**
53
- * MAC operating system name.
54
- * @see Device.os.name
55
- * @name Device.os.OS.MACINTOSH
56
- */
57
- /**
58
- * iOS operating system name.
59
- * @see Device.os.name
60
- * @name Device.os.OS.IOS
61
- */
62
- /**
63
- * Android operating system name.
64
- * @see Device.os.name
65
- * @name Device.os.OS.ANDROID
66
- */
67
- const OS = {
68
- WINDOWS: 'win',
69
- MACINTOSH: 'mac',
70
- IOS: 'iOS',
71
- ANDROID: 'Android'
72
- };
73
- const _getMobileOS = () => {
74
- const userAgent = navigator.userAgent;
75
- // iOS, Android
76
- let rPlatform = /\(([a-zA-Z ]+);\s(?:[U]?[;]?)([\D]+)((?:[\d._]*))(?:.*[)][^\d]*)([\d.]*)\s/;
77
- let aMatches = userAgent.match(rPlatform);
78
- if (aMatches) {
79
- const rAppleDevices = /iPhone|iPad|iPod/;
80
- if (aMatches[0].match(rAppleDevices)) {
81
- aMatches[3] = aMatches[3].replace(/_/g, '.');
82
- return {
83
- name: OS.IOS,
84
- versionStr: aMatches[3]
85
- };
86
- }
87
- if (aMatches[2].match(/Android/)) {
88
- aMatches[2] = aMatches[2].replace(/\s/g, '');
89
- return {
90
- name: OS.ANDROID,
91
- versionStr: aMatches[3]
92
- };
93
- }
94
- }
95
- // Firefox on Android
96
- rPlatform = /\((Android)[\s]?([\d][.\d]*)?;.*Firefox\/[\d][.\d]*/;
97
- aMatches = userAgent.match(rPlatform);
98
- if (aMatches) {
99
- return {
100
- name: OS.ANDROID,
101
- versionStr: aMatches.length === 3 ? aMatches[2] : ''
102
- };
103
- }
104
- return {};
105
- };
106
- const _getDesktopOS = () => {
107
- const sPlatform = navigator.platform;
108
- if (sPlatform.indexOf('Win') !== -1) {
109
- const rVersion = /Windows NT (\d+).(\d)/i; // userAgent since windows 10: Windows NT 10[...]
110
- const uaResult = navigator.userAgent.match(rVersion);
111
- return {
112
- name: OS.WINDOWS,
113
- versionStr: (uaResult && uaResult[1]) || ''
114
- };
115
- }
116
- if (sPlatform.indexOf('Mac') !== -1) {
117
- return {
118
- name: OS.MACINTOSH,
119
- versionStr: ''
120
- };
121
- }
122
- return null;
123
- };
124
- const _getOS = () => _getMobileOS() || _getDesktopOS();
125
- const _setOS = () => {
126
- if (Device.os) {
127
- return;
128
- }
129
- Device.os = _getOS() || {};
130
- Device.os.OS = OS;
131
- Device.os.version = Device.os.versionStr ? parseFloat(Device.os.versionStr) : -1;
132
- if (Device.os.name) {
133
- Object.keys(OS).forEach((name) => {
134
- if (OS[name] === Device.os.name) {
135
- Device.os[name.toLowerCase()] = true;
136
- }
137
- });
138
- }
139
- };
140
- const getOS = () => {
141
- if (!Device.os) {
142
- _setOS();
143
- }
144
- return Device.os;
145
- };
146
- const isAndroid = () => {
147
- if (!Device.os) {
148
- _setOS();
149
- }
150
- return !!Device.os.android;
151
- };
152
- // * ******* Browser Detection ********
153
- /**
154
- * Contains information about the used browser.
155
- * @name Device.browser
156
- */
157
- /**
158
- * Enumeration containing the names of known browsers.
159
- * @name Device.browser.BROWSER
160
- *
161
- * The name of the browser.
162
- * @name Device.browser.name
163
- * @type String
164
- */
165
- /**
166
- * The version of the browser as <code>string</code>. Might be empty if no version can be determined.
167
- * @name Device.browser.versionStr
168
- * @type String
169
- */
170
- /**
171
- * The version of the browser as <code>float</code>. Might be <code>-1</code> if no version can be determined.
172
- * @name Device.browser.version
173
- * @type float
174
- */
175
- /**
176
- * If this flag is set to <code>true</code>, the mobile variant of the browser is used or
177
- * a tablet or phone device is detected. This information might not be available for all browsers.
178
- * @name Device.browser.mobile
179
- * @type boolean
180
- */
181
- /**
182
- * If this flag is set to <code>true</code>, the Microsoft Internet Explorer browser is used.
183
- * @name Device.browser.internet_explorer
184
- * @type boolean
185
- * @deprecated since 1.20, use {@link Device.browser.msie} instead.
186
- */
187
- /**
188
- * If this flag is set to <code>true</code>, the Microsoft Internet Explorer browser is used.
189
- * @name Device.browser.msie
190
- * @type boolean
191
- */
192
- /**
193
- * If this flag is set to <code>true</code>, the Microsoft Edge browser is used.
194
- * @name Device.browser.edge
195
- * @type boolean
196
- */
197
- /**
198
- * If this flag is set to <code>true</code>, the Mozilla Firefox browser is used.
199
- * @name Device.browser.firefox
200
- */
201
- /**
202
- * If this flag is set to <code>true</code>, the Google Chrome browser is used.
203
- * @name Device.browser.chrome
204
- * @type boolean
205
- *
206
- * If this flag is set to <code>true</code>, the Apple Safari browser is used.
207
- *
208
- * <b>Note:</b>
209
- * This flag is also <code>true</code> when the standalone (fullscreen) mode or webview is used on iOS devices.
210
- * Please also note the flags {@link Device.browser.fullscreen} and {@link Device.browser.webview}.
211
- *
212
- * @name Device.browser.safari
213
- * @type boolean
214
- */
215
- /**
216
- * If this flag is set to <code>true</code>, a browser featuring a Webkit engine is used.
217
- *
218
- * <b>Note:</b>
219
- * This flag is also <code>true</code> when the used browser was based on the Webkit engine, but
220
- * uses another rendering engine in the meantime. For example the Chrome browser started from version 28 and above
221
- * uses the Blink rendering engine.
222
- *
223
- * @name Device.browser.webkit
224
- * @type boolean
225
- */
226
- /**
227
- * If this flag is set to <code>true</code>, the Safari browser runs in standalone fullscreen mode on iOS.
228
- *
229
- * <b>Note:</b> This flag is only available if the Safari browser was detected. Furthermore, if this mode is detected,
230
- * technically not a standard Safari is used. There might be slight differences in behavior and detection, e.g.
231
- * the availability of {@link Device.browser.version}.
232
- *
233
- * @name Device.browser.fullscreen
234
- * @type boolean
235
- */
236
- /**
237
- * If this flag is set to <code>true</code>, the Safari browser runs in webview mode on iOS.
238
- *
239
- * <b>Note:</b> This flag is only available if the Safari browser was detected. Furthermore, if this mode is detected,
240
- * technically not a standard Safari is used. There might be slight differences in behavior and detection, e.g.
241
- * the availability of {@link Device.browser.version}.
242
- *
243
- * @name Device.browser.webview
244
- * @type boolean
245
- */
246
- /**
247
- * If this flag is set to <code>true</code>, the Phantom JS browser is used.
248
- * @name Device.browser.phantomJS
249
- * @type boolean
250
- */
251
- /**
252
- * The version of the used Webkit engine, if available.
253
- * @name Device.browser.webkitVersion
254
- * @type String
255
- */
256
- /**
257
- * If this flag is set to <code>true</code>, a browser featuring a Mozilla engine is used.
258
- * @name Device.browser.mozilla
259
- * @type boolean
260
- */
261
- /**
262
- * Internet Explorer browser name.
263
- * @name Device.browser.BROWSER.INTERNET_EXPLORER
264
- */
265
- /**
266
- * Edge browser name.
267
- * @name Device.browser.BROWSER.EDGE
268
- */
269
- /**
270
- * Firefox browser name.
271
- * @name Device.browser.BROWSER.FIREFOX
272
- */
273
- /**
274
- * Chrome browser name.
275
- * @name Device.browser.BROWSER.CHROME
276
- */
277
- /**
278
- * Safari browser name.
279
- * @name Device.browser.BROWSER.SAFARI
280
- */
281
- /**
282
- * Android stock browser name.
283
- * @name Device.browser.BROWSER.ANDROID
284
- */
285
- const BROWSER = {
286
- INTERNET_EXPLORER: 'ie',
287
- EDGE: 'ed',
288
- FIREFOX: 'ff',
289
- CHROME: 'cr',
290
- SAFARI: 'sf',
291
- ANDROID: 'an'
292
- };
293
- /* !
294
- * Taken from jQuery JavaScript Library v1.7.1
295
- * http://jquery.com/
296
- *
297
- * Copyright 2011, John Resig
298
- * Dual licensed under the MIT or GPL Version 2 licenses.
299
- * http://jquery.org/license
300
- *
301
- * Includes Sizzle.js
302
- * http://sizzlejs.com/
303
- * Copyright 2011, The Dojo Foundation
304
- * Released under the MIT, BSD, and GPL Licenses.
305
- *
306
- * Date: Mon Nov 21 21:11:03 2011 -0500
307
- */
308
- const _calcBrowser = () => {
309
- const sUserAgent = navigator.userAgent.toLowerCase();
310
- const rwebkit = /(webkit)[ /]([\w.]+)/;
311
- const rmsie = /(msie) ([\w.]+)/;
312
- const rmsie11 = /(trident)\/[\w.]+;.*rv:([\w.]+)/;
313
- const redge = /(edge)[ /]([\w.]+)/;
314
- const rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/;
315
- // WinPhone IE11 and MS Edge userAgents contain "WebKit" and "Mozilla" and therefore must be checked first
316
- const browserMatch = redge.exec(sUserAgent) ||
317
- rmsie11.exec(sUserAgent) ||
318
- rwebkit.exec(sUserAgent) ||
319
- rmsie.exec(sUserAgent) ||
320
- (sUserAgent.indexOf('compatible') < 0 && rmozilla.exec(sUserAgent)) ||
321
- [];
322
- const oRes = {
323
- browser: browserMatch[1] || '',
324
- version: browserMatch[2] || '0'
325
- };
326
- oRes[oRes.browser] = true;
327
- return oRes;
328
- };
329
- const _getBrowser = () => {
330
- const oBrowser = _calcBrowser();
331
- const sUserAgent = navigator.userAgent;
332
- const oNavigator = window.navigator;
333
- // jQuery checks for user agent strings. We differentiate between browsers
334
- let oExpMobile;
335
- let oResult;
336
- let fVersion;
337
- // Mozilla
338
- if (oBrowser.mozilla) {
339
- oExpMobile = /Mobile/;
340
- if (sUserAgent.match(/Firefox\/(\d+\.\d+)/)) {
341
- fVersion = parseFloat(RegExp.$1);
342
- oResult = {
343
- name: BROWSER.FIREFOX,
344
- versionStr: `${fVersion}`,
345
- version: fVersion,
346
- mozilla: true,
347
- mobile: oExpMobile.test(sUserAgent)
348
- };
349
- }
350
- else {
351
- // unknown mozilla browser
352
- oResult = {
353
- mobile: oExpMobile.test(sUserAgent),
354
- mozilla: true,
355
- version: -1
356
- };
357
- }
358
- }
359
- else if (oBrowser.webkit) {
360
- // webkit version is needed for calculation if the mobile android device is a tablet (calculation of other mobile devices work without)
361
- const regExpWebkitVersion = sUserAgent.toLowerCase().match(/webkit[/]([\d.]+)/);
362
- let webkitVersion;
363
- if (regExpWebkitVersion) {
364
- webkitVersion = regExpWebkitVersion[1];
365
- }
366
- oExpMobile = /Mobile/;
367
- const aChromeMatch = sUserAgent.match(/(Chrome|CriOS)\/(\d+\.\d+).\d+/);
368
- const aFirefoxMatch = sUserAgent.match(/FxiOS\/(\d+\.\d+)/);
369
- const aAndroidMatch = sUserAgent.match(/Android .+ Version\/(\d+\.\d+)/);
370
- if (aChromeMatch || aFirefoxMatch || aAndroidMatch) {
371
- let sName;
372
- let sVersion;
373
- let bMobile;
374
- if (aChromeMatch) {
375
- sName = BROWSER.CHROME;
376
- bMobile = oExpMobile.test(sUserAgent);
377
- sVersion = parseFloat(aChromeMatch[2]);
378
- }
379
- else if (aFirefoxMatch) {
380
- sName = BROWSER.FIREFOX;
381
- bMobile = true;
382
- sVersion = parseFloat(aFirefoxMatch[1]);
383
- }
384
- else if (aAndroidMatch) {
385
- sName = BROWSER.ANDROID;
386
- bMobile = oExpMobile.test(sUserAgent);
387
- sVersion = parseFloat(aAndroidMatch[1]);
388
- }
389
- oResult = {
390
- name: sName,
391
- mobile: bMobile,
392
- versionStr: `${sVersion}`,
393
- version: sVersion,
394
- webkit: true,
395
- webkitVersion
396
- };
397
- }
398
- else {
399
- // Safari might have an issue with sUserAgent.match(...); thus changing
400
- const oExp = /(Version|PhantomJS)\/(\d+\.\d+).*Safari/;
401
- const bStandalone = oNavigator.standalone;
402
- if (oExp.test(sUserAgent)) {
403
- const aParts = oExp.exec(sUserAgent);
404
- fVersion = parseFloat(aParts[2]);
405
- oResult = {
406
- name: BROWSER.SAFARI,
407
- versionStr: `${fVersion}`,
408
- fullscreen: false,
409
- webview: false,
410
- version: fVersion,
411
- mobile: oExpMobile.test(sUserAgent),
412
- webkit: true,
413
- webkitVersion,
414
- phantomJS: aParts[1] === 'PhantomJS'
415
- };
416
- }
417
- else if (/iPhone|iPad|iPod/.test(sUserAgent) &&
418
- !/CriOS/.test(sUserAgent) &&
419
- !/FxiOS/.test(sUserAgent) &&
420
- (bStandalone === true || bStandalone === false)) {
421
- // WebView or Standalone mode on iOS
422
- oResult = {
423
- name: BROWSER.SAFARI,
424
- version: -1,
425
- fullscreen: bStandalone,
426
- webview: !bStandalone,
427
- mobile: oExpMobile.test(sUserAgent),
428
- webkit: true,
429
- webkitVersion
430
- };
431
- }
432
- else {
433
- // other webkit based browser
434
- oResult = {
435
- mobile: oExpMobile.test(sUserAgent),
436
- webkit: true,
437
- webkitVersion,
438
- version: -1
439
- };
440
- }
441
- }
442
- }
443
- else if (oBrowser.msie || oBrowser.trident) {
444
- fVersion = parseFloat(oBrowser.version);
445
- oResult = {
446
- name: BROWSER.INTERNET_EXPLORER,
447
- versionStr: `${fVersion}`,
448
- version: fVersion,
449
- msie: true,
450
- mobile: false
451
- };
452
- }
453
- else if (oBrowser.edge) {
454
- fVersion = parseFloat(oBrowser.version);
455
- oResult = {
456
- name: BROWSER.EDGE,
457
- versionStr: `${fVersion}`,
458
- version: fVersion,
459
- edge: true
460
- };
461
- }
462
- else {
463
- oResult = {
464
- name: '',
465
- versionStr: '',
466
- version: -1,
467
- mobile: false
468
- };
469
- }
470
- return oResult;
471
- };
472
- const _setBrowser = () => {
473
- Device.browser = _getBrowser();
474
- Device.browser.BROWSER = BROWSER;
475
- if (Device.browser.name) {
476
- Object.keys(BROWSER).forEach((b) => {
477
- if (BROWSER[b] === Device.browser.name) {
478
- Device.browser[b.toLowerCase()] = true;
479
- }
480
- });
481
- }
482
- };
483
- const getBrowser = () => {
484
- if (!Device.browser) {
485
- _setBrowser();
486
- }
487
- return Device.browser;
488
- };
489
- const isIE = () => {
490
- if (!Device.browser) {
491
- _setBrowser();
492
- }
493
- return !!Device.browser.msie;
494
- };
495
- const isEdge = () => {
496
- if (!Device.browser) {
497
- _setBrowser();
498
- }
499
- return !!Device.browser.edge;
500
- };
501
- const isChrome = () => {
502
- if (!Device.browser) {
503
- _setBrowser();
504
- }
505
- return !!Device.browser.chrome;
506
- };
507
- const isFF = () => {
508
- if (!Device.browser) {
509
- _setBrowser();
510
- }
511
- return !!Device.browser.firefox;
512
- };
513
- const isSafari = () => {
514
- if (!Device.browser) {
515
- _setBrowser();
516
- }
517
- return !!Device.browser.safari;
518
- };
519
- // * ******* Support Detection ********
520
- const _setSupport = () => {
521
- if (Device.support) {
522
- return;
523
- }
524
- if (!Device.browser) {
525
- _setBrowser();
526
- }
527
- Device.support = {};
528
- Device.support.touch = !!('ontouchstart' in window ||
529
- navigator.maxTouchPoints > 0 ||
530
- (window.DocumentTouch && document instanceof window.DocumentTouch));
531
- };
532
- const supportTouch = () => {
533
- if (!Device.support) {
534
- _setSupport();
535
- }
536
- return !!Device.support.touch;
537
- };
538
- // * ******* System Detection ********
539
- /**
540
- * Provides a basic categorization of the used device based on various indicators.
541
- *
542
- * <b>Note:</b> Depending on the capabilities of the device it is also possible that multiple flags are set to <code>true</code>.
543
- *
544
- * @namespace
545
- * @name Device.system
546
- */
547
- /**
548
- * If this flag is set to <code>true</code>, the device is recognized as a phone.
549
- *
550
- * @name Device.system.phone
551
- * @type boolean
552
- */
553
- /**
554
- * @name Device.system.SYSTEMTYPE
555
- * Enumeration containing the names of known types of the devices.
556
- */
557
- const SYSTEMTYPE = {
558
- TABLET: 'tablet',
559
- PHONE: 'phone',
560
- DESKTOP: 'desktop',
561
- COMBI: 'combi'
562
- };
563
- const _isTablet = () => {
564
- const sUserAgent = navigator.userAgent;
565
- if (Device.os.name === Device.os.OS.IOS) {
566
- return /ipad/i.test(sUserAgent);
567
- }
568
- // in real mobile device
569
- if (supportTouch()) {
570
- if (Device.os.windows && Device.os.version >= 8) {
571
- return true;
572
- }
573
- if (Device.browser.chrome && Device.os.android && Device.os.version >= 4.4) {
574
- return !/Mobile Safari\/[.0-9]+/.test(sUserAgent);
575
- }
576
- let densityFactor = window.devicePixelRatio ? window.devicePixelRatio : 1; // may be undefined in Windows Phone devices
577
- // On Android sometimes window.screen.width returns the logical CSS pixels, sometimes the physical device pixels;
578
- // Tests on multiple devices suggest this depends on the Webkit version.
579
- // The Webkit patch which changed the behavior was done here: https://bugs.webkit.org/show_bug.cgi?id=106460
580
- // Chrome 27 with Webkit 537.36 returns the logical pixels,
581
- // Chrome 18 with Webkit 535.19 returns the physical pixels.
582
- // The BlackBerry 10 browser with Webkit 537.10+ returns the physical pixels.
583
- // So it appears like somewhere above Webkit 537.10 we do not hve to divide by the devicePixelRatio anymore.
584
- if (Device.os.android && Device.browser.webkit && parseFloat(Device.browser.webkitVersion) > 537.1) {
585
- densityFactor = 1;
586
- }
587
- // this is how android distinguishes between tablet and phone
588
- // http://android-developers.blogspot.de/2011/07/new-tools-for-managing-screen-sizes.html
589
- const bTablet = Math.min(window.screen.width / densityFactor, window.screen.height / densityFactor) >= 600;
590
- // special workaround for Nexus 7 where the window.screen.width is 600px or 601px in portrait mode (=> tablet)
591
- // but window.screen.height 552px in landscape mode (=> phone), because the browser UI takes some space on top.
592
- // So the detected device type depends on the orientation :-(
593
- // actually this is a Chrome bug, as "width"/"height" should return the entire screen's dimensions and
594
- // "availWidth"/"availHeight" should return the size available after subtracting the browser UI
595
- /*
596
- if (isLandscape() &&
597
- (window.screen.height === 552 || window.screen.height === 553) // old/new Nexus 7
598
- &&
599
- (/Nexus 7/i.test(sUserAgent))) {
600
- bTablet = true;
601
- }
602
- */
603
- return bTablet;
604
- }
605
- // This simple android phone detection can be used here because this is the mobile emulation mode in desktop browser
606
- const bAndroidPhone = /(?=android)(?=.*mobile)/i.test(sUserAgent);
607
- // in desktop browser, it's detected as tablet when
608
- // 1. Windows 8 device with a touch screen where "Touch" is contained in the userAgent
609
- // 2. Android emulation and it's not an Android phone
610
- return (Device.browser.msie && sUserAgent.indexOf('Touch') !== -1) || (Device.os.android && !bAndroidPhone);
611
- };
612
- const _getSystem = () => {
613
- const bTabletDetected = _isTablet();
614
- const isWin8Upwards = Device.os.windows && Device.os.version >= 8;
615
- const oSystem = {};
616
- oSystem.tablet = !!((Device.support.touch || isWin8Upwards) && bTabletDetected);
617
- oSystem.phone = !!((Device.os.windows_phone || Device.support.touch) && !bTabletDetected);
618
- oSystem.desktop = !!((!oSystem.tablet && !oSystem.phone) || isWin8Upwards);
619
- oSystem.combi = oSystem.desktop && oSystem.tablet;
620
- oSystem.SYSTEMTYPE = SYSTEMTYPE;
621
- return oSystem;
622
- };
623
- const _setSystem = () => {
624
- _setSupport();
625
- _setOS();
626
- Device.system = {};
627
- Device.system = _getSystem();
628
- if (Device.system.tablet || Device.system.phone) {
629
- Device.browser.mobile = true;
630
- }
631
- };
632
- const getSystem = () => {
633
- if (!Device.system) {
634
- _setSystem();
635
- }
636
- return Device.system;
637
- };
638
- const isDesktop = () => {
639
- if (!Device.system) {
640
- _setSystem();
641
- }
642
- return Device.system.desktop;
643
- };
644
- const isTablet = () => {
645
- if (!Device.system) {
646
- _setSystem();
647
- }
648
- return Device.system.tablet;
649
- };
650
- const isPhone = () => {
651
- if (!Device.system) {
652
- _setSystem();
653
- }
654
- return Device.system.phone;
655
- };
656
- const isMobile = () => {
657
- if (!Device.system) {
658
- _setSystem();
659
- }
660
- return Device.browser.mobile;
661
- };
662
- export { isIE, isEdge, isChrome, isFF, isSafari, isMobile, isDesktop, isTablet, isPhone, isAndroid, getOS, getSystem, getBrowser, supportTouch };
663
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGV2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvYmFyc2Etbm92aW4tcmF5LWNvcmUvc3JjL2xpYi9kZXZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsb0JBQW9CO0FBRXBCLE1BQU0sTUFBTSxHQUEyQixFQUFFLENBQUM7QUFFMUMsa0NBQWtDO0FBRWxDOzs7R0FHRztBQUVIOzs7R0FHRztBQUVIOzs7O0dBSUc7QUFFSDs7OztHQUlHO0FBRUg7Ozs7R0FJRztBQUVIOzs7O0dBSUc7QUFFSDs7OztHQUlHO0FBRUg7Ozs7R0FJRztBQUVIOzs7O0dBSUc7QUFFSDs7OztHQUlHO0FBRUg7Ozs7R0FJRztBQUVIOzs7O0dBSUc7QUFFSDs7OztHQUlHO0FBRUgsTUFBTSxFQUFFLEdBQUc7SUFDUCxPQUFPLEVBQUUsS0FBSztJQUNkLFNBQVMsRUFBRSxLQUFLO0lBQ2hCLEdBQUcsRUFBRSxLQUFLO0lBQ1YsT0FBTyxFQUFFLFNBQVM7Q0FDckIsQ0FBQztBQUVGLE1BQU0sWUFBWSxHQUFHLEdBQUcsRUFBRTtJQUN0QixNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDO0lBRXRDLGVBQWU7SUFDZixJQUFJLFNBQVMsR0FBRyw0RUFBNEUsQ0FBQztJQUM3RixJQUFJLFFBQVEsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBRTFDLElBQUksUUFBUSxFQUFFLENBQUM7UUFDWCxNQUFNLGFBQWEsR0FBRyxrQkFBa0IsQ0FBQztRQUV6QyxJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQztZQUNuQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFFN0MsT0FBTztnQkFDSCxJQUFJLEVBQUUsRUFBRSxD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QyxPQUFPLENBQUMsTUFBTSxDQUFDO0FBQ2pDLENBQUMsQ0FBQztBQUVGLE9BQU8sRUFDSCxJQUFJLEVBQ0osTUFBTSxFQUNOLFFBQVEsRUFDUixJQUFJLEVBQ0osUUFBUSxFQUNSLFFBQVEsRUFDUixTQUFTLEVBQ1QsUUFBUSxFQUNSLE9BQU8sRUFDUCxTQUFTLEVBQ1QsS0FBSyxFQUNMLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNmLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSAqL1xyXG5cclxuY29uc3QgRGV2aWNlOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge307XHJcblxyXG4vLyAqICoqKioqKiogT1MgRGV0ZWN0aW9uICoqKioqKioqXHJcblxyXG4vKipcclxuICogQ29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG9wZXJhdGluZyBzeXN0ZW0gb2YgdGhlIERldmljZS5cclxuICogQG5hbWUgRGV2aWNlLm9zXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIEVudW1lcmF0aW9uIGNvbnRhaW5pbmcgdGhlIG5hbWVzIG9mIGtub3duIG9wZXJhdGluZyBzeXN0ZW1zLlxyXG4gKiBAbmFtZSBEZXZpY2Uub3MuT1NcclxuICovXHJcblxyXG4vKipcclxuICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXHJcbiAqIEBuYW1lIERldmljZS5vcy5uYW1lXHJcbiAqIEB0eXBlIFN0cmluZ1xyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBUaGUgdmVyc2lvbiBvZiB0aGUgb3BlcmF0aW5nIHN5c3RlbSBhcyA8Y29kZT5zdHJpbmc8L2NvZGU+LiBNaWdodCBiZSBlbXB0eSBpZiBubyB2ZXJzaW9uIGNhbiBiZSBkZXRlcm1pbmVkLlxyXG4gKiBAbmFtZSBEZXZpY2Uub3MudmVyc2lvblN0clxyXG4gKiBAdHlwZSBTdHJpbmdcclxuICovXHJcblxyXG4vKipcclxuICogVGhlIHZlcnNpb24gb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0gYXMgPGNvZGU+ZmxvYXQ8L2NvZGU+LiBNaWdodCBiZSA8Y29kZT4tMTwvY29kZT4gaWYgbm8gdmVyc2lvbiBjYW4gYmUgZGV0ZXJtaW5lZC5cclxuICogQG5hbWUgRGV2aWNlLm9zLnZlcnNpb25cclxuICogQHR5cGUgZmxvYXRcclxuICovXHJcblxyXG4vKipcclxuICogSWYgdGhpcyBmbGFnIGlzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiwgYSBXaW5kb3dzIG9wZXJhdGluZyBzeXN0ZW0gaXMgdXNlZC5cclxuICogQG5hbWUgRGV2aWNlLm9zLndpbmRvd3NcclxuICogQHR5cGUgYm9vbGVhblxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBJZiB0aGlzIGZsYWcgaXMgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+LCBhIE1hYyBvcGVyYXRpbmcgc3lzdGVtIGlzIHVzZWQuXHJcbiAqIEBuYW1lIERldmljZS5vcy5tYWNpbnRvc2hcclxuICogQHR5cGUgYm9vbGVhblxyXG4gKi9cclxuXHJcbi8qXHJcbiAqIElmIHRoaXMgZmxhZyBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4sIGFuIGlPUyBvcGVyYXRpbmcgc3lzdGVtIGlzIHVzZWQuXHJcbiAqIEBuYW1lIERldmljZS5vcy5pb3NcclxuICogQHR5cGUgYm9vbGVhblxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBJZiB0aGlzIGZsYWcgaXMgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+LCBhbiBBbmRyb2lkIG9wZXJhdGluZyBzeXN0ZW0gaXMgdXNlZC5cclxuICogQG5hbWUgRGV2aWNlLm9zLmFuZHJvaWRcclxuICogQHR5cGUgYm9vbGVhblxyXG4gKi9cclxuXHJcbi8qXHJcbiAqIFdpbmRvd3Mgb3BlcmF0aW5nIHN5c3RlbSBuYW1lLlxyXG4gKiBAc2VlIERldmljZS5vcy5uYW1lXHJcbiAqIEBuYW1lIERldmljZS5vcy5PUy5XSU5ET1dTXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIE1BQyBvcGVyYXRpbmcgc3lzdGVtIG5hbWUuXHJcbiAqIEBzZWUgRGV2aWNlLm9zLm5hbWVcclxuICogQG5hbWUgRGV2aWNlLm9zLk9TLk1BQ0lOVE9TSFxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBpT1Mgb3BlcmF0aW5nIHN5c3RlbSBuYW1lLlxyXG4gKiBAc2VlIERldmljZS5vcy5uYW1lXHJcbiAqIEBuYW1lIERldmljZS5vcy5PUy5JT1NcclxuICovXHJcblxyXG4vKipcclxuICogQW5kcm9pZCBvcGVyYXRpbmcgc3lzdGVtIG5hbWUuXHJcbiAqIEBzZWUgRGV2aWNlLm9zLm5hbWVcclxuICogQG5hbWUgRGV2aWNlLm9zLk9TLkFORFJPSURcclxuICovXHJcblxyXG5jb25zdCBPUyA9IHtcclxuICAgIFdJTkRPV1M6ICd3aW4nLFxyXG4gICAgTUFDSU5UT1NIOiAnbWFjJyxcclxuICAgIElPUzogJ2lPUycsXHJcbiAgICBBTkRST0lEOiAnQW5kcm9pZCdcclxufTtcclxuXHJcbmNvbnN0IF9nZXRNb2JpbGVPUyA9ICgpID0+IHtcclxuICAgIGNvbnN0IHVzZXJBZ2VudCA9IG5hdmlnYXRvci51c2VyQWdlbnQ7XHJcblxyXG4gICAgLy8gaU9TLCBBbmRyb2lkXHJcbiAgICBsZXQgclBsYXRmb3JtID0gL1xcKChbYS16QS1aIF0rKTtcXHMoPzpbVV0/WztdPykoW1xcRF0rKSgoPzpbXFxkLl9dKikpKD86LipbKV1bXlxcZF0qKShbXFxkLl0qKVxccy87XHJcbiAgICBsZXQgYU1hdGNoZXMgPSB1c2VyQWdlbnQubWF0Y2goclBsYXRmb3JtKTtcclxuXHJcbiAgICBpZiAoYU1hdGNoZXMpIHtcclxuICAgICAgICBjb25zdCByQXBwbGVEZXZpY2VzID0gL2lQaG9uZXxpUGFkfGlQb2QvO1xyXG5cclxuICAgICAgICBpZiAoYU1hdGNoZXNbMF0ubWF0Y2gockFwcGxlRGV2aWNlcykpIHtcclxuICAgICAgICAgICAgYU1hdGNoZXNbM10gPSBhTWF0Y2hlc1szXS5yZXBsYWNlKC9fL2csICcuJyk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgbmFtZTogT1MuSU9TLFxyXG4gICAgICAgICAgICAgICAgdmVyc2lvblN0cjogYU1hdGNoZXNbM11cclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChhTWF0Y2hlc1syXS5tYXRjaCgvQW5kcm9pZC8pKSB7XHJcbiAgICAgICAgICAgIGFNYXRjaGVzWzJdID0gYU1hdGNoZXNbMl0ucmVwbGFjZSgvXFxzL2csICcnKTtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIG5hbWU6IE9TLkFORFJPSUQsXHJcbiAgICAgICAgICAgICAgICB2ZXJzaW9uU3RyOiBhTWF0Y2hlc1szXVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBGaXJlZm94IG9uIEFuZHJvaWRcclxuICAgIHJQbGF0Zm9ybSA9IC9cXCgoQW5kcm9pZClbXFxzXT8oW1xcZF1bLlxcZF0qKT87LipGaXJlZm94XFwvW1xcZF1bLlxcZF0qLztcclxuICAgIGFNYXRjaGVzID0gdXNlckFnZW50Lm1hdGNoKHJQbGF0Zm9ybSk7XHJcbiAgICBpZiAoYU1hdGNoZXMpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBuYW1lOiBPUy5BTkRST0lELFxyXG4gICAgICAgICAgICB2ZXJzaW9uU3RyOiBhTWF0Y2hlcy5sZW5ndGggPT09IDMgPyBhTWF0Y2hlc1syXSA6ICcnXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIHJldHVybiB7fTtcclxufTtcclxuXHJcbmNvbnN0IF9nZXREZXNrdG9wT1MgPSAoKSA9PiB7XHJcbiAgICBjb25zdCBzUGxhdGZvcm0gPSBuYXZpZ2F0b3IucGxhdGZvcm07XHJcbiAgICBpZiAoc1BsYXRmb3JtLmluZGV4T2YoJ1dpbicpICE9PSAtMSkge1xyXG4gICAgICAgIGNvbnN0IHJWZXJzaW9uID0gL1dpbmRvd3MgTlQgKFxcZCspLihcXGQpL2k7IC8vIHVzZXJBZ2VudCBzaW5jZSB3aW5kb3dzIDEwOiBXaW5kb3dzIE5UIDEwWy4uLl1cclxuICAgICAgICBjb25zdCB1YVJlc3VsdCA9IG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goclZlcnNpb24pO1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBuYW1lOiBPUy5XSU5ET1dTLFxyXG4gICAgICAgICAgICB2ZXJzaW9uU3RyOiAodWFSZXN1bHQgJiYgdWFSZXN1bHRbMV0pIHx8ICcnXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoc1BsYXRmb3JtLmluZGV4T2YoJ01hYycpICE9PSAtMSkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIG5hbWU6IE9TLk1BQ0lOVE9TSCxcclxuICAgICAgICAgICAgdmVyc2lvblN0cjogJydcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBudWxsO1xyXG59O1xyXG5cclxuY29uc3QgX2dldE9TID0gKCkgPT4gX2dldE1vYmlsZU9TKCkgfHwgX2dldERlc2t0b3BPUygpO1xyXG5cclxuY29uc3QgX3NldE9TID0gKCkgPT4ge1xyXG4gICAgaWYgKERldmljZS5vcykge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBEZXZpY2Uub3MgPSBfZ2V0T1MoKSB8fCB7fTtcclxuICAgIERldmljZS5vcy5PUyA9IE9TO1xyXG4gICAgRGV2aWNlLm9zLnZlcnNpb24gPSBEZXZpY2Uub3MudmVyc2lvblN0ciA/IHBhcnNlRmxvYXQoRGV2aWNlLm9zLnZlcnNpb25TdHIpIDogLTE7XHJcblxyXG4gICAgaWYgKERldmljZS5vcy5uYW1lKSB7XHJcbiAgICAgICAgT2JqZWN0LmtleXMoT1MpLmZvckVhY2goKG5hbWUpID0+IHtcclxuICAgICAgICAgICAgaWYgKE9TW25hbWVdID09PSBEZXZpY2Uub3MubmFtZSkge1xyXG4gICAgICAgICAgICAgICAgRGV2aWNlLm9zW25hbWUudG9Mb3dlckNhc2UoKV0gPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn07XHJcblxyXG5jb25zdCBnZXRPUyA9ICgpID0+IHtcclxuICAgIGlmICghRGV2aWNlLm9zKSB7XHJcbiAgICAgICAgX3NldE9TKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIERldmljZS5vcztcclxufTtcclxuXHJcbmNvbnN0IGlzQW5kcm9pZCA9ICgpID0+IHtcclxuICAgIGlmICghRGV2aWNlLm9zKSB7XHJcbiAgICAgICAgX3NldE9TKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuICEhRGV2aWNlLm9zLmFuZHJvaWQ7XHJcbn07XHJcblxyXG4vLyAqICoqKioqKiogQnJvd3NlciBEZXRlY3Rpb24gKioqKioqKipcclxuXHJcbi8qKlxyXG4gKiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdXNlZCBicm93c2VyLlxyXG4gKiBAbmFtZSBEZXZpY2UuYnJvd3NlclxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBFbnVtZXJhdGlvbiBjb250YWluaW5nIHRoZSBuYW1lcyBvZiBrbm93biBicm93c2Vycy5cclxuICogQG5hbWUgRGV2aWNlLmJyb3dzZXIuQlJPV1NFUlxyXG4gKlxyXG4gKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3Nlci5cclxuICogQG5hbWUgRGV2aWNlLmJyb3dzZXIubmFtZVxyXG4gKiBAdHlwZSBTdHJpbmdcclxuICovXHJcblxyXG4vKipcclxuICogVGhlIHZlcnNpb24gb2YgdGhlIGJyb3dzZXIgYXMgPGNvZGU+c3RyaW5nPC9jb2RlPi4gTWlnaHQgYmUgZW1wdHkgaWYgbm8gdmVyc2lvbiBjYW4gYmUgZGV0ZXJtaW5lZC5cclxuICogQG5hbWUgRGV2aWNlLmJyb3dzZXIudmVyc2lvblN0clxyXG4gKiBAdHlwZSBTdHJpbmdcclxuICovXHJcblxyXG4vKipcclxuICogVGhlIHZlcnNpb24gb2YgdGhlIGJyb3dzZXIgYXMgPGNvZGU+ZmxvYXQ8L2NvZGU+LiBNaWdodCBiZSA8Y29kZT4tMTwvY29kZT4gaWYgbm8gdmVyc2lvbiBjYW4gYmUgZGV0ZXJtaW5lZC5cclxuICogQG5hbWUgRGV2aWNlLmJyb3dzZXIudmVyc2lvblxyXG4gKiBAdHlwZSBmbG9hdFxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBJZiB0aGlzIGZsYWcgaXMgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+LCB0aGUgbW9iaWxlIHZhcmlhbnQgb2YgdGhlIGJyb3dzZXIgaXMgdXNlZCBvclxyXG4gKiBhIHRhYmxldCBvciBwaG9uZSBkZXZpY2UgaXMgZGV0ZWN0ZWQuIFRoaXMgaW5mb3JtYXRpb24gbWlnaHQgbm90IGJlIGF2YWlsYWJsZSBmb3IgYWxsIGJyb3dzZXJzLlxyXG4gKiBAbmFtZSBEZXZpY2UuYnJvd3Nlci5tb2JpbGVcclxuICogQHR5cGUgYm9vbGVhblxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBJZiB0aGlzIGZsYWcgaXMgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+LCB0aGUgTWljcm9zb2Z0IEludGVybmV0IEV4cGxvcmVyIGJyb3dzZXIgaXMgdXNlZC5cclxuICogQG5hbWUgRGV2aWNlLmJyb3dzZXIuaW50ZXJuZXRfZXhwbG9yZXJcclxuICogQHR5cGUgYm9vbGVhblxyXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSAxLjIwLCB1c2Uge0BsaW5rIERldmljZS5icm93c2VyLm1zaWV9IGluc3RlYWQuXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIElmIHRoaXMgZmxhZyBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4sIHRoZSBNaWNyb3NvZnQgSW50ZXJuZXQgRXhwbG9yZXIgYnJvd3NlciBpcyB1c2VkLlxyXG4gKiBAbmFtZSBEZXZpY2UuYnJvd3Nlci5tc2llXHJcbiAqIEB0eXBlIGJvb2xlYW5cclxuICovXHJcblxyXG4vKipcclxuICogSWYgdGhpcyBmbGFnIGlzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiwgdGhlIE1pY3Jvc29mdCBFZGdlIGJyb3dzZXIgaXMgdXNlZC5cclxuICogQG5hbWUgRGV2aWNlLmJyb3dzZXIuZWRnZVxyXG4gKiBAdHlwZSBib29sZWFuXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIElmIHRoaXMgZmxhZyBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4sIHRoZSBNb3ppbGxhIEZpcmVmb3ggYnJvd3NlciBpcyB1c2VkLlxyXG4gKiBAbmFtZSBEZXZpY2UuYnJvd3Nlci5maXJlZm94XHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIElmIHRoaXMgZmxhZyBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4sIHRoZSBHb29nbGUgQ2hyb21lIGJyb3dzZXIgaXMgdXNlZC5cclxuICogQG5hbWUgRGV2aWNlLmJyb3dzZXIuY2hyb21lXHJcbiAqIEB0eXBlIGJvb2xlYW5cclxuICpcclxuICogSWYgdGhpcyBmbGFnIGlzIHNldCB0byA8Y29kZT50cnVlPC9jb2RlPiwgdGhlIEFwcGxlIFNhZmFyaSBicm93c2VyIGlzIHVzZWQuXHJcbiAqXHJcbiAqIDxiPk5vdGU6PC9iPlxyXG4gKiBUaGlzIGZsYWcgaXMgYWxzbyA8Y29kZT50cnVlPC9jb2RlPiB3aGVuIHRoZSBzdGFuZGFsb25lIChmdWxsc2NyZWVuKSBtb2RlIG9yIHdlYnZpZXcgaXMgdXNlZCBvbiBpT1MgZGV2aWNlcy5cclxuICogUGxlYXNlIGFsc28gbm90ZSB0aGUgZmxhZ3Mge0BsaW5rIERldmljZS5icm93c2VyLmZ1bGxzY3JlZW59IGFuZCB7QGxpbmsgRGV2aWNlLmJyb3dzZXIud2Vidmlld30uXHJcbiAqXHJcbiAqIEBuYW1lIERldmljZS5icm93c2VyLnNhZmFyaVxyXG4gKiBAdHlwZSBib29sZWFuXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIElmIHRoaXMgZmxhZyBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4sIGEgYnJvd3NlciBmZWF0dXJpbmcgYSBXZWJraXQgZW5naW5lIGlzIHVzZWQuXHJcbiAqXHJcbiAqIDxiPk5vdGU6PC9iPlxyXG4gKiBUaGlzIGZsYWcgaXMgYWxzbyA8Y29kZT50cnVlPC9jb2RlPiB3aGVuIHRoZSB1c2VkIGJyb3dzZXIgd2FzIGJhc2VkIG9uIHRoZSBXZWJraXQgZW5naW5lLCBidXRcclxuICogdXNlcyBhbm90aGVyIHJlbmRlcmluZyBlbmdpbmUgaW4gdGhlIG1lYW50aW1lLiBGb3IgZXhhbXBsZSB0aGUgQ2hyb21lIGJyb3dzZXIgc3RhcnRlZCBmcm9tIHZlcnNpb24gMjggYW5kIGFib3ZlXHJcbiAqIHVzZXMgdGhlIEJsaW5rIHJlbmRlcmluZyBlbmdpbmUuXHJcbiAqXHJcbiAqIEBuYW1lIERldmljZS5icm93c2VyLndlYmtpdFxyXG4gKiBAdHlwZSBib29sZWFuXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIElmIHRoaXMgZmxhZyBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4sIHRoZSBTYWZhcmkgYnJvd3NlciBydW5zIGluIHN0YW5kYWxvbmUgZnVsbHNjcmVlbiBtb2RlIG9uIGlPUy5cclxuICpcclxuICogPGI+Tm90ZTo8L2I+IFRoaXMgZmxhZyBpcyBvbmx5IGF2YWlsYWJsZSBpZiB0aGUgU2FmYXJpIGJyb3dzZXIgd2FzIGRldGVjdGVkLiBGdXJ0aGVybW9yZSwgaWYgdGhpcyBtb2RlIGlzIGRldGVjdGVkLFxyXG4gKiB0ZWNobmljYWxseSBub3QgYSBzdGFuZGFyZCBTYWZhcmkgaXMgdXNlZC4gVGhlcmUgbWlnaHQgYmUgc2xpZ2h0IGRpZmZlcmVuY2VzIGluIGJlaGF2aW9yIGFuZCBkZXRlY3Rpb24sIGUuZy5cclxuICogdGhlIGF2YWlsYWJpbGl0eSBvZiB7QGxpbmsgRGV2aWNlLmJyb3dzZXIudmVyc2lvbn0uXHJcbiAqXHJcbiAqIEBuYW1lIERldmljZS5icm93c2VyLmZ1bGxzY3JlZW5cclxuICogQHR5cGUgYm9vbGVhblxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBJZiB0aGlzIGZsYWcgaXMgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+LCB0aGUgU2FmYXJpIGJyb3dzZXIgcnVucyBpbiB3ZWJ2aWV3IG1vZGUgb24gaU9TLlxyXG4gKlxyXG4gKiA8Yj5Ob3RlOjwvYj4gVGhpcyBmbGFnIGlzIG9ubHkgYXZhaWxhYmxlIGlmIHRoZSBTYWZhcmkgYnJvd3NlciB3YXMgZGV0ZWN0ZWQuIEZ1cnRoZXJtb3JlLCBpZiB0aGlzIG1vZGUgaXMgZGV0ZWN0ZWQsXHJcbiAqIHRlY2huaWNhbGx5IG5vdCBhIHN0YW5kYXJkIFNhZmFyaSBpcyB1c2VkLiBUaGVyZSBtaWdodCBiZSBzbGlnaHQgZGlmZmVyZW5jZXMgaW4gYmVoYXZpb3IgYW5kIGRldGVjdGlvbiwgZS5nLlxyXG4gKiB0aGUgYXZhaWxhYmlsaXR5IG9mIHtAbGluayBEZXZpY2UuYnJvd3Nlci52ZXJzaW9ufS5cclxuICpcclxuICogQG5hbWUgRGV2aWNlLmJyb3dzZXIud2Vidmlld1xyXG4gKiBAdHlwZSBib29sZWFuXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIElmIHRoaXMgZmxhZyBpcyBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4sIHRoZSBQaGFudG9tIEpTIGJyb3dzZXIgaXMgdXNlZC5cclxuICogQG5hbWUgRGV2aWNlLmJyb3dzZXIucGhhbnRvbUpTXHJcbiAqIEB0eXBlIGJvb2xlYW5cclxuICovXHJcblxyXG4vKipcclxuICogVGhlIHZlcnNpb24gb2YgdGhlIHVzZWQgV2Via2l0IGVuZ2luZSwgaWYgYXZhaWxhYmxlLlxyXG4gKiBAbmFtZSBEZXZpY2UuYnJvd3Nlci53ZWJraXRWZXJzaW9uXHJcbiAqIEB0eXBlIFN0cmluZ1xyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBJZiB0aGlzIGZsYWcgaXMgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+LCBhIGJyb3dzZXIgZmVhdHVyaW5nIGEgTW96aWxsYSBlbmdpbmUgaXMgdXNlZC5cclxuICogQG5hbWUgRGV2aWNlLmJyb3dzZXIubW96aWxsYVxyXG4gKiBAdHlwZSBib29sZWFuXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIEludGVybmV0IEV4cGxvcmVyIGJyb3dzZXIgbmFtZS5cclxuICogQG5hbWUgRGV2aWNlLmJyb3dzZXIuQlJPV1NFUi5JTlRFUk5FVF9FWFBMT1JFUlxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBFZGdlIGJyb3dzZXIgbmFtZS5cclxuICogQG5hbWUgRGV2aWNlLmJyb3dzZXIuQlJPV1NFUi5FREdFXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIEZpcmVmb3ggYnJvd3NlciBuYW1lLlxyXG4gKiBAbmFtZSBEZXZpY2UuYnJvd3Nlci5CUk9XU0VSLkZJUkVGT1hcclxuICovXHJcblxyXG4vKipcclxuICogQ2hyb21lIGJyb3dzZXIgbmFtZS5cclxuICogQG5hbWUgRGV2aWNlLmJyb3dzZXIuQlJPV1NFUi5DSFJPTUVcclxuICovXHJcblxyXG4vKipcclxuICogU2FmYXJpIGJyb3dzZXIgbmFtZS5cclxuICogQG5hbWUgRGV2aWNlLmJyb3dzZXIuQlJPV1NFUi5TQUZBUklcclxuICovXHJcblxyXG4vKipcclxuICogQW5kcm9pZCBzdG9jayBicm93c2VyIG5hbWUuXHJcbiAqIEBuYW1lIERldmljZS5icm93c2VyLkJST1dTRVIuQU5EUk9JRFxyXG4gKi9cclxuXHJcbmNvbnN0IEJST1dTRVIgPSB7XHJcbiAgICBJTlRFUk5FVF9FWFBMT1JFUjogJ2llJyxcclxuICAgIEVER0U6ICdlZCcsXHJcbiAgICBGSVJFRk9YOiAnZmYnLFxyXG4gICAgQ0hST01FOiAnY3InLFxyXG4gICAgU0FGQVJJOiAnc2YnLFxyXG4gICAgQU5EUk9JRDogJ2FuJ1xyXG59O1xyXG5cclxuLyogIVxyXG4gKiBUYWtlbiBmcm9tIGpRdWVyeSBKYXZhU2NyaXB0IExpYnJhcnkgdjEuNy4xXHJcbiAqIGh0dHA6Ly9qcXVlcnkuY29tL1xyXG4gKlxyXG4gKiBDb3B5cmlnaHQgMjAxMSwgSm9obiBSZXNpZ1xyXG4gKiBEdWFsIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgb3IgR1BMIFZlcnNpb24gMiBsaWNlbnNlcy5cclxuICogaHR0cDovL2pxdWVyeS5vcmcvbGljZW5zZVxyXG4gKlxyXG4gKiBJbmNsdWRlcyBTaXp6bGUuanNcclxuICogaHR0cDovL3NpenpsZWpzLmNvbS9cclxuICogQ29weXJpZ2h0IDIwMTEsIFRoZSBEb2pvIEZvdW5kYXRpb25cclxuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCwgQlNELCBhbmQgR1BMIExpY2Vuc2VzLlxyXG4gKlxyXG4gKiBEYXRlOiBNb24gTm92IDIxIDIxOjExOjAzIDIwMTEgLTA1MDBcclxuICovXHJcbmNvbnN0IF9jYWxjQnJvd3NlciA9ICgpID0+IHtcclxuICAgIGNvbnN0IHNVc2VyQWdlbnQgPSBuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCk7XHJcblxyXG4gICAgY29uc3QgcndlYmtpdCA9IC8od2Via2l0KVsgL10oW1xcdy5dKykvO1xyXG4gICAgY29uc3Qgcm1zaWUgPSAvKG1zaWUpIChbXFx3Ll0rKS87XHJcbiAgICBjb25zdCBybXNpZTExID0gLyh0cmlkZW50KVxcL1tcXHcuXSs7LipydjooW1xcdy5dKykvO1xyXG4gICAgY29uc3QgcmVkZ2UgPSAvKGVkZ2UpWyAvXShbXFx3Ll0rKS87XHJcbiAgICBjb25zdCBybW96aWxsYSA9IC8obW96aWxsYSkoPzouKj8gcnY6KFtcXHcuXSspKT8vO1xyXG5cclxuICAgIC8vIFdpblBob25lIElFMTEgYW5kIE1TIEVkZ2UgdXNlckFnZW50cyBjb250YWluIFwiV2ViS2l0XCIgYW5kIFwiTW96aWxsYVwiIGFuZCB0aGVyZWZvcmUgbXVzdCBiZSBjaGVja2VkIGZpcnN0XHJcbiAgICBjb25zdCBicm93c2VyTWF0Y2ggPVxyXG4gICAgICAgIHJlZGdlLmV4ZWMoc1VzZXJBZ2VudCkgfHxcclxuICAgICAgICBybXNpZTExLmV4ZWMoc1VzZXJBZ2VudCkgfHxcclxuICAgICAgICByd2Via2l0LmV4ZWMoc1VzZXJBZ2VudCkgfHxcclxuICAgICAgICBybXNpZS5leGVjKHNVc2VyQWdlbnQpIHx8XHJcbiAgICAgICAgKHNVc2VyQWdlbnQuaW5kZXhPZignY29tcGF0aWJsZScpIDwgMCAmJiBybW96aWxsYS5leGVjKHNVc2VyQWdlbnQpKSB8fFxyXG4gICAgICAgIFtdO1xyXG5cclxuICAgIGNvbnN0IG9SZXMgPSB7XHJcbiAgICAgICAgYnJvd3NlcjogYnJvd3Nlck1hdGNoWzFdIHx8ICcnLFxyXG4gICAgICAgIHZlcnNpb246IGJyb3dzZXJNYXRjaFsyXSB8fCAnMCdcclxuICAgIH07XHJcbiAgICBvUmVzW29SZXMuYnJvd3Nlcl0gPSB0cnVlO1xyXG4gICAgcmV0dXJuIG9SZXM7XHJcbn07XHJcblxyXG5jb25zdCBfZ2V0QnJvd3NlciA9ICgpID0+IHtcclxuICAgIGNvbnN0IG9Ccm93c2VyOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0gX2NhbGNCcm93c2VyKCk7XHJcbiAgICBjb25zdCBzVXNlckFnZW50ID0gbmF2aWdhdG9yLnVzZXJBZ2VudDtcclxuICAgIGNvbnN0IG9OYXZpZ2F0b3I6IHsgW2tleTogc3RyaW5nXTogYW55IH0gPSB3aW5kb3cubmF2aWdhdG9yO1xyXG5cclxuICAgIC8vIGpRdWVyeSBjaGVja3MgZm9yIHVzZXIgYWdlbnQgc3RyaW5ncy4gV2UgZGlmZmVyZW50aWF0ZSBiZXR3ZWVuIGJyb3dzZXJzXHJcbiAgICBsZXQgb0V4cE1vYmlsZTtcclxuICAgIGxldCBvUmVzdWx0O1xyXG4gICAgbGV0IGZWZXJzaW9uO1xyXG5cclxuICAgIC8vIE1vemlsbGFcclxuICAgIGlmIChvQnJvd3Nlci5tb3ppbGxhKSB7XHJcbiAgICAgICAgb0V4cE1vYmlsZSA9IC9Nb2JpbGUvO1xyXG4gICAgICAgIGlmIChzVXNlckFnZW50Lm1hdGNoKC9GaXJlZm94XFwvKFxcZCtcXC5cXGQrKS8pKSB7XHJcbiAgICAgICAgICAgIGZWZXJzaW9uID0gcGFyc2VGbG9hdChSZWdFeHAuJDEpO1xyXG4gICAgICAgICAgICBvUmVzdWx0ID0ge1xyXG4gICAgICAgICAgICAgICAgbmFtZTogQlJPV1NFUi5GSVJFRk9YLFxyXG4gICAgICAgICAgICAgICAgdmVyc2lvblN0cjogYCR7ZlZlcnNpb259YCxcclxuICAgICAgICAgICAgICAgIHZlcnNpb246IGZWZXJzaW9uLFxyXG4gICAgICAgICAgICAgICAgbW96aWxsYTogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIG1vYmlsZTogb0V4cE1vYmlsZS50ZXN0KHNVc2VyQWdlbnQpXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gdW5rbm93biBtb3ppbGxhIGJyb3dzZXJcclxuICAgICAgICAgICAgb1Jlc3VsdCA9IHtcclxuICAgICAgICAgICAgICAgIG1vYmlsZTogb0V4cE1vYmlsZS50ZXN0KHNVc2VyQWdlbnQpLFxyXG4gICAgICAgICAgICAgICAgbW96aWxsYTogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIHZlcnNpb246IC0xXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgfSBlbHNlIGlmIChvQnJvd3Nlci53ZWJraXQpIHtcclxuICAgICAgICAvLyB3ZWJraXQgdmVyc2lvbiBpcyBuZWVkZWQgZm9yIGNhbGN1bGF0aW9uIGlmIHRoZSBtb2JpbGUgYW5kcm9pZCBkZXZpY2UgaXMgYSB0YWJsZXQgKGNhbGN1bGF0aW9uIG9mIG90aGVyIG1vYmlsZSBkZXZpY2VzIHdvcmsgd2l0aG91dClcclxuICAgICAgICBjb25zdCByZWdFeHBXZWJraXRWZXJzaW9uID0gc1VzZXJBZ2VudC50b0xvd2VyQ2FzZSgpLm1hdGNoKC93ZWJraXRbL10oW1xcZC5dKykvKTtcclxuICAgICAgICBsZXQgd2Via2l0VmVyc2lvbjtcclxuICAgICAgICBpZiAocmVnRXhwV2Via2l0VmVyc2lvbikge1xyXG4gICAgICAgICAgICB3ZWJraXRWZXJzaW9uID0gcmVnRXhwV2Via2l0VmVyc2lvblsxXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgb0V4cE1vYmlsZSA9IC9Nb2JpbGUvO1xyXG4gICAgICAgIGNvbnN0IGFDaHJvbWVNYXRjaCA9IHNVc2VyQWdlbnQubWF0Y2goLyhDaHJvbWV8Q3JpT1MpXFwvKFxcZCtcXC5cXGQrKS5cXGQrLyk7XHJcbiAgICAgICAgY29uc3QgYUZpcmVmb3hNYXRjaCA9IHNVc2VyQWdlbnQubWF0Y2goL0Z4aU9TXFwvKFxcZCtcXC5cXGQrKS8pO1xyXG4gICAgICAgIGNvbnN0IGFBbmRyb2lkTWF0Y2ggPSBzVXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkIC4rIFZlcnNpb25cXC8oXFxkK1xcLlxcZCspLyk7XHJcblxyXG4gICAgICAgIGlmIChhQ2hyb21lTWF0Y2ggfHwgYUZpcmVmb3hNYXRjaCB8fCBhQW5kcm9pZE1hdGNoKSB7XHJcbiAgICAgICAgICAgIGxldCBzTmFtZTtcclxuICAgICAgICAgICAgbGV0IHNWZXJzaW9uO1xyXG4gICAgICAgICAgICBsZXQgYk1vYmlsZTtcclxuXHJcbiAgICAgICAgICAgIGlmIChhQ2hyb21lTWF0Y2gpIHtcclxuICAgICAgICAgICAgICAgIHNOYW1lID0gQlJPV1NFUi5DSFJPTUU7XHJcbiAgICAgICAgICAgICAgICBiTW9iaWxlID0gb0V4cE1vYmlsZS50ZXN0KHNVc2VyQWdlbnQpO1xyXG4gICAgICAgICAgICAgICAgc1ZlcnNpb24gPSBwYXJzZUZsb2F0KGFDaHJvbWVNYXRjaFsyXSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoYUZpcmVmb3hNYXRjaCkge1xyXG4gICAgICAgICAgICAgICAgc05hbWUgPSBCUk9XU0VSLkZJUkVGT1g7XHJcbiAgICAgICAgICAgICAgICBiTW9iaWxlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHNWZXJzaW9uID0gcGFyc2VGbG9hdChhRmlyZWZveE1hdGNoWzFdKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChhQW5kcm9pZE1hdGNoKSB7XHJcbiAgICAgICAgICAgICAgICBzTmFtZSA9IEJST1dTRVIuQU5EUk9JRDtcclxuICAgICAgICAgICAgICAgIGJNb2JpbGUgPSBvRXhwTW9iaWxlLnRlc3Qoc1VzZXJBZ2VudCk7XHJcbiAgICAgICAgICAgICAgICBzVmVyc2lvbiA9IHBhcnNlRmxvYXQoYUFuZHJvaWRNYXRjaFsxXSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIG9SZXN1bHQgPSB7XHJcbiAgICAgICAgICAgICAgICBuYW1lOiBzTmFtZSxcclxuICAgICAgICAgICAgICAgIG1vYmlsZTogYk1vYmlsZSxcclxuICAgICAgICAgICAgICAgIHZlcnNpb25TdHI6IGAke3NWZXJzaW9ufWAsXHJcbiAgICAgICAgICAgICAgICB2ZXJzaW9uOiBzVmVyc2lvbixcclxuICAgICAgICAgICAgICAgIHdlYmtpdDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIHdlYmtpdFZlcnNpb25cclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBTYWZhcmkgbWlnaHQgaGF2ZSBhbiBpc3N1ZSB3aXRoIHNVc2VyQWdlbnQubWF0Y2goLi4uKTsgdGh1cyBjaGFuZ2luZ1xyXG4gICAgICAgICAgICBjb25zdCBvRXhwID0gLyhWZXJzaW9ufFBoYW50b21KUylcXC8oXFxkK1xcLlxcZCspLipTYWZhcmkvO1xyXG4gICAgICAgICAgICBjb25zdCBiU3RhbmRhbG9uZTogYW55ID0gb05hdmlnYXRvci5zdGFuZGFsb25lO1xyXG4gICAgICAgICAgICBpZiAob0V4cC50ZXN0KHNVc2VyQWdlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhUGFydHM6IGFueSA9IG9FeHAuZXhlYyhzVXNlckFnZW50KTtcclxuICAgICAgICAgICAgICAgIGZWZXJzaW9uID0gcGFyc2VGbG9hdChhUGFydHNbMl0pO1xyXG4gICAgICAgICAgICAgICAgb1Jlc3VsdCA9IHtcclxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBCUk9XU0VSLlNBRkFSSSxcclxuICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uU3RyOiBgJHtmVmVyc2lvbn1gLFxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bGxzY3JlZW46IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICAgIHdlYnZpZXc6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICAgIHZlcnNpb246IGZWZXJzaW9uLFxyXG4gICAgICAgICAgICAgICAgICAgIG1vYmlsZTogb0V4cE1vYmlsZS50ZXN0KHNVc2VyQWdlbnQpLFxyXG4gICAgICAgICAgICAgICAgICAgIHdlYmtpdDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICB3ZWJraXRWZXJzaW9uLFxyXG4gICAgICAgICAgICAgICAgICAgIHBoYW50b21KUzogYVBhcnRzWzFdID09PSAnUGhhbnRvbUpTJ1xyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChcclxuICAgICAgICAgICAgICAgIC9pUGhvbmV8aVBhZHxpUG9kLy50ZXN0KHNVc2VyQWdlbnQpICYmXHJcbiAgICAgICAgICAgICAgICAhL0NyaU9TLy50ZXN0KHNVc2VyQWdlbnQpICYmXHJcbiAgICAgICAgICAgICAgICAhL0Z4aU9TLy50ZXN0KHNVc2VyQWdlbnQpICYmXHJcbiAgICAgICAgICAgICAgICAoYlN0YW5kYWxvbmUgPT09IHRydWUgfHwgYlN0YW5kYWxvbmUgPT09IGZhbHNlKVxyXG4gICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgIC8vIFdlYlZpZXcgb3IgU3RhbmRhbG9uZSBtb2RlIG9uIGlPU1xyXG4gICAgICAgICAgICAgICAgb1Jlc3VsdCA9IHtcclxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBCUk9XU0VSLlNBRkFSSSxcclxuICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uOiAtMSxcclxuICAgICAgICAgICAgICAgICAgICBmdWxsc2NyZWVuOiBiU3RhbmRhbG9uZSxcclxuICAgICAgICAgICAgICAgICAgICB3ZWJ2aWV3OiAhYlN0YW5kYWxvbmUsXHJcbiAgICAgICAgICAgICAgICAgICAgbW9iaWxlOiBvRXhwTW9iaWxlLnRlc3Qoc1VzZXJBZ2VudCksXHJcbiAgICAgICAgICAgICAgICAgICAgd2Via2l0OiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgIHdlYmtpdFZlcnNpb25cclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBvdGhlciB3ZWJraXQgYmFzZWQgYnJvd3NlclxyXG4gICAgICAgICAgICAgICAgb1Jlc3VsdCA9IHtcclxuICAgICAgICAgICAgICAgICAgICBtb2JpbGU6IG9FeHBNb2JpbGUudGVzdChzVXNlckFnZW50KSxcclxuICAgICAgICAgICAgICAgICAgICB3ZWJraXQ6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgd2Via2l0VmVyc2lvbixcclxuICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uOiAtMVxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH0gZWxzZSBpZiAob0Jyb3dzZXIubXNpZSB8fCBvQnJvd3Nlci50cmlkZW50KSB7XHJcbiAgICAgICAgZlZlcnNpb24gPSBwYXJzZUZsb2F0KG9Ccm93c2VyLnZlcnNpb24pO1xyXG5cclxuICAgICAgICBvUmVzdWx0ID0ge1xyXG4gICAgICAgICAgICBuYW1lOiBCUk9XU0VSLklOVEVSTkVUX0VYUExPUkVSLFxyXG4gICAgICAgICAgICB2ZXJzaW9uU3RyOiBgJHtmVmVyc2lvbn1gLFxyXG4gICAgICAgICAgICB2ZXJzaW9uOiBmVmVyc2lvbixcclxuICAgICAgICAgICAgbXNpZTogdHJ1ZSxcclxuICAgICAgICAgICAgbW9iaWxlOiBmYWxzZVxyXG4gICAgICAgIH07XHJcbiAgICB9IGVsc2UgaWYgKG9Ccm93c2VyLmVkZ2UpIHtcclxuICAgICAgICBmVmVyc2lvbiA9IHBhcnNlRmxvYXQob0Jyb3dzZXIudmVyc2lvbik7XHJcbiAgICAgICAgb1Jlc3VsdCA9IHtcclxuICAgICAgICAgICAgbmFtZTogQlJPV1NFUi5FREdFLFxyXG4gICAgICAgICAgICB2ZXJzaW9uU3RyOiBgJHtmVmVyc2lvbn1gLFxyXG4gICAgICAgICAgICB2ZXJzaW9uOiBmVmVyc2lvbixcclxuICAgICAgICAgICAgZWRnZTogdHJ1ZVxyXG4gICAgICAgIH07XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIG9SZXN1bHQgPSB7XHJcbiAgICAgICAgICAgIG5hbWU6ICcnLFxyXG4gICAgICAgICAgICB2ZXJzaW9uU3RyOiAnJyxcclxuICAgICAgICAgICAgdmVyc2lvbjogLTEsXHJcbiAgICAgICAgICAgIG1vYmlsZTogZmFsc2VcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBvUmVzdWx0O1xyXG59O1xyXG5cclxuY29uc3QgX3NldEJyb3dzZXIgPSAoKSA9PiB7XHJcbiAgICBEZXZpY2UuYnJvd3NlciA9IF9nZXRCcm93c2VyKCk7XHJcbiAgICBEZXZpY2UuYnJvd3Nlci5CUk9XU0VSID0gQlJPV1NFUjtcclxuXHJcbiAgICBpZiAoRGV2aWNlLmJyb3dzZXIubmFtZSkge1xyXG4gICAgICAgIE9iamVjdC5rZXlzKEJST1dTRVIpLmZvckVhY2goKGIpID0+IHtcclxuICAgICAgICAgICAgaWYgKEJST1dTRVJbYl0gPT09IERldmljZS5icm93c2VyLm5hbWUpIHtcclxuICAgICAgICAgICAgICAgIERldmljZS5icm93c2VyW2IudG9Mb3dlckNhc2UoKV0gPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn07XHJcblxyXG5jb25zdCBnZXRCcm93c2VyID0gKCkgPT4ge1xyXG4gICAgaWYgKCFEZXZpY2UuYnJvd3Nlcikge1xyXG4gICAgICAgIF9zZXRCcm93c2VyKCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gRGV2aWNlLmJyb3dzZXI7XHJcbn07XHJcblxyXG5jb25zdCBpc0lFID0gKCkgPT4ge1xyXG4gICAgaWYgKCFEZXZpY2UuYnJvd3Nlcikge1xyXG4gICAgICAgIF9zZXRCcm93c2VyKCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gISFEZXZpY2UuYnJvd3Nlci5tc2llO1xyXG59O1xyXG5cclxuY29uc3QgaXNFZGdlID0gKCkgPT4ge1xyXG4gICAgaWYgKCFEZXZpY2UuYnJvd3Nlcikge1xyXG4gICAgICAgIF9zZXRCcm93c2VyKCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gISFEZXZpY2UuYnJvd3Nlci5lZGdlO1xyXG59O1xyXG5cclxuY29uc3QgaXNDaHJvbWUgPSAoKSA9PiB7XHJcbiAgICBpZiAoIURldmljZS5icm93c2VyKSB7XHJcbiAgICAgICAgX3NldEJyb3dzZXIoKTtcclxuICAgIH1cclxuICAgIHJldHVybiAhIURldmljZS5icm93c2VyLmNocm9tZTtcclxufTtcclxuXHJcbmNvbnN0IGlzRkYgPSAoKSA9PiB7XHJcbiAgICBpZiAoIURldmljZS5icm93c2VyKSB7XHJcbiAgICAgICAgX3NldEJyb3dzZXIoKTtcclxuICAgIH1cclxuICAgIHJldHVybiAhIURldmljZS5icm93c2VyLmZpcmVmb3g7XHJcbn07XHJcblxyXG5jb25zdCBpc1NhZmFyaSA9ICgpID0+IHtcclxuICAgIGlmICghRGV2aWNlLmJyb3dzZXIpIHtcclxuICAgICAgICBfc2V0QnJvd3NlcigpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuICEhRGV2aWNlLmJyb3dzZXIuc2FmYXJpO1xyXG59O1xyXG5cclxuLy8gKiAqKioqKioqIFN1cHBvcnQgRGV0ZWN0aW9uICoqKioqKioqXHJcblxyXG5jb25zdCBfc2V0U3VwcG9ydCA9ICgpID0+IHtcclxuICAgIGlmIChEZXZpY2Uuc3VwcG9ydCkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIURldmljZS5icm93c2VyKSB7XHJcbiAgICAgICAgX3NldEJyb3dzZXIoKTtcclxuICAgIH1cclxuXHJcbiAgICBEZXZpY2Uuc3VwcG9ydCA9IHt9O1xyXG4gICAgRGV2aWNlLnN1cHBvcnQudG91Y2ggPSAhIShcclxuICAgICAgICAnb250b3VjaHN0YXJ0JyBpbiB3aW5kb3cgfHxcclxuICAgICAgICBuYXZpZ2F0b3IubWF4VG91Y2hQb2ludHMgPiAwIHx8XHJcbiAgICAgICAgKCh3aW5kb3cgYXMgYW55KS5Eb2N1bWVudFRvdWNoICYmIGRvY3VtZW50IGluc3RhbmNlb2YgKHdpbmRvdyBhcyBhbnkpLkRvY3VtZW50VG91Y2gpXHJcbiAgICApO1xyXG59O1xyXG5cclxuY29uc3Qgc3VwcG9ydFRvdWNoID0gKCkgPT4ge1xyXG4gICAgaWYgKCFEZXZpY2Uuc3VwcG9ydCkge1xyXG4gICAgICAgIF9zZXRTdXBwb3J0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuICEhRGV2aWNlLnN1cHBvcnQudG91Y2g7XHJcbn07XHJcblxyXG4vLyAqICoqKioqKiogU3lzdGVtIERldGVjdGlvbiAqKioqKioqKlxyXG5cclxuLyoqXHJcbiAqIFByb3ZpZGVzIGEgYmFzaWMgY2F0ZWdvcml6YXRpb24gb2YgdGhlIHVzZWQgZGV2aWNlIGJhc2VkIG9uIHZhcmlvdXMgaW5kaWNhdG9ycy5cclxuICpcclxuICogPGI+Tm90ZTo8L2I+IERlcGVuZGluZyBvbiB0aGUgY2FwYWJpbGl0aWVzIG9mIHRoZSBkZXZpY2UgaXQgaXMgYWxzbyBwb3NzaWJsZSB0aGF0IG11bHRpcGxlIGZsYWdzIGFyZSBzZXQgdG8gPGNvZGU+dHJ1ZTwvY29kZT4uXHJcbiAqXHJcbiAqIEBuYW1lc3BhY2VcclxuICogQG5hbWUgRGV2aWNlLnN5c3RlbVxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBJZiB0aGlzIGZsYWcgaXMgc2V0IHRvIDxjb2RlPnRydWU8L2NvZGU+LCB0aGUgZGV2aWNlIGlzIHJlY29nbml6ZWQgYXMgYSBwaG9uZS5cclxuICpcclxuICogQG5hbWUgRGV2aWNlLnN5c3RlbS5waG9uZVxyXG4gKiBAdHlwZSBib29sZWFuXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIEBuYW1lIERldmljZS5zeXN0ZW0uU1lTVEVNVFlQRVxyXG4gKiBFbnVtZXJhdGlvbiBjb250YWluaW5nIHRoZSBuYW1lcyBvZiBrbm93biB0eXBlcyBvZiB0aGUgZGV2aWNlcy5cclxuICovXHJcblxyXG5jb25zdCBTWVNURU1UWVBFID0ge1xyXG4gICAgVEFCTEVUOiAndGFibGV0JyxcclxuICAgIFBIT05FOiAncGhvbmUnLFxyXG4gICAgREVTS1RPUDogJ2Rlc2t0b3AnLFxyXG4gICAgQ09NQkk6ICdjb21iaSdcclxufTtcclxuXHJcbmNvbnN0IF9pc1RhYmxldCA9ICgpID0+IHtcclxuICAgIGNvbnN0IHNVc2VyQWdlbnQgPSBuYXZpZ2F0b3IudXNlckFnZW50O1xyXG4gICAgaWYgKERldmljZS5vcy5uYW1lID09PSBEZXZpY2Uub3MuT1MuSU9TKSB7XHJcbiAgICAgICAgcmV0dXJuIC9pcGFkL2kudGVzdChzVXNlckFnZW50KTtcclxuICAgIH1cclxuICAgIC8vIGluIHJlYWwgbW9iaWxlIGRldmljZVxyXG4gICAgaWYgKHN1cHBvcnRUb3VjaCgpKSB7XHJcbiAgICAgICAgaWYgKERldmljZS5vcy53aW5kb3dzICYmIERldmljZS5vcy52ZXJzaW9uID49IDgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoRGV2aWNlLmJyb3dzZXIuY2hyb21lICYmIERldmljZS5vcy5hbmRyb2lkICYmIERldmljZS5vcy52ZXJzaW9uID49IDQuNCkge1xyXG4gICAgICAgICAgICByZXR1cm4gIS9Nb2JpbGUgU2FmYXJpXFwvWy4wLTldKy8udGVzdChzVXNlckFnZW50KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgbGV0IGRlbnNpdHlGYWN0b3IgPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyA/IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIDogMTsgLy8gbWF5IGJlIHVuZGVmaW5lZCBpbiBXaW5kb3dzIFBob25lIGRldmljZXNcclxuICAgICAgICAvLyBPbiBBbmRyb2lkIHNvbWV0aW1lcyB3aW5kb3cuc2NyZWVuLndpZHRoIHJldHVybnMgdGhlIGxvZ2ljYWwgQ1NTIHBpeGVscywgc29tZXRpbWVzIHRoZSBwaHlzaWNhbCBkZXZpY2UgcGl4ZWxzO1xyXG4gICAgICAgIC8vIFRlc3RzIG9uIG11bHRpcGxlIGRldmljZXMgc3VnZ2VzdCB0aGlzIGRlcGVuZHMgb24gdGhlIFdlYmtpdCB2ZXJzaW9uLlxyXG4gICAgICAgIC8vIFRoZSBXZWJraXQgcGF0Y2ggd2hpY2ggY2hhbmdlZCB0aGUgYmVoYXZpb3Igd2FzIGRvbmUgaGVyZTogaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTEwNjQ2MFxyXG4gICAgICAgIC8vIENocm9tZSAyNyB3aXRoIFdlYmtpdCA1MzcuMzYgcmV0dXJucyB0aGUgbG9naWNhbCBwaXhlbHMsXHJcbiAgICAgICAgLy8gQ2hyb21lIDE4IHdpdGggV2Via2l0IDUzNS4xOSByZXR1cm5zIHRoZSBwaHlzaWNhbCBwaXhlbHMuXHJcbiAgICAgICAgLy8gVGhlIEJsYWNrQmVycnkgMTAgYnJvd3NlciB3aXRoIFdlYmtpdCA1MzcuMTArIHJldHVybnMgdGhlIHBoeXNpY2FsIHBpeGVscy5cclxuICAgICAgICAvLyBTbyBpdCBhcHBlYXJzIGxpa2Ugc29tZXdoZXJlIGFib3ZlIFdlYmtpdCA1MzcuMTAgd2UgZG8gbm90IGh2ZSB0byBkaXZpZGUgYnkgdGhlIGRldmljZVBpeGVsUmF0aW8gYW55bW9yZS5cclxuICAgICAgICBpZiAoRGV2aWNlLm9zLmFuZHJvaWQgJiYgRGV2aWNlLmJyb3dzZXIud2Via2l0ICYmIHBhcnNlRmxvYXQoRGV2aWNlLmJyb3dzZXIud2Via2l0VmVyc2lvbikgPiA1MzcuMSkge1xyXG4gICAgICAgICAgICBkZW5zaXR5RmFjdG9yID0gMTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIHRoaXMgaXMgaG93IGFuZHJvaWQgZGlzdGluZ3Vpc2hlcyBiZXR3ZWVuIHRhYmxldCBhbmQgcGhvbmVcclxuICAgICAgICAvLyBodHRwOi8vYW5kcm9pZC1kZXZlbG9wZXJzLmJsb2dzcG90LmRlLzIwMTEvMDcvbmV3LXRvb2xzLWZvci1tYW5hZ2luZy1zY3JlZW4tc2l6ZXMuaHRtbFxyXG4gICAgICAgIGNvbnN0IGJUYWJsZXQgPSBNYXRoLm1pbih3aW5kb3cuc2NyZWVuLndpZHRoIC8gZGVuc2l0eUZhY3Rvciwgd2luZG93LnNjcmVlbi5oZWlnaHQgLyBkZW5zaXR5RmFjdG9yKSA+PSA2MDA7XHJcblxyXG4gICAgICAgIC8vIHNwZWNpYWwgd29ya2Fyb3VuZCBmb3IgTmV4dXMgNyB3aGVyZSB0aGUgd2luZG93LnNjcmVlbi53aWR0aCBpcyA2MDBweCBvciA2MDFweCBpbiBwb3J0cmFpdCBtb2RlICg9PiB0YWJsZXQpXHJcbiAgICAgICAgLy8gYnV0IHdpbmRvdy5zY3JlZW4uaGVpZ2h0IDU1MnB4IGluIGxhbmRzY2FwZSBtb2RlICg9PiBwaG9uZSksIGJlY2F1c2UgdGhlIGJyb3dzZXIgVUkgdGFrZXMgc29tZSBzcGFjZSBvbiB0b3AuXHJcbiAgICAgICAgLy8gU28gdGhlIGRldGVjdGVkIGRldmljZSB0eXBlIGRlcGVuZHMgb24gdGhlIG9yaWVudGF0aW9uIDotKFxyXG4gICAgICAgIC8vIGFjdHVhbGx5IHRoaXMgaXMgYSBDaHJvbWUgYnVnLCBhcyBcIndpZHRoXCIvXCJoZWlnaHRcIiBzaG91bGQgcmV0dXJuIHRoZSBlbnRpcmUgc2NyZWVuJ3MgZGltZW5zaW9ucyBhbmRcclxuICAgICAgICAvLyBcImF2YWlsV2lkdGhcIi9cImF2YWlsSGVpZ2h0XCIgc2hvdWxkIHJldHVybiB0aGUgc2l6ZSBhdmFpbGFibGUgYWZ0ZXIgc3VidHJhY3RpbmcgdGhlIGJyb3dzZXIgVUlcclxuXHJcbiAgICAgICAgLypcclxuICAgICAgICAgICAgICAgICBpZiAoaXNMYW5kc2NhcGUoKSAmJlxyXG4gICAgICAgICAgICAgICAgICAgICAod2luZG93LnNjcmVlbi5oZWlnaHQgPT09IDU1MiB8fCB3aW5kb3cuc2NyZWVuLmhlaWdodCA9PT0gNTUzKSAvLyBvbGQvbmV3IE5leHVzIDdcclxuICAgICAgICAgICAgICAgICAgICAgJiZcclxuICAgICAgICAgICAgICAgICAgICAgKC9OZXh1cyA3L2kudGVzdChzVXNlckFnZW50KSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgYlRhYmxldCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICovXHJcblxyXG4gICAgICAgIHJldHVybiBiVGFibGV0O1xyXG4gICAgfVxyXG4gICAgLy8gVGhpcyBzaW1wbGUgYW5kcm9pZCBwaG9uZSBkZXRlY3Rpb24gY2FuIGJlIHVzZWQgaGVyZSBiZWNhdXNlIHRoaXMgaXMgdGhlIG1vYmlsZSBlbXVsYXRpb24gbW9kZSBpbiBkZXNrdG9wIGJyb3dzZXJcclxuICAgIGNvbnN0IGJBbmRyb2lkUGhvbmUgPSAvKD89YW5kcm9pZCkoPz0uKm1vYmlsZSkvaS50ZXN0KHNVc2VyQWdlbnQpO1xyXG4gICAgLy8gaW4gZGVza3RvcCBicm93c2VyLCBpdCdzIGRldGVjdGVkIGFzIHRhYmxldCB3aGVuXHJcbiAgICAvLyAxLiBXaW5kb3dzIDggZGV2aWNlIHdpdGggYSB0b3VjaCBzY3JlZW4gd2hlcmUgXCJUb3VjaFwiIGlzIGNvbnRhaW5lZCBpbiB0aGUgdXNlckFnZW50XHJcbiAgICAvLyAyLiBBbmRyb2lkIGVtdWxhdGlvbiBhbmQgaXQncyBub3QgYW4gQW5kcm9pZCBwaG9uZVxyXG4gICAgcmV0dXJuIChEZXZpY2UuYnJvd3Nlci5tc2llICYmIHNVc2VyQWdlbnQuaW5kZXhPZignVG91Y2gnKSAhPT0gLTEpIHx8IChEZXZpY2Uub3MuYW5kcm9pZCAmJiAhYkFuZHJvaWRQaG9uZSk7XHJcbn07XHJcblxyXG5jb25zdCBfZ2V0U3lzdGVtID0gKCkgPT4ge1xyXG4gICAgY29uc3QgYlRhYmxldERldGVjdGVkID0gX2lzVGFibGV0KCk7XHJcbiAgICBjb25zdCBpc1dpbjhVcHdhcmRzID0gRGV2aWNlLm9zLndpbmRvd3MgJiYgRGV2aWNlLm9zLnZlcnNpb24gPj0gODtcclxuXHJcbiAgICBjb25zdCBvU3lzdGVtOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge307XHJcbiAgICBvU3lzdGVtLnRhYmxldCA9ICEhKChEZXZpY2Uuc3VwcG9ydC50b3VjaCB8fCBpc1dpbjhVcHdhcmRzKSAmJiBiVGFibGV0RGV0ZWN0ZWQpO1xyXG4gICAgb1N5c3RlbS5waG9uZSA9ICEhKChEZXZpY2Uub3Mud2luZG93c19waG9uZSB8fCBEZXZpY2Uuc3VwcG9ydC50b3VjaCkgJiYgIWJUYWJsZXREZXRlY3RlZCk7XHJcbiAgICBvU3lzdGVtLmRlc2t0b3AgPSAhISgoIW9TeXN0ZW0udGFibGV0ICYmICFvU3lzdGVtLnBob25lKSB8fCBpc1dpbjhVcHdhcmRzKTtcclxuICAgIG9TeXN0ZW0uY29tYmkgPSBvU3lzdGVtLmRlc2t0b3AgJiYgb1N5c3RlbS50YWJsZXQ7XHJcbiAgICBvU3lzdGVtLlNZU1RFTVRZUEUgPSBTWVNURU1UWVBFO1xyXG5cclxuICAgIHJldHVybiBvU3lzdGVtO1xyXG59O1xyXG5cclxuY29uc3QgX3NldFN5c3RlbSA9ICgpID0+IHtcclxuICAgIF9zZXRTdXBwb3J0KCk7XHJcbiAgICBfc2V0T1MoKTtcclxuXHJcbiAgICBEZXZpY2Uuc3lzdGVtID0ge307XHJcbiAgICBEZXZpY2Uuc3lzdGVtID0gX2dldFN5c3RlbSgpO1xyXG4gICAgaWYgKERldmljZS5zeXN0ZW0udGFibGV0IHx8IERldmljZS5zeXN0ZW0ucGhvbmUpIHtcclxuICAgICAgICBEZXZpY2UuYnJvd3Nlci5tb2JpbGUgPSB0cnVlO1xyXG4gICAgfVxyXG59O1xyXG5cclxuY29uc3QgZ2V0U3lzdGVtID0gKCkgPT4ge1xyXG4gICAgaWYgKCFEZXZpY2Uuc3lzdGVtKSB7XHJcbiAgICAgICAgX3NldFN5c3RlbSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBEZXZpY2Uuc3lzdGVtO1xyXG59O1xyXG5cclxuY29uc3QgaXNEZXNrdG9wID0gKCkgPT4ge1xyXG4gICAgaWYgKCFEZXZpY2Uuc3lzdGVtKSB7XHJcbiAgICAgICAgX3NldFN5c3RlbSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBEZXZpY2Uuc3lzdGVtLmRlc2t0b3A7XHJcbn07XHJcblxyXG5jb25zdCBpc1RhYmxldCA9ICgpID0+IHtcclxuICAgIGlmICghRGV2aWNlLnN5c3RlbSkge1xyXG4gICAgICAgIF9zZXRTeXN0ZW0oKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gRGV2aWNlLnN5c3RlbS50YWJsZXQ7XHJcbn07XHJcblxyXG5jb25zdCBpc1Bob25lID0gKCkgPT4ge1xyXG4gICAgaWYgKCFEZXZpY2Uuc3lzdGVtKSB7XHJcbiAgICAgICAgX3NldFN5c3RlbSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBEZXZpY2Uuc3lzdGVtLnBob25lO1xyXG59O1xyXG5cclxuY29uc3QgaXNNb2JpbGUgPSAoKSA9PiB7XHJcbiAgICBpZiAoIURldmljZS5zeXN0ZW0pIHtcclxuICAgICAgICBfc2V0U3lzdGVtKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIERldmljZS5icm93c2VyLm1vYmlsZTtcclxufTtcclxuXHJcbmV4cG9ydCB7XHJcbiAgICBpc0lFLFxyXG4gICAgaXNFZGdlLFxyXG4gICAgaXNDaHJvbWUsXHJcbiAgICBpc0ZGLFxyXG4gICAgaXNTYWZhcmksXHJcbiAgICBpc01vYmlsZSxcclxuICAgIGlzRGVza3RvcCxcclxuICAgIGlzVGFibGV0LFxyXG4gICAgaXNQaG9uZSxcclxuICAgIGlzQW5kcm9pZCxcclxuICAgIGdldE9TLFxyXG4gICAgZ2V0U3lzdGVtLFxyXG4gICAgZ2V0QnJvd3NlcixcclxuICAgIHN1cHBvcnRUb3VjaFxyXG59O1xyXG4iXX0=