barsa-novin-ray-core 2.2.73 → 2.2.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/barsa-novin-ray-core.mjs +630 -651
- package/fesm2022/barsa-novin-ray-core.mjs.map +1 -1
- package/lib/abstract-classes/field-base.d.ts +1 -1
- package/lib/abstract-classes/number-base.d.ts +1 -1
- package/lib/date-services/date-hijri.service.d.ts +1 -1
- package/lib/date-services/date.service.d.ts +1 -1
- package/lib/directives/base.directive.d.ts +1 -1
- package/lib/dynamic-component/base-view-item-props.d.ts +4 -4
- package/lib/resolvers/login-settings.resolver.d.ts +1 -1
- package/lib/resolvers/tile-group-breadcrumb.resolver.d.ts +1 -1
- package/lib/services/notification.service.d.ts +2 -2
- package/lib/services/portal.service.d.ts +1 -1
- package/package.json +3 -5
- package/esm2022/barsa-novin-ray-core.mjs +0 -5
- package/esm2022/lib/abstract-classes/application-base.mjs +0 -25
- package/esm2022/lib/abstract-classes/barsa-api.mjs +0 -43
- package/esm2022/lib/abstract-classes/base-column-props.mjs +0 -89
- package/esm2022/lib/abstract-classes/base.component.mjs +0 -60
- package/esm2022/lib/abstract-classes/field-base.mjs +0 -244
- package/esm2022/lib/abstract-classes/files-validation-helper.mjs +0 -75
- package/esm2022/lib/abstract-classes/form-base.mjs +0 -164
- package/esm2022/lib/abstract-classes/form-field-report-page.component.mjs +0 -54
- package/esm2022/lib/abstract-classes/form-page-base.mjs +0 -132
- package/esm2022/lib/abstract-classes/form-page.component.mjs +0 -53
- package/esm2022/lib/abstract-classes/form-props.base.mjs +0 -100
- package/esm2022/lib/abstract-classes/form-toolbar-base.mjs +0 -57
- package/esm2022/lib/abstract-classes/index.mjs +0 -25
- package/esm2022/lib/abstract-classes/layout-item-base.mjs +0 -49
- package/esm2022/lib/abstract-classes/layout-panel-base.mjs +0 -68
- package/esm2022/lib/abstract-classes/linear-list-helper.mjs +0 -135
- package/esm2022/lib/abstract-classes/models.mjs +0 -184
- package/esm2022/lib/abstract-classes/module-with-dynamic-components.mjs +0 -2
- package/esm2022/lib/abstract-classes/number-base.mjs +0 -201
- package/esm2022/lib/abstract-classes/page-base.mjs +0 -98
- package/esm2022/lib/abstract-classes/page-with-form-handler-base.mjs +0 -41
- package/esm2022/lib/abstract-classes/report-base.mjs +0 -266
- package/esm2022/lib/abstract-classes/report-item-base.mjs +0 -54
- package/esm2022/lib/abstract-classes/report-view-base.component.mjs +0 -450
- package/esm2022/lib/abstract-classes/system-base.mjs +0 -25
- package/esm2022/lib/abstract-classes/tile-props.mjs +0 -49
- package/esm2022/lib/auth-guard.mjs +0 -48
- package/esm2022/lib/barsa-novin-ray-core-routing.module.mjs +0 -311
- package/esm2022/lib/barsa-novin-ray-core.module.mjs +0 -522
- package/esm2022/lib/base-ulv-setting.component.mjs +0 -46
- package/esm2022/lib/base.module.mjs +0 -28
- package/esm2022/lib/button-loading/button-loading.component.mjs +0 -20
- package/esm2022/lib/constants.mjs +0 -963
- package/esm2022/lib/container.component.mjs +0 -100
- package/esm2022/lib/controllers/base-controller.mjs +0 -9
- package/esm2022/lib/controllers/base-view.mjs +0 -24
- package/esm2022/lib/controllers/index.mjs +0 -4
- package/esm2022/lib/controllers/models.mjs +0 -2
- package/esm2022/lib/custom-route-reuse-strategy.mjs +0 -32
- package/esm2022/lib/date-services/date-hijri.service.mjs +0 -146
- package/esm2022/lib/date-services/date-info.mjs +0 -2
- package/esm2022/lib/date-services/date-miladi.service.mjs +0 -124
- package/esm2022/lib/date-services/date-shamsi.service.mjs +0 -148
- package/esm2022/lib/date-services/date.service.mjs +0 -149
- package/esm2022/lib/date-services/index.mjs +0 -6
- package/esm2022/lib/device.mjs +0 -663
- package/esm2022/lib/directives/absolute-div-body.directive.mjs +0 -46
- package/esm2022/lib/directives/anchor-scroll.directive.mjs +0 -25
- package/esm2022/lib/directives/attr-rtl.directive.mjs +0 -36
- package/esm2022/lib/directives/base.directive.mjs +0 -55
- package/esm2022/lib/directives/body-click.directive.mjs +0 -36
- package/esm2022/lib/directives/column-resizer.directive.mjs +0 -40
- package/esm2022/lib/directives/copy.directive.mjs +0 -60
- package/esm2022/lib/directives/count-down.directive.mjs +0 -109
- package/esm2022/lib/directives/dynamic-command.directive.mjs +0 -43
- package/esm2022/lib/directives/dynamic-style.directive.mjs +0 -66
- package/esm2022/lib/directives/ellapsis-text.directive.mjs +0 -70
- package/esm2022/lib/directives/ellipsify.directive.mjs +0 -73
- package/esm2022/lib/directives/field-binding.directive.mjs +0 -18
- package/esm2022/lib/directives/fill-empty-space.mjs +0 -89
- package/esm2022/lib/directives/form-close.directive.mjs +0 -33
- package/esm2022/lib/directives/img-lazy.directive.mjs +0 -82
- package/esm2022/lib/directives/index.mjs +0 -42
- package/esm2022/lib/directives/intersection-observer.directive.mjs +0 -52
- package/esm2022/lib/directives/items-renderer.directive.mjs +0 -60
- package/esm2022/lib/directives/label-mandatory.directive.mjs +0 -49
- package/esm2022/lib/directives/load-external-files.directive.mjs +0 -38
- package/esm2022/lib/directives/mobile.directive.mjs +0 -30
- package/esm2022/lib/directives/nowraptext.directive.mjs +0 -27
- package/esm2022/lib/directives/numbers-only-input.directive.mjs +0 -27
- package/esm2022/lib/directives/placeHolder.directive.mjs +0 -16
- package/esm2022/lib/directives/prevent-default.directive.mjs +0 -21
- package/esm2022/lib/directives/print-files.directive.mjs +0 -39
- package/esm2022/lib/directives/render-ulv-paging.directive.mjs +0 -81
- package/esm2022/lib/directives/render-ulv-viewer.directive.mjs +0 -76
- package/esm2022/lib/directives/render-ulv.directive.mjs +0 -52
- package/esm2022/lib/directives/route-form-change.directive.mjs +0 -38
- package/esm2022/lib/directives/save-image.directive.mjs +0 -28
- package/esm2022/lib/directives/splide-slider.directive.mjs +0 -113
- package/esm2022/lib/directives/stop-propagation.directive.mjs +0 -21
- package/esm2022/lib/directives/table-resizer.directive.mjs +0 -236
- package/esm2022/lib/directives/ulv-command.directive.mjs +0 -43
- package/esm2022/lib/directives/until-inview.directive.mjs +0 -53
- package/esm2022/lib/directives/webotp.directive.mjs +0 -49
- package/esm2022/lib/directives/workflow-choice-command.directive.mjs +0 -61
- package/esm2022/lib/dynamic-component/base-dynamic.component.mjs +0 -97
- package/esm2022/lib/dynamic-component/base-form-toolbaritem-props.mjs +0 -53
- package/esm2022/lib/dynamic-component/base-item-content-props.mjs +0 -83
- package/esm2022/lib/dynamic-component/base-view-content-props.mjs +0 -27
- package/esm2022/lib/dynamic-component/base-view-item-props.mjs +0 -552
- package/esm2022/lib/dynamic-component/base-view-props.mjs +0 -163
- package/esm2022/lib/dynamic-component/dynamic-form-toolbar-item.component.mjs +0 -38
- package/esm2022/lib/dynamic-component/dynamic-form.component.mjs +0 -69
- package/esm2022/lib/dynamic-component/dynamic-item.component.mjs +0 -78
- package/esm2022/lib/dynamic-component/dynamic-layout.component.mjs +0 -64
- package/esm2022/lib/dynamic-component/index.mjs +0 -11
- package/esm2022/lib/empty-page/empty-page.component.mjs +0 -49
- package/esm2022/lib/empty-page-with-router-and-router-outlet/empty-page-with-router-and-router-outlet.component.mjs +0 -16
- package/esm2022/lib/field-ui/field-ui.component.mjs +0 -149
- package/esm2022/lib/form/form.component.mjs +0 -212
- package/esm2022/lib/form-new/form-new.component.mjs +0 -31
- package/esm2022/lib/form-page-routing/barsa-sap-ui-form-page-routing.module.mjs +0 -54
- package/esm2022/lib/form-page-routing/barsa-sap-ui-form-page.module.mjs +0 -29
- package/esm2022/lib/form-page-routing/constants.mjs +0 -9
- package/esm2022/lib/form-page-routing/index.mjs +0 -3
- package/esm2022/lib/from-intersection-observer.mjs +0 -53
- package/esm2022/lib/global-error-handler.mjs +0 -26
- package/esm2022/lib/injdection-tokens.mjs +0 -8
- package/esm2022/lib/modal-root.component.mjs +0 -34
- package/esm2022/lib/not-found/not-found.component.mjs +0 -16
- package/esm2022/lib/not-internet/not-internet.component.mjs +0 -21
- package/esm2022/lib/pipes/barsa-icon-dict.pipe.mjs +0 -20
- package/esm2022/lib/pipes/bbb-translate.pipe.mjs +0 -36
- package/esm2022/lib/pipes/can-upload.pipe.mjs +0 -27
- package/esm2022/lib/pipes/card-media-size.pipe.mjs +0 -21
- package/esm2022/lib/pipes/column-custom-component.pipe.mjs +0 -41
- package/esm2022/lib/pipes/column-customui.pipe.mjs +0 -33
- package/esm2022/lib/pipes/column-icon.pipe.mjs +0 -23
- package/esm2022/lib/pipes/column-value.pipe.mjs +0 -35
- package/esm2022/lib/pipes/column-valueof-parameters.pipe.mjs +0 -34
- package/esm2022/lib/pipes/combo-row-img.pipe.mjs +0 -17
- package/esm2022/lib/pipes/context-menu.pipe.mjs +0 -41
- package/esm2022/lib/pipes/control-ui.pipe.mjs +0 -32
- package/esm2022/lib/pipes/convert-to-style.pipe.mjs +0 -33
- package/esm2022/lib/pipes/date-time-to-caption.pipe.mjs +0 -35
- package/esm2022/lib/pipes/fileinfo-count.pipe.mjs +0 -21
- package/esm2022/lib/pipes/filter-columns-by-details.pipe.mjs +0 -23
- package/esm2022/lib/pipes/filter-inline-action-list.pipe.mjs +0 -19
- package/esm2022/lib/pipes/filter-string.pipe.mjs +0 -45
- package/esm2022/lib/pipes/filter-tab.pipe.mjs +0 -20
- package/esm2022/lib/pipes/filter-toolbar-control.pipe.mjs +0 -17
- package/esm2022/lib/pipes/filter-workflow-mobile.pipe.mjs +0 -25
- package/esm2022/lib/pipes/filter.pipe.mjs +0 -34
- package/esm2022/lib/pipes/find-column-by-db-name.pipe.mjs +0 -28
- package/esm2022/lib/pipes/find-preview-column.pipe.mjs +0 -20
- package/esm2022/lib/pipes/fiori-icon.pipe.mjs +0 -43
- package/esm2022/lib/pipes/groupby.pipe.mjs +0 -64
- package/esm2022/lib/pipes/header-facet-value.pipe.mjs +0 -23
- package/esm2022/lib/pipes/hide-accept-cancel-buttons.pipe.mjs +0 -24
- package/esm2022/lib/pipes/hide-columns-inmobile.pipe.mjs +0 -23
- package/esm2022/lib/pipes/index.mjs +0 -55
- package/esm2022/lib/pipes/isimage.pipe.mjs +0 -20
- package/esm2022/lib/pipes/list-count.pipe.mjs +0 -18
- package/esm2022/lib/pipes/merge-fields-to-columns.pipe.mjs +0 -43
- package/esm2022/lib/pipes/mo-info-ulv-data.pipe.mjs +0 -59
- package/esm2022/lib/pipes/mo-info-ulv-paging.pipe.mjs +0 -17
- package/esm2022/lib/pipes/mo-report-value-concat.pipe.mjs +0 -36
- package/esm2022/lib/pipes/mo-report-value.pipe.mjs +0 -18
- package/esm2022/lib/pipes/mo-value.pipe.mjs +0 -19
- package/esm2022/lib/pipes/multiple-groupby.pipe.mjs +0 -91
- package/esm2022/lib/pipes/numeral.pipe.mjs +0 -44
- package/esm2022/lib/pipes/picture-field-source.pipe.mjs +0 -23
- package/esm2022/lib/pipes/remove-newline.pipe.mjs +0 -21
- package/esm2022/lib/pipes/replace.pipe.mjs +0 -18
- package/esm2022/lib/pipes/reverse.pipe.mjs +0 -23
- package/esm2022/lib/pipes/rownumber.pipe.mjs +0 -26
- package/esm2022/lib/pipes/sanitize-text.pipe.mjs +0 -21
- package/esm2022/lib/pipes/seperator-fix.pipe.mjs +0 -24
- package/esm2022/lib/pipes/sort.pipe.mjs +0 -49
- package/esm2022/lib/pipes/string-to-number.pipe.mjs +0 -26
- package/esm2022/lib/pipes/th-image-icon.pipe.mjs +0 -22
- package/esm2022/lib/pipes/tlbButtons.pipe.mjs +0 -60
- package/esm2022/lib/pipes/toolbar-settings.pipe.mjs +0 -27
- package/esm2022/lib/pipes/total-summary.pipe.mjs +0 -17
- package/esm2022/lib/pipes/tree-item-isexpanded.pipe.mjs +0 -26
- package/esm2022/lib/pipes/visible-value.pipe.mjs +0 -19
- package/esm2022/lib/portal-page/portal-page.component.mjs +0 -24
- package/esm2022/lib/portal-page/portal-sidebar.component.mjs +0 -37
- package/esm2022/lib/redirect-home-guard.mjs +0 -51
- package/esm2022/lib/redirect-report-navigator-command/redirect-report-navigator-command.component.mjs +0 -12
- package/esm2022/lib/report-container/report-container.component.mjs +0 -63
- package/esm2022/lib/resizable-module/resizable.component.mjs +0 -31
- package/esm2022/lib/resizable-module/resizable.directive.mjs +0 -42
- package/esm2022/lib/resizable-module/resizable.module.mjs +0 -17
- package/esm2022/lib/resolvers/index.mjs +0 -7
- package/esm2022/lib/resolvers/login-settings.resolver.mjs +0 -18
- package/esm2022/lib/resolvers/portal-dynamic-page.resolver.mjs +0 -49
- package/esm2022/lib/resolvers/portal-form-page.resolver.mjs +0 -18
- package/esm2022/lib/resolvers/portal-page.resolver.mjs +0 -30
- package/esm2022/lib/resolvers/portal-report-page.resolver.mjs +0 -37
- package/esm2022/lib/resolvers/tile-group-breadcrumb.resolver.mjs +0 -30
- package/esm2022/lib/root-page/root-page.component.mjs +0 -21
- package/esm2022/lib/root-portal/root-portal.component.mjs +0 -236
- package/esm2022/lib/server-connection-error/server-connection-error.component.mjs +0 -19
- package/esm2022/lib/services/api.service.mjs +0 -63
- package/esm2022/lib/services/audio-recording.service.mjs +0 -95
- package/esm2022/lib/services/barsa-dialog.service.mjs +0 -80
- package/esm2022/lib/services/barsa-storage.service.mjs +0 -78
- package/esm2022/lib/services/breadcrumb.service.mjs +0 -64
- package/esm2022/lib/services/column.service.mjs +0 -20
- package/esm2022/lib/services/container.service.mjs +0 -69
- package/esm2022/lib/services/dynamic-component.service.mjs +0 -55
- package/esm2022/lib/services/form-panel.service.mjs +0 -394
- package/esm2022/lib/services/form.service.mjs +0 -14
- package/esm2022/lib/services/groupby.service.mjs +0 -21
- package/esm2022/lib/services/horizontal-layout.service.mjs +0 -16
- package/esm2022/lib/services/index.mjs +0 -32
- package/esm2022/lib/services/indexeddb.service.mjs +0 -34
- package/esm2022/lib/services/layout-main-content.service.mjs +0 -19
- package/esm2022/lib/services/layout.service.mjs +0 -42
- package/esm2022/lib/services/local-storage.service.mjs +0 -32
- package/esm2022/lib/services/log.service.mjs +0 -50
- package/esm2022/lib/services/network-status.service.mjs +0 -15
- package/esm2022/lib/services/notification-popup.service.mjs +0 -2
- package/esm2022/lib/services/notification-sw.service.mjs +0 -180
- package/esm2022/lib/services/notification.service.mjs +0 -189
- package/esm2022/lib/services/portal.service.mjs +0 -950
- package/esm2022/lib/services/prompt-update.service.mjs +0 -56
- package/esm2022/lib/services/routing.service.mjs +0 -60
- package/esm2022/lib/services/save-scoll-position.service.mjs +0 -29
- package/esm2022/lib/services/service-worker-communication.service.mjs +0 -120
- package/esm2022/lib/services/tabpage.service.mjs +0 -13
- package/esm2022/lib/services/toast.service.mjs +0 -2
- package/esm2022/lib/services/ui.service.mjs +0 -23
- package/esm2022/lib/services/ulvmain.service.mjs +0 -824
- package/esm2022/lib/services/upload.service.mjs +0 -166
- package/esm2022/lib/services/video-recording.service.mjs +0 -115
- package/esm2022/lib/unlimit-session/unlimit-session.component.mjs +0 -40
- package/esm2022/public-api.mjs +0 -42
package/esm2022/lib/device.mjs
DELETED
|
@@ -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=
|