ngwr 2.2.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -7
- package/alert/alert-type.d.ts +7 -0
- package/alert/alert.component.d.ts +21 -0
- package/alert/alert.module.d.ts +7 -0
- package/alert/index.d.ts +5 -0
- package/alert/public-api.d.ts +9 -0
- package/alert/styles/_index.scss +58 -0
- package/alert/styles/theming.scss +26 -0
- package/alert/styles/vars.scss +11 -0
- package/avatar/avatar.component.d.ts +27 -0
- package/avatar/avatar.module.d.ts +7 -0
- package/avatar/index.d.ts +5 -0
- package/avatar/public-api.d.ts +8 -0
- package/avatar/styles/_index.scss +39 -0
- package/button/button-group.component.d.ts +12 -0
- package/button/button.component.d.ts +26 -58
- package/button/button.module.d.ts +2 -1
- package/button/index.d.ts +5 -2
- package/button/public-api.d.ts +9 -0
- package/button/styles/_index.scss +187 -0
- package/button/styles/vars.scss +13 -0
- package/{core/abstract/base.d.ts → cdk/base.directive.d.ts} +7 -1
- package/cdk/index.d.ts +5 -0
- package/cdk/public-api.d.ts +7 -0
- package/cdk/rxjs/index.d.ts +5 -0
- package/cdk/rxjs/is-array.d.ts +8 -0
- package/cdk/rxjs/is-defined.d.ts +8 -0
- package/cdk/rxjs/is-not-empty-array.d.ts +8 -0
- package/cdk/rxjs/is-observable.d.ts +9 -0
- package/cdk/rxjs/public-api.d.ts +10 -0
- package/cdk/types/index.d.ts +5 -0
- package/cdk/types/maybe.d.ts +7 -0
- package/cdk/types/public-api.d.ts +9 -0
- package/cdk/types/safe-any.d.ts +7 -0
- package/{core/color/color.d.ts → cdk/types/theme-color.d.ts} +6 -0
- package/cdk/utils/generate-random-id.d.ts +12 -0
- package/cdk/utils/index.d.ts +5 -0
- package/cdk/utils/public-api.d.ts +7 -0
- package/checkbox/checkbox.component.d.ts +24 -45
- package/checkbox/checkbox.module.d.ts +1 -1
- package/checkbox/index.d.ts +5 -2
- package/checkbox/public-api.d.ts +8 -0
- package/checkbox/styles/_index.scss +86 -0
- package/checkbox/styles/vars.scss +16 -0
- package/dialog/dialog-animations.d.ts +7 -1
- package/dialog/{dialog-base.d.ts → dialog-base.directive.d.ts} +13 -7
- package/dialog/dialog-close.directive.d.ts +9 -0
- package/dialog/dialog-content.directive.d.ts +6 -0
- package/dialog/dialog-data.token.d.ts +8 -0
- package/dialog/dialog-footer.directive.d.ts +8 -0
- package/dialog/dialog-options.d.ts +19 -0
- package/dialog/dialog-ref.d.ts +19 -13
- package/dialog/dialog-title.directive.d.ts +6 -0
- package/dialog/dialog.component.d.ts +28 -0
- package/dialog/dialog.module.d.ts +11 -0
- package/dialog/dialog.service.d.ts +28 -0
- package/dialog/index.d.ts +5 -9
- package/dialog/public-api.d.ts +18 -0
- package/dialog/{dialog.scss → styles/_index.scss} +2 -0
- package/dialog/styles/vars.scss +7 -0
- package/divider/divider.component.d.ts +8 -35
- package/divider/divider.module.d.ts +1 -1
- package/divider/index.d.ts +5 -2
- package/divider/public-api.d.ts +8 -0
- package/divider/{divider.scss → styles/_index.scss} +1 -1
- package/esm2022/alert/alert-type.mjs +8 -0
- package/esm2022/alert/alert.component.mjs +54 -0
- package/esm2022/alert/alert.module.mjs +22 -0
- package/esm2022/alert/ngwr-alert.mjs +5 -0
- package/esm2022/alert/public-api.mjs +10 -0
- package/esm2022/avatar/avatar.component.mjs +77 -0
- package/esm2022/avatar/avatar.module.mjs +22 -0
- package/esm2022/avatar/ngwr-avatar.mjs +5 -0
- package/esm2022/avatar/public-api.mjs +9 -0
- package/esm2022/button/button-group.component.mjs +36 -0
- package/esm2022/button/button.component.mjs +55 -163
- package/esm2022/button/button.module.mjs +15 -8
- package/esm2022/button/ngwr-button.mjs +2 -2
- package/esm2022/button/public-api.mjs +10 -0
- package/esm2022/cdk/base.directive.mjs +27 -0
- package/esm2022/cdk/ngwr-cdk.mjs +5 -0
- package/esm2022/cdk/public-api.mjs +8 -0
- package/esm2022/cdk/rxjs/is-array.mjs +10 -0
- package/esm2022/cdk/rxjs/is-defined.mjs +10 -0
- package/esm2022/cdk/rxjs/is-not-empty-array.mjs +10 -0
- package/esm2022/cdk/rxjs/is-observable.mjs +10 -0
- package/esm2022/cdk/rxjs/ngwr-cdk-rxjs.mjs +5 -0
- package/esm2022/cdk/rxjs/public-api.mjs +11 -0
- package/esm2022/cdk/types/maybe.mjs +8 -0
- package/esm2022/cdk/types/ngwr-cdk-types.mjs +5 -0
- package/esm2022/cdk/types/public-api.mjs +10 -0
- package/esm2022/cdk/types/safe-any.mjs +8 -0
- package/esm2022/cdk/types/theme-color.mjs +17 -0
- package/esm2022/cdk/utils/generate-random-id.mjs +17 -0
- package/esm2022/cdk/utils/ngwr-cdk-utils.mjs +5 -0
- package/esm2022/cdk/utils/public-api.mjs +8 -0
- package/esm2022/checkbox/checkbox.component.mjs +54 -120
- package/esm2022/checkbox/checkbox.module.mjs +14 -8
- package/esm2022/checkbox/ngwr-checkbox.mjs +2 -2
- package/esm2022/checkbox/public-api.mjs +9 -0
- package/esm2022/dialog/dialog-animations.mjs +8 -2
- package/esm2022/dialog/dialog-base.directive.mjs +95 -0
- package/esm2022/dialog/dialog-close.directive.mjs +33 -0
- package/esm2022/dialog/dialog-content.directive.mjs +25 -0
- package/esm2022/dialog/dialog-data.token.mjs +9 -0
- package/esm2022/dialog/dialog-footer.directive.mjs +36 -0
- package/esm2022/dialog/dialog-options.mjs +9 -0
- package/esm2022/dialog/dialog-ref.mjs +22 -16
- package/esm2022/dialog/dialog-title.directive.mjs +25 -0
- package/esm2022/dialog/dialog.component.mjs +57 -0
- package/esm2022/dialog/dialog.module.mjs +38 -0
- package/esm2022/dialog/dialog.service.mjs +107 -0
- package/esm2022/dialog/ngwr-dialog.mjs +2 -2
- package/esm2022/dialog/public-api.mjs +19 -0
- package/esm2022/divider/divider.component.mjs +16 -57
- package/esm2022/divider/divider.module.mjs +8 -8
- package/esm2022/divider/ngwr-divider.mjs +2 -2
- package/esm2022/divider/public-api.mjs +9 -0
- package/esm2022/form/form-error.component.mjs +33 -0
- package/esm2022/form/form-item.component.mjs +43 -0
- package/esm2022/form/form.module.mjs +23 -0
- package/esm2022/form/ngwr-form.mjs +2 -2
- package/esm2022/form/public-api.mjs +10 -0
- package/esm2022/icon/icon.component.mjs +82 -0
- package/esm2022/icon/icon.module.mjs +22 -0
- package/esm2022/icon/icon.service.mjs +40 -0
- package/esm2022/icon/icons.mjs +289 -279
- package/esm2022/icon/ngwr-icon.mjs +2 -2
- package/esm2022/icon/provide-wr-icons.mjs +17 -0
- package/esm2022/icon/public-api.mjs +12 -0
- package/esm2022/input/input-types.mjs +1 -1
- package/esm2022/input/input.component.mjs +119 -0
- package/esm2022/input/input.module.mjs +22 -0
- package/esm2022/input/ngwr-input.mjs +2 -2
- package/esm2022/input/public-api.mjs +10 -0
- package/esm2022/ngwr.mjs +2 -2
- package/esm2022/pipes/new-array.pipe.mjs +23 -0
- package/esm2022/pipes/ngwr-pipes.mjs +5 -0
- package/esm2022/pipes/pipes.module.mjs +22 -0
- package/esm2022/pipes/public-api.mjs +9 -0
- package/esm2022/progress/ngwr-progress.mjs +5 -0
- package/esm2022/progress/progress.component.mjs +42 -0
- package/esm2022/progress/progress.module.mjs +22 -0
- package/esm2022/progress/public-api.mjs +9 -0
- package/esm2022/public-api.mjs +3 -0
- package/esm2022/qr/generator.mjs +84 -0
- package/esm2022/qr/ngwr-qr.mjs +5 -0
- package/esm2022/qr/public-api.mjs +9 -0
- package/esm2022/qr/qr.component.mjs +90 -0
- package/esm2022/qr/qr.module.mjs +22 -0
- package/esm2022/qr/qrcodegen.mjs +872 -0
- package/esm2022/skeleton/index.mjs +3 -3
- package/esm2022/skeleton/skeleton.component.mjs +43 -0
- package/esm2022/skeleton/skeleton.module.mjs +16 -0
- package/esm2022/spinner/index.mjs +3 -3
- package/esm2022/spinner/spinner.component.mjs +33 -0
- package/esm2022/spinner/spinner.module.mjs +22 -0
- package/esm2022/tag/ngwr-tag.mjs +2 -2
- package/esm2022/tag/public-api.mjs +9 -0
- package/esm2022/tag/tag.component.mjs +74 -0
- package/esm2022/tag/tag.module.mjs +16 -0
- package/fesm2022/ngwr-alert.mjs +94 -0
- package/fesm2022/ngwr-alert.mjs.map +1 -0
- package/fesm2022/ngwr-avatar.mjs +110 -0
- package/fesm2022/ngwr-avatar.mjs.map +1 -0
- package/fesm2022/ngwr-button.mjs +108 -169
- package/fesm2022/ngwr-button.mjs.map +1 -1
- package/fesm2022/ngwr-cdk-rxjs.mjs +53 -0
- package/fesm2022/ngwr-cdk-rxjs.mjs.map +1 -0
- package/fesm2022/ngwr-cdk-types.mjs +44 -0
- package/fesm2022/ngwr-cdk-types.mjs.map +1 -0
- package/fesm2022/ngwr-cdk-utils.mjs +30 -0
- package/fesm2022/ngwr-cdk-utils.mjs.map +1 -0
- package/fesm2022/ngwr-cdk.mjs +41 -0
- package/fesm2022/ngwr-cdk.mjs.map +1 -0
- package/fesm2022/ngwr-checkbox.mjs +73 -126
- package/fesm2022/ngwr-checkbox.mjs.map +1 -1
- package/fesm2022/ngwr-dialog.mjs +225 -165
- package/fesm2022/ngwr-dialog.mjs.map +1 -1
- package/fesm2022/ngwr-divider.mjs +29 -63
- package/fesm2022/ngwr-divider.mjs.map +1 -1
- package/fesm2022/ngwr-form.mjs +72 -54
- package/fesm2022/ngwr-form.mjs.map +1 -1
- package/fesm2022/ngwr-icon.mjs +445 -368
- package/fesm2022/ngwr-icon.mjs.map +1 -1
- package/fesm2022/ngwr-input.mjs +97 -208
- package/fesm2022/ngwr-input.mjs.map +1 -1
- package/fesm2022/ngwr-pipes.mjs +56 -0
- package/fesm2022/ngwr-pipes.mjs.map +1 -0
- package/fesm2022/ngwr-progress.mjs +75 -0
- package/fesm2022/ngwr-progress.mjs.map +1 -0
- package/fesm2022/{ngwr-qrcode.mjs → ngwr-qr.mjs} +72 -113
- package/fesm2022/ngwr-qr.mjs.map +1 -0
- package/fesm2022/ngwr-skeleton.mjs +19 -22
- package/fesm2022/ngwr-skeleton.mjs.map +1 -1
- package/fesm2022/ngwr-spinner.mjs +35 -19
- package/fesm2022/ngwr-spinner.mjs.map +1 -1
- package/fesm2022/ngwr-tag.mjs +46 -49
- package/fesm2022/ngwr-tag.mjs.map +1 -1
- package/fesm2022/ngwr.mjs +1 -1
- package/fesm2022/ngwr.mjs.map +1 -1
- package/form/form-error.component.d.ts +11 -0
- package/form/form-item.component.d.ts +14 -0
- package/form/form.module.d.ts +8 -0
- package/form/index.d.ts +5 -3
- package/form/public-api.d.ts +9 -0
- package/icon/icon.component.d.ts +19 -0
- package/icon/icon.module.d.ts +7 -0
- package/icon/icon.service.d.ts +23 -0
- package/icon/icons.d.ts +115 -101
- package/icon/index.d.ts +5 -4
- package/icon/provide-wr-icons.d.ts +9 -0
- package/icon/public-api.d.ts +11 -0
- package/icon/{icon.scss → styles/_index.scss} +4 -2
- package/icon/styles/vars.scss +3 -0
- package/index.d.ts +5 -2
- package/input/index.d.ts +5 -2
- package/input/input-types.d.ts +0 -2
- package/input/input.component.d.ts +43 -0
- package/input/input.module.d.ts +7 -0
- package/input/public-api.d.ts +9 -0
- package/input/styles/_index.scss +107 -0
- package/input/styles/vars.scss +16 -0
- package/package.json +110 -57
- package/pipes/index.d.ts +5 -0
- package/pipes/new-array.pipe.d.ts +13 -0
- package/pipes/pipes.module.d.ts +7 -0
- package/pipes/public-api.d.ts +8 -0
- package/progress/index.d.ts +5 -0
- package/progress/progress.component.d.ts +10 -0
- package/progress/progress.module.d.ts +7 -0
- package/progress/public-api.d.ts +8 -0
- package/progress/styles/_index.scss +24 -0
- package/progress/styles/theming.scss +8 -0
- package/progress/styles/vars.scss +6 -0
- package/public-api.d.ts +2 -0
- package/qr/index.d.ts +5 -0
- package/qr/public-api.d.ts +8 -0
- package/qr/qr.component.d.ts +31 -0
- package/qr/qr.module.d.ts +7 -0
- package/skeleton/index.d.ts +2 -2
- package/skeleton/skeleton.component.d.ts +10 -0
- package/skeleton/{skeleton-module.d.ts → skeleton.module.d.ts} +2 -3
- package/skeleton/{skeleton.scss → styles/_index.scss} +1 -1
- package/spinner/index.d.ts +2 -2
- package/spinner/spinner.component.d.ts +11 -0
- package/spinner/{spinner-module.d.ts → spinner.module.d.ts} +2 -2
- package/spinner/{spinner.scss → styles/_index.scss} +2 -1
- package/styles/animations.scss +4 -4
- package/styles/cdk.scss +4 -0
- package/styles/colors.scss +72 -0
- package/styles/grid.scss +1 -2
- package/styles/reset.scss +2 -2
- package/styles/variables.scss +78 -0
- package/styles.scss +23 -0
- package/tag/index.d.ts +5 -2
- package/tag/public-api.d.ts +8 -0
- package/tag/styles/_index.scss +32 -0
- package/tag/styles/theming.scss +21 -0
- package/tag/styles/vars.scss +12 -0
- package/tag/tag.component.d.ts +21 -0
- package/tag/tag.module.d.ts +7 -0
- package/_grid.scss +0 -2
- package/_index.scss +0 -31
- package/backdrop/backdrop.scss +0 -3
- package/button/button.scss +0 -160
- package/checkbox/checkbox.scss +0 -103
- package/core/abstract/index.d.ts +0 -1
- package/core/color/index.d.ts +0 -2
- package/core/color/is-theme-color.d.ts +0 -2
- package/core/decorators/index.d.ts +0 -1
- package/core/decorators/input-boolean.d.ts +0 -1
- package/core/overlay/connected-overlay-directive.d.ts +0 -16
- package/core/overlay/get-placement-name.d.ts +0 -2
- package/core/overlay/index.d.ts +0 -5
- package/core/overlay/overlay-module.d.ts +0 -7
- package/core/overlay/overlay.scss +0 -9
- package/core/overlay/position-map.d.ts +0 -17
- package/core/overlay/position-type.d.ts +0 -2
- package/core/types/index.d.ts +0 -3
- package/core/types/on-change-type.d.ts +0 -2
- package/core/types/on-touched-type.d.ts +0 -2
- package/core/types/safe-any.d.ts +0 -1
- package/dialog/dialog-config.d.ts +0 -11
- package/dialog/dialog-container.d.ts +0 -22
- package/dialog/dialog-content-directives.d.ts +0 -31
- package/dialog/dialog-module.d.ts +0 -12
- package/dialog/dialog-service.d.ts +0 -27
- package/dialog/dialog-tokens.d.ts +0 -2
- package/esm2022/button/index.mjs +0 -3
- package/esm2022/checkbox/index.mjs +0 -3
- package/esm2022/core/abstract/base.mjs +0 -18
- package/esm2022/core/abstract/index.mjs +0 -2
- package/esm2022/core/abstract/ngwr-core-abstract.mjs +0 -5
- package/esm2022/core/color/color.mjs +0 -11
- package/esm2022/core/color/index.mjs +0 -3
- package/esm2022/core/color/is-theme-color.mjs +0 -9
- package/esm2022/core/color/ngwr-core-color.mjs +0 -5
- package/esm2022/core/decorators/index.mjs +0 -2
- package/esm2022/core/decorators/input-boolean.mjs +0 -15
- package/esm2022/core/decorators/ngwr-core-decorators.mjs +0 -5
- package/esm2022/core/overlay/connected-overlay-directive.mjs +0 -98
- package/esm2022/core/overlay/get-placement-name.mjs +0 -13
- package/esm2022/core/overlay/index.mjs +0 -5
- package/esm2022/core/overlay/ngwr-core-overlay.mjs +0 -5
- package/esm2022/core/overlay/overlay-module.mjs +0 -16
- package/esm2022/core/overlay/position-map.mjs +0 -18
- package/esm2022/core/overlay/position-type.mjs +0 -2
- package/esm2022/core/types/index.mjs +0 -4
- package/esm2022/core/types/ngwr-core-types.mjs +0 -5
- package/esm2022/core/types/on-change-type.mjs +0 -2
- package/esm2022/core/types/on-touched-type.mjs +0 -2
- package/esm2022/core/types/safe-any.mjs +0 -2
- package/esm2022/dialog/dialog-base.mjs +0 -92
- package/esm2022/dialog/dialog-config.mjs +0 -3
- package/esm2022/dialog/dialog-container.mjs +0 -58
- package/esm2022/dialog/dialog-content-directives.mjs +0 -98
- package/esm2022/dialog/dialog-module.mjs +0 -24
- package/esm2022/dialog/dialog-service.mjs +0 -109
- package/esm2022/dialog/dialog-tokens.mjs +0 -3
- package/esm2022/dialog/index.mjs +0 -10
- package/esm2022/divider/index.mjs +0 -3
- package/esm2022/form/form-error.mjs +0 -23
- package/esm2022/form/form-item.mjs +0 -46
- package/esm2022/form/form-module.mjs +0 -19
- package/esm2022/form/index.mjs +0 -4
- package/esm2022/icon/icon-module.mjs +0 -21
- package/esm2022/icon/icon-service.mjs +0 -21
- package/esm2022/icon/icon.mjs +0 -60
- package/esm2022/icon/index.mjs +0 -5
- package/esm2022/index.mjs +0 -3
- package/esm2022/input/index.mjs +0 -3
- package/esm2022/input/input-module.mjs +0 -20
- package/esm2022/input/input.mjs +0 -240
- package/esm2022/qrcode/generator.mjs +0 -84
- package/esm2022/qrcode/index.mjs +0 -3
- package/esm2022/qrcode/ngwr-qrcode.mjs +0 -5
- package/esm2022/qrcode/qrcode-module.mjs +0 -19
- package/esm2022/qrcode/qrcode.mjs +0 -142
- package/esm2022/qrcode/qrcodegen.mjs +0 -872
- package/esm2022/skeleton/skeleton-module.mjs +0 -18
- package/esm2022/skeleton/skeleton.mjs +0 -44
- package/esm2022/spinner/spinner-module.mjs +0 -16
- package/esm2022/spinner/spinner.mjs +0 -23
- package/esm2022/tag/index.mjs +0 -3
- package/esm2022/tag/tag-module.mjs +0 -20
- package/esm2022/tag/tag.mjs +0 -80
- package/esm2022/tooltip/index.mjs +0 -5
- package/esm2022/tooltip/ngwr-tooltip.mjs +0 -5
- package/esm2022/tooltip/tooltip-component.mjs +0 -93
- package/esm2022/tooltip/tooltip-default-positions.mjs +0 -8
- package/esm2022/tooltip/tooltip-directive.mjs +0 -85
- package/esm2022/tooltip/tooltip-module.mjs +0 -21
- package/esm2022/tooltip/tooltip-trigger.mjs +0 -2
- package/fesm2022/ngwr-core-abstract.mjs +0 -25
- package/fesm2022/ngwr-core-abstract.mjs.map +0 -1
- package/fesm2022/ngwr-core-color.mjs +0 -25
- package/fesm2022/ngwr-core-color.mjs.map +0 -1
- package/fesm2022/ngwr-core-decorators.mjs +0 -22
- package/fesm2022/ngwr-core-decorators.mjs.map +0 -1
- package/fesm2022/ngwr-core-overlay.mjs +0 -146
- package/fesm2022/ngwr-core-overlay.mjs.map +0 -1
- package/fesm2022/ngwr-core-types.mjs +0 -4
- package/fesm2022/ngwr-core-types.mjs.map +0 -1
- package/fesm2022/ngwr-qrcode.mjs.map +0 -1
- package/fesm2022/ngwr-tooltip.mjs +0 -204
- package/fesm2022/ngwr-tooltip.mjs.map +0 -1
- package/form/form-error.d.ts +0 -6
- package/form/form-item.d.ts +0 -15
- package/form/form-module.d.ts +0 -9
- package/icon/icon-module.d.ts +0 -9
- package/icon/icon-service.d.ts +0 -8
- package/icon/icon.d.ts +0 -20
- package/input/input-module.d.ts +0 -10
- package/input/input.d.ts +0 -65
- package/input/input.scss +0 -163
- package/qrcode/index.d.ts +0 -2
- package/qrcode/qrcode-module.d.ts +0 -9
- package/qrcode/qrcode.d.ts +0 -46
- package/skeleton/skeleton.d.ts +0 -11
- package/spinner/spinner.d.ts +0 -6
- package/styles/root.scss +0 -172
- package/tag/tag-module.d.ts +0 -10
- package/tag/tag.d.ts +0 -18
- package/tag/tag.scss +0 -106
- package/tooltip/index.d.ts +0 -5
- package/tooltip/tooltip-component.d.ts +0 -31
- package/tooltip/tooltip-default-positions.d.ts +0 -1
- package/tooltip/tooltip-directive.d.ts +0 -22
- package/tooltip/tooltip-module.d.ts +0 -11
- package/tooltip/tooltip-trigger.d.ts +0 -1
- package/tooltip/tooltip.scss +0 -67
- /package/form/{form.scss → styles/_index.scss} +0 -0
- /package/{qrcode → qr}/generator.d.ts +0 -0
- /package/{qrcode → qr}/qrcodegen.d.ts +0 -0
- /package/{qrcode/qrcode.scss → qr/styles/_index.scss} +0 -0
|
@@ -1,872 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* QR Code generator library (TypeScript)
|
|
3
|
-
*
|
|
4
|
-
* Copyright (c) Project Nayuki. (MIT License)
|
|
5
|
-
* https://www.nayuki.io/page/qr-code-generator-library
|
|
6
|
-
*
|
|
7
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
8
|
-
* this software and associated documentation files (the "Software"), to deal in
|
|
9
|
-
* the Software without restriction, including without limitation the rights to
|
|
10
|
-
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
11
|
-
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
12
|
-
* subject to the following conditions:
|
|
13
|
-
* - The above copyright notice and this permission notice shall be included in
|
|
14
|
-
* all copies or substantial portions of the Software.
|
|
15
|
-
* - The Software is provided "as is", without warranty of any kind, express or
|
|
16
|
-
* implied, including but not limited to the warranties of merchantability,
|
|
17
|
-
* fitness for a particular purpose and noninfringement. In no event shall the
|
|
18
|
-
* authors or copyright holders be liable for any claim, damages or other
|
|
19
|
-
* liability, whether in an action of contract, tort or otherwise, arising from,
|
|
20
|
-
* out of or in connection with the Software or the use or other dealings in the
|
|
21
|
-
* Software.
|
|
22
|
-
*/
|
|
23
|
-
'use strict';
|
|
24
|
-
var qrcodegen;
|
|
25
|
-
(function (qrcodegen) {
|
|
26
|
-
/*---- QR Code symbol class ----*/
|
|
27
|
-
/*
|
|
28
|
-
* A QR Code symbol, which is a type of two-dimension barcode.
|
|
29
|
-
* Invented by Denso Wave and described in the ISO/IEC 18004 standard.
|
|
30
|
-
* Instances of this class represent an immutable square grid of dark and light cells.
|
|
31
|
-
* The class provides static factory functions to create a QR Code from text or binary data.
|
|
32
|
-
* The class covers the QR Code Model 2 specification, supporting all versions (sizes)
|
|
33
|
-
* from 1 to 40, all 4 error correction levels, and 4 character encoding modes.
|
|
34
|
-
*
|
|
35
|
-
* Ways to create a QR Code object:
|
|
36
|
-
* - High level: Take the payload data and call QrCode.encodeText() or QrCode.encodeBinary().
|
|
37
|
-
* - Mid level: Custom-make the list of segments and call QrCode.encodeSegments().
|
|
38
|
-
* - Low level: Custom-make the array of data codeword bytes (including
|
|
39
|
-
* segment headers and final padding, excluding error correction codewords),
|
|
40
|
-
* supply the appropriate version number, and call the QrCode() constructor.
|
|
41
|
-
* (Note that all ways require supplying the desired error correction level.)
|
|
42
|
-
*/
|
|
43
|
-
class QrCode {
|
|
44
|
-
/*-- Static factory functions (high level) --*/
|
|
45
|
-
// Returns a QR Code representing the given Unicode text string at the given error correction level.
|
|
46
|
-
// As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer
|
|
47
|
-
// Unicode code points (not UTF-16 code units) if the low error correction level is used. The smallest possible
|
|
48
|
-
// QR Code version is automatically chosen for the output. The ECC level of the result may be higher than the
|
|
49
|
-
// ecl argument if it can be done without increasing the version.
|
|
50
|
-
static encodeText(text, ecl) {
|
|
51
|
-
const segs = qrcodegen.QrSegment.makeSegments(text);
|
|
52
|
-
return QrCode.encodeSegments(segs, ecl);
|
|
53
|
-
}
|
|
54
|
-
// Returns a QR Code representing the given binary data at the given error correction level.
|
|
55
|
-
// This function always encodes using the binary segment mode, not any text mode. The maximum number of
|
|
56
|
-
// bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
|
|
57
|
-
// The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.
|
|
58
|
-
static encodeBinary(data, ecl) {
|
|
59
|
-
const seg = qrcodegen.QrSegment.makeBytes(data);
|
|
60
|
-
return QrCode.encodeSegments([seg], ecl);
|
|
61
|
-
}
|
|
62
|
-
/*-- Static factory functions (mid level) --*/
|
|
63
|
-
// Returns a QR Code representing the given segments with the given encoding parameters.
|
|
64
|
-
// The smallest possible QR Code version within the given range is automatically
|
|
65
|
-
// chosen for the output. Iff boostEcl is true, then the ECC level of the result
|
|
66
|
-
// may be higher than the ecl argument if it can be done without increasing the
|
|
67
|
-
// version. The mask number is either between 0 to 7 (inclusive) to force that
|
|
68
|
-
// mask, or -1 to automatically choose an appropriate mask (which may be slow).
|
|
69
|
-
// This function allows the user to create a custom sequence of segments that switches
|
|
70
|
-
// between modes (such as alphanumeric and byte) to encode text in less space.
|
|
71
|
-
// This is a mid-level API; the high-level API is encodeText() and encodeBinary().
|
|
72
|
-
static encodeSegments(segs, ecl, minVersion = 1, maxVersion = 40, mask = -1, boostEcl = true) {
|
|
73
|
-
if (!(QrCode.MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= QrCode.MAX_VERSION) ||
|
|
74
|
-
mask < -1 ||
|
|
75
|
-
mask > 7)
|
|
76
|
-
throw new RangeError('Invalid value');
|
|
77
|
-
// Find the minimal version number to use
|
|
78
|
-
let version;
|
|
79
|
-
let dataUsedBits;
|
|
80
|
-
for (version = minVersion;; version++) {
|
|
81
|
-
const dataCapacityBits = QrCode.getNumDataCodewords(version, ecl) * 8; // Number of data bits available
|
|
82
|
-
const usedBits = QrSegment.getTotalBits(segs, version);
|
|
83
|
-
if (usedBits <= dataCapacityBits) {
|
|
84
|
-
dataUsedBits = usedBits;
|
|
85
|
-
break; // This version number is found to be suitable
|
|
86
|
-
}
|
|
87
|
-
if (version >= maxVersion)
|
|
88
|
-
// All versions in the range could not fit the given data
|
|
89
|
-
throw new RangeError('Data too long');
|
|
90
|
-
}
|
|
91
|
-
// Increase the error correction level while the data still fits in the current version number
|
|
92
|
-
for (const newEcl of [QrCode.Ecc.MEDIUM, QrCode.Ecc.QUARTILE, QrCode.Ecc.HIGH]) {
|
|
93
|
-
// From low to high
|
|
94
|
-
if (boostEcl && dataUsedBits <= QrCode.getNumDataCodewords(version, newEcl) * 8)
|
|
95
|
-
ecl = newEcl;
|
|
96
|
-
}
|
|
97
|
-
// Concatenate all segments to create the data bit string
|
|
98
|
-
let bb = [];
|
|
99
|
-
for (const seg of segs) {
|
|
100
|
-
appendBits(seg.mode.modeBits, 4, bb);
|
|
101
|
-
appendBits(seg.numChars, seg.mode.numCharCountBits(version), bb);
|
|
102
|
-
for (const b of seg.getData())
|
|
103
|
-
bb.push(b);
|
|
104
|
-
}
|
|
105
|
-
assert(bb.length == dataUsedBits);
|
|
106
|
-
// Add terminator and pad up to a byte if applicable
|
|
107
|
-
const dataCapacityBits = QrCode.getNumDataCodewords(version, ecl) * 8;
|
|
108
|
-
assert(bb.length <= dataCapacityBits);
|
|
109
|
-
appendBits(0, Math.min(4, dataCapacityBits - bb.length), bb);
|
|
110
|
-
appendBits(0, (8 - (bb.length % 8)) % 8, bb);
|
|
111
|
-
assert(bb.length % 8 == 0);
|
|
112
|
-
// Pad with alternating bytes until data capacity is reached
|
|
113
|
-
for (let padByte = 0xec; bb.length < dataCapacityBits; padByte ^= 0xec ^ 0x11)
|
|
114
|
-
appendBits(padByte, 8, bb);
|
|
115
|
-
// Pack bits into bytes in big endian
|
|
116
|
-
let dataCodewords = [];
|
|
117
|
-
while (dataCodewords.length * 8 < bb.length)
|
|
118
|
-
dataCodewords.push(0);
|
|
119
|
-
bb.forEach((b, i) => (dataCodewords[i >>> 3] |= b << (7 - (i & 7))));
|
|
120
|
-
// Create the QR Code object
|
|
121
|
-
return new QrCode(version, ecl, dataCodewords, mask);
|
|
122
|
-
}
|
|
123
|
-
/*-- Constructor (low level) and fields --*/
|
|
124
|
-
// Creates a new QR Code with the given version number,
|
|
125
|
-
// error correction level, data codeword bytes, and mask number.
|
|
126
|
-
// This is a low-level API that most users should not use directly.
|
|
127
|
-
// A mid-level API is the encodeSegments() function.
|
|
128
|
-
constructor(
|
|
129
|
-
// The version number of this QR Code, which is between 1 and 40 (inclusive).
|
|
130
|
-
// This determines the size of this barcode.
|
|
131
|
-
version,
|
|
132
|
-
// The error correction level used in this QR Code.
|
|
133
|
-
errorCorrectionLevel, dataCodewords, msk) {
|
|
134
|
-
this.version = version;
|
|
135
|
-
this.errorCorrectionLevel = errorCorrectionLevel;
|
|
136
|
-
// The modules of this QR Code (false = light, true = dark).
|
|
137
|
-
// Immutable after constructor finishes. Accessed through getModule().
|
|
138
|
-
this.modules = [];
|
|
139
|
-
// Indicates function modules that are not subjected to masking. Discarded when constructor finishes.
|
|
140
|
-
this.isFunction = [];
|
|
141
|
-
// Check scalar arguments
|
|
142
|
-
if (version < QrCode.MIN_VERSION || version > QrCode.MAX_VERSION)
|
|
143
|
-
throw new RangeError('Version value out of range');
|
|
144
|
-
if (msk < -1 || msk > 7)
|
|
145
|
-
throw new RangeError('Mask value out of range');
|
|
146
|
-
this.size = version * 4 + 17;
|
|
147
|
-
// Initialize both grids to be size*size arrays of Boolean false
|
|
148
|
-
let row = [];
|
|
149
|
-
for (let i = 0; i < this.size; i++)
|
|
150
|
-
row.push(false);
|
|
151
|
-
for (let i = 0; i < this.size; i++) {
|
|
152
|
-
this.modules.push(row.slice()); // Initially all light
|
|
153
|
-
this.isFunction.push(row.slice());
|
|
154
|
-
}
|
|
155
|
-
// Compute ECC, draw modules
|
|
156
|
-
this.drawFunctionPatterns();
|
|
157
|
-
const allCodewords = this.addEccAndInterleave(dataCodewords);
|
|
158
|
-
this.drawCodewords(allCodewords);
|
|
159
|
-
// Do masking
|
|
160
|
-
if (msk == -1) {
|
|
161
|
-
// Automatically choose best mask
|
|
162
|
-
let minPenalty = 1000000000;
|
|
163
|
-
for (let i = 0; i < 8; i++) {
|
|
164
|
-
this.applyMask(i);
|
|
165
|
-
this.drawFormatBits(i);
|
|
166
|
-
const penalty = this.getPenaltyScore();
|
|
167
|
-
if (penalty < minPenalty) {
|
|
168
|
-
msk = i;
|
|
169
|
-
minPenalty = penalty;
|
|
170
|
-
}
|
|
171
|
-
this.applyMask(i); // Undoes the mask due to XOR
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
assert(msk >= 0 && msk <= 7);
|
|
175
|
-
this.mask = msk;
|
|
176
|
-
this.applyMask(msk); // Apply the final choice of mask
|
|
177
|
-
this.drawFormatBits(msk); // Overwrite old format bits
|
|
178
|
-
this.isFunction = [];
|
|
179
|
-
}
|
|
180
|
-
/*-- Accessor methods --*/
|
|
181
|
-
// Returns the color of the module (pixel) at the given coordinates, which is false
|
|
182
|
-
// for light or true for dark. The top left corner has the coordinates (x=0, y=0).
|
|
183
|
-
// If the given coordinates are out of bounds, then false (light) is returned.
|
|
184
|
-
getModule(x, y) {
|
|
185
|
-
return x >= 0 && x < this.size && y >= 0 && y < this.size && this.modules[y][x];
|
|
186
|
-
}
|
|
187
|
-
/*-- Private helper methods for constructor: Drawing function modules --*/
|
|
188
|
-
// Reads this object's version field, and draws and marks all function modules.
|
|
189
|
-
drawFunctionPatterns() {
|
|
190
|
-
// Draw horizontal and vertical timing patterns
|
|
191
|
-
for (let i = 0; i < this.size; i++) {
|
|
192
|
-
this.setFunctionModule(6, i, i % 2 == 0);
|
|
193
|
-
this.setFunctionModule(i, 6, i % 2 == 0);
|
|
194
|
-
}
|
|
195
|
-
// Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules)
|
|
196
|
-
this.drawFinderPattern(3, 3);
|
|
197
|
-
this.drawFinderPattern(this.size - 4, 3);
|
|
198
|
-
this.drawFinderPattern(3, this.size - 4);
|
|
199
|
-
// Draw numerous alignment patterns
|
|
200
|
-
const alignPatPos = this.getAlignmentPatternPositions();
|
|
201
|
-
const numAlign = alignPatPos.length;
|
|
202
|
-
for (let i = 0; i < numAlign; i++) {
|
|
203
|
-
for (let j = 0; j < numAlign; j++) {
|
|
204
|
-
// Don't draw on the three finder corners
|
|
205
|
-
if (!((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) || (i == numAlign - 1 && j == 0)))
|
|
206
|
-
this.drawAlignmentPattern(alignPatPos[i], alignPatPos[j]);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
// Draw configuration data
|
|
210
|
-
this.drawFormatBits(0); // Dummy mask value; overwritten later in the constructor
|
|
211
|
-
this.drawVersion();
|
|
212
|
-
}
|
|
213
|
-
// Draws two copies of the format bits (with its own error correction code)
|
|
214
|
-
// based on the given mask and this object's error correction level field.
|
|
215
|
-
drawFormatBits(mask) {
|
|
216
|
-
// Calculate error correction code and pack bits
|
|
217
|
-
const data = (this.errorCorrectionLevel.formatBits << 3) | mask; // errCorrLvl is uint2, mask is uint3
|
|
218
|
-
let rem = data;
|
|
219
|
-
for (let i = 0; i < 10; i++)
|
|
220
|
-
rem = (rem << 1) ^ ((rem >>> 9) * 0x537);
|
|
221
|
-
const bits = ((data << 10) | rem) ^ 0x5412; // uint15
|
|
222
|
-
assert(bits >>> 15 == 0);
|
|
223
|
-
// Draw first copy
|
|
224
|
-
for (let i = 0; i <= 5; i++)
|
|
225
|
-
this.setFunctionModule(8, i, getBit(bits, i));
|
|
226
|
-
this.setFunctionModule(8, 7, getBit(bits, 6));
|
|
227
|
-
this.setFunctionModule(8, 8, getBit(bits, 7));
|
|
228
|
-
this.setFunctionModule(7, 8, getBit(bits, 8));
|
|
229
|
-
for (let i = 9; i < 15; i++)
|
|
230
|
-
this.setFunctionModule(14 - i, 8, getBit(bits, i));
|
|
231
|
-
// Draw second copy
|
|
232
|
-
for (let i = 0; i < 8; i++)
|
|
233
|
-
this.setFunctionModule(this.size - 1 - i, 8, getBit(bits, i));
|
|
234
|
-
for (let i = 8; i < 15; i++)
|
|
235
|
-
this.setFunctionModule(8, this.size - 15 + i, getBit(bits, i));
|
|
236
|
-
this.setFunctionModule(8, this.size - 8, true); // Always dark
|
|
237
|
-
}
|
|
238
|
-
// Draws two copies of the version bits (with its own error correction code),
|
|
239
|
-
// based on this object's version field, iff 7 <= version <= 40.
|
|
240
|
-
drawVersion() {
|
|
241
|
-
if (this.version < 7)
|
|
242
|
-
return;
|
|
243
|
-
// Calculate error correction code and pack bits
|
|
244
|
-
let rem = this.version; // version is uint6, in the range [7, 40]
|
|
245
|
-
for (let i = 0; i < 12; i++)
|
|
246
|
-
rem = (rem << 1) ^ ((rem >>> 11) * 0x1f25);
|
|
247
|
-
const bits = (this.version << 12) | rem; // uint18
|
|
248
|
-
assert(bits >>> 18 == 0);
|
|
249
|
-
// Draw two copies
|
|
250
|
-
for (let i = 0; i < 18; i++) {
|
|
251
|
-
const color = getBit(bits, i);
|
|
252
|
-
const a = this.size - 11 + (i % 3);
|
|
253
|
-
const b = Math.floor(i / 3);
|
|
254
|
-
this.setFunctionModule(a, b, color);
|
|
255
|
-
this.setFunctionModule(b, a, color);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
// Draws a 9*9 finder pattern including the border separator,
|
|
259
|
-
// with the center module at (x, y). Modules can be out of bounds.
|
|
260
|
-
drawFinderPattern(x, y) {
|
|
261
|
-
for (let dy = -4; dy <= 4; dy++) {
|
|
262
|
-
for (let dx = -4; dx <= 4; dx++) {
|
|
263
|
-
const dist = Math.max(Math.abs(dx), Math.abs(dy)); // Chebyshev/infinity norm
|
|
264
|
-
const xx = x + dx;
|
|
265
|
-
const yy = y + dy;
|
|
266
|
-
if (xx >= 0 && xx < this.size && yy >= 0 && yy < this.size)
|
|
267
|
-
this.setFunctionModule(xx, yy, dist != 2 && dist != 4);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
// Draws a 5*5 alignment pattern, with the center module
|
|
272
|
-
// at (x, y). All modules must be in bounds.
|
|
273
|
-
drawAlignmentPattern(x, y) {
|
|
274
|
-
for (let dy = -2; dy <= 2; dy++) {
|
|
275
|
-
for (let dx = -2; dx <= 2; dx++)
|
|
276
|
-
this.setFunctionModule(x + dx, y + dy, Math.max(Math.abs(dx), Math.abs(dy)) != 1);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
// Sets the color of a module and marks it as a function module.
|
|
280
|
-
// Only used by the constructor. Coordinates must be in bounds.
|
|
281
|
-
setFunctionModule(x, y, isDark) {
|
|
282
|
-
this.modules[y][x] = isDark;
|
|
283
|
-
this.isFunction[y][x] = true;
|
|
284
|
-
}
|
|
285
|
-
/*-- Private helper methods for constructor: Codewords and masking --*/
|
|
286
|
-
// Returns a new byte string representing the given data with the appropriate error correction
|
|
287
|
-
// codewords appended to it, based on this object's version and error correction level.
|
|
288
|
-
addEccAndInterleave(data) {
|
|
289
|
-
const ver = this.version;
|
|
290
|
-
const ecl = this.errorCorrectionLevel;
|
|
291
|
-
if (data.length != QrCode.getNumDataCodewords(ver, ecl))
|
|
292
|
-
throw new RangeError('Invalid argument');
|
|
293
|
-
// Calculate parameter numbers
|
|
294
|
-
const numBlocks = QrCode.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver];
|
|
295
|
-
const blockEccLen = QrCode.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver];
|
|
296
|
-
const rawCodewords = Math.floor(QrCode.getNumRawDataModules(ver) / 8);
|
|
297
|
-
const numShortBlocks = numBlocks - (rawCodewords % numBlocks);
|
|
298
|
-
const shortBlockLen = Math.floor(rawCodewords / numBlocks);
|
|
299
|
-
// Split data into blocks and append ECC to each block
|
|
300
|
-
let blocks = [];
|
|
301
|
-
const rsDiv = QrCode.reedSolomonComputeDivisor(blockEccLen);
|
|
302
|
-
for (let i = 0, k = 0; i < numBlocks; i++) {
|
|
303
|
-
let dat = data.slice(k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1));
|
|
304
|
-
k += dat.length;
|
|
305
|
-
const ecc = QrCode.reedSolomonComputeRemainder(dat, rsDiv);
|
|
306
|
-
if (i < numShortBlocks)
|
|
307
|
-
dat.push(0);
|
|
308
|
-
blocks.push(dat.concat(ecc));
|
|
309
|
-
}
|
|
310
|
-
// Interleave (not concatenate) the bytes from every block into a single sequence
|
|
311
|
-
let result = [];
|
|
312
|
-
for (let i = 0; i < blocks[0].length; i++) {
|
|
313
|
-
blocks.forEach((block, j) => {
|
|
314
|
-
// Skip the padding byte in short blocks
|
|
315
|
-
if (i != shortBlockLen - blockEccLen || j >= numShortBlocks)
|
|
316
|
-
result.push(block[i]);
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
assert(result.length == rawCodewords);
|
|
320
|
-
return result;
|
|
321
|
-
}
|
|
322
|
-
// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
|
|
323
|
-
// data area of this QR Code. Function modules need to be marked off before this is called.
|
|
324
|
-
drawCodewords(data) {
|
|
325
|
-
if (data.length != Math.floor(QrCode.getNumRawDataModules(this.version) / 8))
|
|
326
|
-
throw new RangeError('Invalid argument');
|
|
327
|
-
let i = 0; // Bit index into the data
|
|
328
|
-
// Do the funny zigzag scan
|
|
329
|
-
for (let right = this.size - 1; right >= 1; right -= 2) {
|
|
330
|
-
// Index of right column in each column pair
|
|
331
|
-
if (right == 6)
|
|
332
|
-
right = 5;
|
|
333
|
-
for (let vert = 0; vert < this.size; vert++) {
|
|
334
|
-
// Vertical counter
|
|
335
|
-
for (let j = 0; j < 2; j++) {
|
|
336
|
-
const x = right - j; // Actual x coordinate
|
|
337
|
-
const upward = ((right + 1) & 2) == 0;
|
|
338
|
-
const y = upward ? this.size - 1 - vert : vert; // Actual y coordinate
|
|
339
|
-
if (!this.isFunction[y][x] && i < data.length * 8) {
|
|
340
|
-
this.modules[y][x] = getBit(data[i >>> 3], 7 - (i & 7));
|
|
341
|
-
i++;
|
|
342
|
-
}
|
|
343
|
-
// If this QR Code has any remainder bits (0 to 7), they were assigned as
|
|
344
|
-
// 0/false/light by the constructor and are left unchanged by this method
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
assert(i == data.length * 8);
|
|
349
|
-
}
|
|
350
|
-
// XORs the codeword modules in this QR Code with the given mask pattern.
|
|
351
|
-
// The function modules must be marked and the codeword bits must be drawn
|
|
352
|
-
// before masking. Due to the arithmetic of XOR, calling applyMask() with
|
|
353
|
-
// the same mask value a second time will undo the mask. A final well-formed
|
|
354
|
-
// QR Code needs exactly one (not zero, two, etc.) mask applied.
|
|
355
|
-
applyMask(mask) {
|
|
356
|
-
if (mask < 0 || mask > 7)
|
|
357
|
-
throw new RangeError('Mask value out of range');
|
|
358
|
-
for (let y = 0; y < this.size; y++) {
|
|
359
|
-
for (let x = 0; x < this.size; x++) {
|
|
360
|
-
let invert;
|
|
361
|
-
switch (mask) {
|
|
362
|
-
case 0:
|
|
363
|
-
invert = (x + y) % 2 == 0;
|
|
364
|
-
break;
|
|
365
|
-
case 1:
|
|
366
|
-
invert = y % 2 == 0;
|
|
367
|
-
break;
|
|
368
|
-
case 2:
|
|
369
|
-
invert = x % 3 == 0;
|
|
370
|
-
break;
|
|
371
|
-
case 3:
|
|
372
|
-
invert = (x + y) % 3 == 0;
|
|
373
|
-
break;
|
|
374
|
-
case 4:
|
|
375
|
-
invert = (Math.floor(x / 3) + Math.floor(y / 2)) % 2 == 0;
|
|
376
|
-
break;
|
|
377
|
-
case 5:
|
|
378
|
-
invert = ((x * y) % 2) + ((x * y) % 3) == 0;
|
|
379
|
-
break;
|
|
380
|
-
case 6:
|
|
381
|
-
invert = (((x * y) % 2) + ((x * y) % 3)) % 2 == 0;
|
|
382
|
-
break;
|
|
383
|
-
case 7:
|
|
384
|
-
invert = (((x + y) % 2) + ((x * y) % 3)) % 2 == 0;
|
|
385
|
-
break;
|
|
386
|
-
default:
|
|
387
|
-
throw new Error('Unreachable');
|
|
388
|
-
}
|
|
389
|
-
if (!this.isFunction[y][x] && invert)
|
|
390
|
-
this.modules[y][x] = !this.modules[y][x];
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
// Calculates and returns the penalty score based on state of this QR Code's current modules.
|
|
395
|
-
// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
|
|
396
|
-
getPenaltyScore() {
|
|
397
|
-
let result = 0;
|
|
398
|
-
// Adjacent modules in row having same color, and finder-like patterns
|
|
399
|
-
for (let y = 0; y < this.size; y++) {
|
|
400
|
-
let runColor = false;
|
|
401
|
-
let runX = 0;
|
|
402
|
-
let runHistory = [0, 0, 0, 0, 0, 0, 0];
|
|
403
|
-
for (let x = 0; x < this.size; x++) {
|
|
404
|
-
if (this.modules[y][x] == runColor) {
|
|
405
|
-
runX++;
|
|
406
|
-
if (runX == 5)
|
|
407
|
-
result += QrCode.PENALTY_N1;
|
|
408
|
-
else if (runX > 5)
|
|
409
|
-
result++;
|
|
410
|
-
}
|
|
411
|
-
else {
|
|
412
|
-
this.finderPenaltyAddHistory(runX, runHistory);
|
|
413
|
-
if (!runColor)
|
|
414
|
-
result += this.finderPenaltyCountPatterns(runHistory) * QrCode.PENALTY_N3;
|
|
415
|
-
runColor = this.modules[y][x];
|
|
416
|
-
runX = 1;
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
result += this.finderPenaltyTerminateAndCount(runColor, runX, runHistory) * QrCode.PENALTY_N3;
|
|
420
|
-
}
|
|
421
|
-
// Adjacent modules in column having same color, and finder-like patterns
|
|
422
|
-
for (let x = 0; x < this.size; x++) {
|
|
423
|
-
let runColor = false;
|
|
424
|
-
let runY = 0;
|
|
425
|
-
let runHistory = [0, 0, 0, 0, 0, 0, 0];
|
|
426
|
-
for (let y = 0; y < this.size; y++) {
|
|
427
|
-
if (this.modules[y][x] == runColor) {
|
|
428
|
-
runY++;
|
|
429
|
-
if (runY == 5)
|
|
430
|
-
result += QrCode.PENALTY_N1;
|
|
431
|
-
else if (runY > 5)
|
|
432
|
-
result++;
|
|
433
|
-
}
|
|
434
|
-
else {
|
|
435
|
-
this.finderPenaltyAddHistory(runY, runHistory);
|
|
436
|
-
if (!runColor)
|
|
437
|
-
result += this.finderPenaltyCountPatterns(runHistory) * QrCode.PENALTY_N3;
|
|
438
|
-
runColor = this.modules[y][x];
|
|
439
|
-
runY = 1;
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
result += this.finderPenaltyTerminateAndCount(runColor, runY, runHistory) * QrCode.PENALTY_N3;
|
|
443
|
-
}
|
|
444
|
-
// 2*2 blocks of modules having same color
|
|
445
|
-
for (let y = 0; y < this.size - 1; y++) {
|
|
446
|
-
for (let x = 0; x < this.size - 1; x++) {
|
|
447
|
-
const color = this.modules[y][x];
|
|
448
|
-
if (color == this.modules[y][x + 1] && color == this.modules[y + 1][x] && color == this.modules[y + 1][x + 1])
|
|
449
|
-
result += QrCode.PENALTY_N2;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
// Balance of dark and light modules
|
|
453
|
-
let dark = 0;
|
|
454
|
-
for (const row of this.modules)
|
|
455
|
-
dark = row.reduce((sum, color) => sum + (color ? 1 : 0), dark);
|
|
456
|
-
const total = this.size * this.size; // Note that size is odd, so dark/total != 1/2
|
|
457
|
-
// Compute the smallest integer k >= 0 such that (45-5k)% <= dark/total <= (55+5k)%
|
|
458
|
-
const k = Math.ceil(Math.abs(dark * 20 - total * 10) / total) - 1;
|
|
459
|
-
assert(k >= 0 && k <= 9);
|
|
460
|
-
result += k * QrCode.PENALTY_N4;
|
|
461
|
-
assert(result >= 0 && result <= 2568888); // Non-tight upper bound based on default values of PENALTY_N1, ..., N4
|
|
462
|
-
return result;
|
|
463
|
-
}
|
|
464
|
-
/*-- Private helper functions --*/
|
|
465
|
-
// Returns an ascending list of positions of alignment patterns for this version number.
|
|
466
|
-
// Each position is in the range [0,177), and are used on both the x and y axes.
|
|
467
|
-
// This could be implemented as lookup table of 40 variable-length lists of integers.
|
|
468
|
-
getAlignmentPatternPositions() {
|
|
469
|
-
if (this.version == 1)
|
|
470
|
-
return [];
|
|
471
|
-
else {
|
|
472
|
-
const numAlign = Math.floor(this.version / 7) + 2;
|
|
473
|
-
const step = this.version == 32 ? 26 : Math.ceil((this.version * 4 + 4) / (numAlign * 2 - 2)) * 2;
|
|
474
|
-
let result = [6];
|
|
475
|
-
for (let pos = this.size - 7; result.length < numAlign; pos -= step)
|
|
476
|
-
result.splice(1, 0, pos);
|
|
477
|
-
return result;
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
// Returns the number of data bits that can be stored in a QR Code of the given version number, after
|
|
481
|
-
// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
|
|
482
|
-
// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
|
|
483
|
-
static getNumRawDataModules(ver) {
|
|
484
|
-
if (ver < QrCode.MIN_VERSION || ver > QrCode.MAX_VERSION)
|
|
485
|
-
throw new RangeError('Version number out of range');
|
|
486
|
-
let result = (16 * ver + 128) * ver + 64;
|
|
487
|
-
if (ver >= 2) {
|
|
488
|
-
const numAlign = Math.floor(ver / 7) + 2;
|
|
489
|
-
result -= (25 * numAlign - 10) * numAlign - 55;
|
|
490
|
-
if (ver >= 7)
|
|
491
|
-
result -= 36;
|
|
492
|
-
}
|
|
493
|
-
assert(result >= 208 && result <= 29648);
|
|
494
|
-
return result;
|
|
495
|
-
}
|
|
496
|
-
// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
|
|
497
|
-
// QR Code of the given version number and error correction level, with remainder bits discarded.
|
|
498
|
-
// This stateless pure function could be implemented as a (40*4)-cell lookup table.
|
|
499
|
-
static getNumDataCodewords(ver, ecl) {
|
|
500
|
-
return (Math.floor(QrCode.getNumRawDataModules(ver) / 8) -
|
|
501
|
-
QrCode.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver] * QrCode.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver]);
|
|
502
|
-
}
|
|
503
|
-
// Returns a Reed-Solomon ECC generator polynomial for the given degree. This could be
|
|
504
|
-
// implemented as a lookup table over all possible parameter values, instead of as an algorithm.
|
|
505
|
-
static reedSolomonComputeDivisor(degree) {
|
|
506
|
-
if (degree < 1 || degree > 255)
|
|
507
|
-
throw new RangeError('Degree out of range');
|
|
508
|
-
// Polynomial coefficients are stored from highest to lowest power, excluding the leading term which is always 1.
|
|
509
|
-
// For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array [255, 8, 93].
|
|
510
|
-
let result = [];
|
|
511
|
-
for (let i = 0; i < degree - 1; i++)
|
|
512
|
-
result.push(0);
|
|
513
|
-
result.push(1); // Start off with the monomial x^0
|
|
514
|
-
// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
|
|
515
|
-
// and drop the highest monomial term which is always 1x^degree.
|
|
516
|
-
// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
|
|
517
|
-
let root = 1;
|
|
518
|
-
for (let i = 0; i < degree; i++) {
|
|
519
|
-
// Multiply the current product by (x - r^i)
|
|
520
|
-
for (let j = 0; j < result.length; j++) {
|
|
521
|
-
result[j] = QrCode.reedSolomonMultiply(result[j], root);
|
|
522
|
-
if (j + 1 < result.length)
|
|
523
|
-
result[j] ^= result[j + 1];
|
|
524
|
-
}
|
|
525
|
-
root = QrCode.reedSolomonMultiply(root, 0x02);
|
|
526
|
-
}
|
|
527
|
-
return result;
|
|
528
|
-
}
|
|
529
|
-
// Returns the Reed-Solomon error correction codeword for the given data and divisor polynomials.
|
|
530
|
-
static reedSolomonComputeRemainder(data, divisor) {
|
|
531
|
-
let result = divisor.map(_ => 0);
|
|
532
|
-
for (const b of data) {
|
|
533
|
-
// Polynomial division
|
|
534
|
-
const factor = b ^ result.shift();
|
|
535
|
-
result.push(0);
|
|
536
|
-
divisor.forEach((coef, i) => (result[i] ^= QrCode.reedSolomonMultiply(coef, factor)));
|
|
537
|
-
}
|
|
538
|
-
return result;
|
|
539
|
-
}
|
|
540
|
-
// Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result
|
|
541
|
-
// are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8.
|
|
542
|
-
static reedSolomonMultiply(x, y) {
|
|
543
|
-
if (x >>> 8 != 0 || y >>> 8 != 0)
|
|
544
|
-
throw new RangeError('Byte out of range');
|
|
545
|
-
// Russian peasant multiplication
|
|
546
|
-
let z = 0;
|
|
547
|
-
for (let i = 7; i >= 0; i--) {
|
|
548
|
-
z = (z << 1) ^ ((z >>> 7) * 0x11d);
|
|
549
|
-
z ^= ((y >>> i) & 1) * x;
|
|
550
|
-
}
|
|
551
|
-
assert(z >>> 8 == 0);
|
|
552
|
-
return z;
|
|
553
|
-
}
|
|
554
|
-
// Can only be called immediately after a light run is added, and
|
|
555
|
-
// returns either 0, 1, or 2. A helper function for getPenaltyScore().
|
|
556
|
-
finderPenaltyCountPatterns(runHistory) {
|
|
557
|
-
const n = runHistory[1];
|
|
558
|
-
assert(n <= this.size * 3);
|
|
559
|
-
const core = n > 0 && runHistory[2] == n && runHistory[3] == n * 3 && runHistory[4] == n && runHistory[5] == n;
|
|
560
|
-
return ((core && runHistory[0] >= n * 4 && runHistory[6] >= n ? 1 : 0) +
|
|
561
|
-
(core && runHistory[6] >= n * 4 && runHistory[0] >= n ? 1 : 0));
|
|
562
|
-
}
|
|
563
|
-
// Must be called at the end of a line (row or column) of modules. A helper function for getPenaltyScore().
|
|
564
|
-
finderPenaltyTerminateAndCount(currentRunColor, currentRunLength, runHistory) {
|
|
565
|
-
if (currentRunColor) {
|
|
566
|
-
// Terminate dark run
|
|
567
|
-
this.finderPenaltyAddHistory(currentRunLength, runHistory);
|
|
568
|
-
currentRunLength = 0;
|
|
569
|
-
}
|
|
570
|
-
currentRunLength += this.size; // Add light border to final run
|
|
571
|
-
this.finderPenaltyAddHistory(currentRunLength, runHistory);
|
|
572
|
-
return this.finderPenaltyCountPatterns(runHistory);
|
|
573
|
-
}
|
|
574
|
-
// Pushes the given value to the front and drops the last value. A helper function for getPenaltyScore().
|
|
575
|
-
finderPenaltyAddHistory(currentRunLength, runHistory) {
|
|
576
|
-
if (runHistory[0] == 0)
|
|
577
|
-
currentRunLength += this.size; // Add light border to initial run
|
|
578
|
-
runHistory.pop();
|
|
579
|
-
runHistory.unshift(currentRunLength);
|
|
580
|
-
}
|
|
581
|
-
/*-- Constants and tables --*/
|
|
582
|
-
// The minimum version number supported in the QR Code Model 2 standard.
|
|
583
|
-
static { this.MIN_VERSION = 1; }
|
|
584
|
-
// The maximum version number supported in the QR Code Model 2 standard.
|
|
585
|
-
static { this.MAX_VERSION = 40; }
|
|
586
|
-
// For use in getPenaltyScore(), when evaluating which mask is best.
|
|
587
|
-
static { this.PENALTY_N1 = 3; }
|
|
588
|
-
static { this.PENALTY_N2 = 3; }
|
|
589
|
-
static { this.PENALTY_N3 = 40; }
|
|
590
|
-
static { this.PENALTY_N4 = 10; }
|
|
591
|
-
static { this.ECC_CODEWORDS_PER_BLOCK = [
|
|
592
|
-
// Version: (note that index 0 is for padding, and is set to an illegal value)
|
|
593
|
-
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level
|
|
594
|
-
[
|
|
595
|
-
-1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30,
|
|
596
|
-
30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
|
|
597
|
-
], // Low
|
|
598
|
-
[
|
|
599
|
-
-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28,
|
|
600
|
-
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
|
|
601
|
-
], // Medium
|
|
602
|
-
[
|
|
603
|
-
-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30,
|
|
604
|
-
30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
|
|
605
|
-
], // Quartile
|
|
606
|
-
[
|
|
607
|
-
-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30,
|
|
608
|
-
30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
|
|
609
|
-
], // High
|
|
610
|
-
]; }
|
|
611
|
-
static { this.NUM_ERROR_CORRECTION_BLOCKS = [
|
|
612
|
-
// Version: (note that index 0 is for padding, and is set to an illegal value)
|
|
613
|
-
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level
|
|
614
|
-
[
|
|
615
|
-
-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18,
|
|
616
|
-
19, 19, 20, 21, 22, 24, 25,
|
|
617
|
-
], // Low
|
|
618
|
-
[
|
|
619
|
-
-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29,
|
|
620
|
-
31, 33, 35, 37, 38, 40, 43, 45, 47, 49,
|
|
621
|
-
], // Medium
|
|
622
|
-
[
|
|
623
|
-
-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40,
|
|
624
|
-
43, 45, 48, 51, 53, 56, 59, 62, 65, 68,
|
|
625
|
-
], // Quartile
|
|
626
|
-
[
|
|
627
|
-
-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45,
|
|
628
|
-
48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81,
|
|
629
|
-
], // High
|
|
630
|
-
]; }
|
|
631
|
-
}
|
|
632
|
-
qrcodegen.QrCode = QrCode;
|
|
633
|
-
// Appends the given number of low-order bits of the given value
|
|
634
|
-
// to the given buffer. Requires 0 <= len <= 31 and 0 <= val < 2^len.
|
|
635
|
-
function appendBits(val, len, bb) {
|
|
636
|
-
if (len < 0 || len > 31 || val >>> len != 0)
|
|
637
|
-
throw new RangeError('Value out of range');
|
|
638
|
-
for (let i = len - 1; i >= 0; i-- // Append bit by bit
|
|
639
|
-
)
|
|
640
|
-
bb.push((val >>> i) & 1);
|
|
641
|
-
}
|
|
642
|
-
// Returns true iff the i'th bit of x is set to 1.
|
|
643
|
-
function getBit(x, i) {
|
|
644
|
-
return ((x >>> i) & 1) != 0;
|
|
645
|
-
}
|
|
646
|
-
// Throws an exception if the given condition is false.
|
|
647
|
-
function assert(cond) {
|
|
648
|
-
if (!cond)
|
|
649
|
-
throw new Error('Assertion error');
|
|
650
|
-
}
|
|
651
|
-
/*---- Data segment class ----*/
|
|
652
|
-
/*
|
|
653
|
-
* A segment of character/binary/control data in a QR Code symbol.
|
|
654
|
-
* Instances of this class are immutable.
|
|
655
|
-
* The mid-level way to create a segment is to take the payload data
|
|
656
|
-
* and call a static factory function such as QrSegment.makeNumeric().
|
|
657
|
-
* The low-level way to create a segment is to custom-make the bit buffer
|
|
658
|
-
* and call the QrSegment() constructor with appropriate values.
|
|
659
|
-
* This segment class imposes no length restrictions, but QR Codes have restrictions.
|
|
660
|
-
* Even in the most favorable conditions, a QR Code can only hold 7089 characters of data.
|
|
661
|
-
* Any segment longer than this is meaningless for the purpose of generating QR Codes.
|
|
662
|
-
*/
|
|
663
|
-
class QrSegment {
|
|
664
|
-
/*-- Static factory functions (mid level) --*/
|
|
665
|
-
// Returns a segment representing the given binary data encoded in
|
|
666
|
-
// byte mode. All input byte arrays are acceptable. Any text string
|
|
667
|
-
// can be converted to UTF-8 bytes and encoded as a byte mode segment.
|
|
668
|
-
static makeBytes(data) {
|
|
669
|
-
let bb = [];
|
|
670
|
-
for (const b of data)
|
|
671
|
-
appendBits(b, 8, bb);
|
|
672
|
-
return new QrSegment(QrSegment.Mode.BYTE, data.length, bb);
|
|
673
|
-
}
|
|
674
|
-
// Returns a segment representing the given string of decimal digits encoded in numeric mode.
|
|
675
|
-
static makeNumeric(digits) {
|
|
676
|
-
if (!QrSegment.isNumeric(digits))
|
|
677
|
-
throw new RangeError('String contains non-numeric characters');
|
|
678
|
-
let bb = [];
|
|
679
|
-
for (let i = 0; i < digits.length;) {
|
|
680
|
-
// Consume up to 3 digits per iteration
|
|
681
|
-
const n = Math.min(digits.length - i, 3);
|
|
682
|
-
appendBits(parseInt(digits.substring(i, i + n), 10), n * 3 + 1, bb);
|
|
683
|
-
i += n;
|
|
684
|
-
}
|
|
685
|
-
return new QrSegment(QrSegment.Mode.NUMERIC, digits.length, bb);
|
|
686
|
-
}
|
|
687
|
-
// Returns a segment representing the given text string encoded in alphanumeric mode.
|
|
688
|
-
// The characters allowed are: 0 to 9, A to Z (uppercase only), space,
|
|
689
|
-
// dollar, percent, asterisk, plus, hyphen, period, slash, colon.
|
|
690
|
-
static makeAlphanumeric(text) {
|
|
691
|
-
if (!QrSegment.isAlphanumeric(text))
|
|
692
|
-
throw new RangeError('String contains unencodable characters in alphanumeric mode');
|
|
693
|
-
let bb = [];
|
|
694
|
-
let i;
|
|
695
|
-
for (i = 0; i + 2 <= text.length; i += 2) {
|
|
696
|
-
// Process groups of 2
|
|
697
|
-
let temp = QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)) * 45;
|
|
698
|
-
temp += QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i + 1));
|
|
699
|
-
appendBits(temp, 11, bb);
|
|
700
|
-
}
|
|
701
|
-
if (i < text.length)
|
|
702
|
-
// 1 character remaining
|
|
703
|
-
appendBits(QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)), 6, bb);
|
|
704
|
-
return new QrSegment(QrSegment.Mode.ALPHANUMERIC, text.length, bb);
|
|
705
|
-
}
|
|
706
|
-
// Returns a new mutable list of zero or more segments to represent the given Unicode text string.
|
|
707
|
-
// The result may use various segment modes and switch modes to optimize the length of the bit stream.
|
|
708
|
-
static makeSegments(text) {
|
|
709
|
-
// Select the most efficient segment encoding automatically
|
|
710
|
-
if (text == '')
|
|
711
|
-
return [];
|
|
712
|
-
else if (QrSegment.isNumeric(text))
|
|
713
|
-
return [QrSegment.makeNumeric(text)];
|
|
714
|
-
else if (QrSegment.isAlphanumeric(text))
|
|
715
|
-
return [QrSegment.makeAlphanumeric(text)];
|
|
716
|
-
else
|
|
717
|
-
return [QrSegment.makeBytes(QrSegment.toUtf8ByteArray(text))];
|
|
718
|
-
}
|
|
719
|
-
// Returns a segment representing an Extended Channel Interpretation
|
|
720
|
-
// (ECI) designator with the given assignment value.
|
|
721
|
-
static makeEci(assignVal) {
|
|
722
|
-
let bb = [];
|
|
723
|
-
if (assignVal < 0)
|
|
724
|
-
throw new RangeError('ECI assignment value out of range');
|
|
725
|
-
else if (assignVal < 1 << 7)
|
|
726
|
-
appendBits(assignVal, 8, bb);
|
|
727
|
-
else if (assignVal < 1 << 14) {
|
|
728
|
-
appendBits(0b10, 2, bb);
|
|
729
|
-
appendBits(assignVal, 14, bb);
|
|
730
|
-
}
|
|
731
|
-
else if (assignVal < 1000000) {
|
|
732
|
-
appendBits(0b110, 3, bb);
|
|
733
|
-
appendBits(assignVal, 21, bb);
|
|
734
|
-
}
|
|
735
|
-
else
|
|
736
|
-
throw new RangeError('ECI assignment value out of range');
|
|
737
|
-
return new QrSegment(QrSegment.Mode.ECI, 0, bb);
|
|
738
|
-
}
|
|
739
|
-
// Tests whether the given string can be encoded as a segment in numeric mode.
|
|
740
|
-
// A string is encodable iff each character is in the range 0 to 9.
|
|
741
|
-
static isNumeric(text) {
|
|
742
|
-
return QrSegment.NUMERIC_REGEX.test(text);
|
|
743
|
-
}
|
|
744
|
-
// Tests whether the given string can be encoded as a segment in alphanumeric mode.
|
|
745
|
-
// A string is encodable iff each character is in the following set: 0 to 9, A to Z
|
|
746
|
-
// (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon.
|
|
747
|
-
static isAlphanumeric(text) {
|
|
748
|
-
return QrSegment.ALPHANUMERIC_REGEX.test(text);
|
|
749
|
-
}
|
|
750
|
-
/*-- Constructor (low level) and fields --*/
|
|
751
|
-
// Creates a new QR Code segment with the given attributes and data.
|
|
752
|
-
// The character count (numChars) must agree with the mode and the bit buffer length,
|
|
753
|
-
// but the constraint isn't checked. The given bit buffer is cloned and stored.
|
|
754
|
-
constructor(
|
|
755
|
-
// The mode indicator of this segment.
|
|
756
|
-
mode,
|
|
757
|
-
// The length of this segment's unencoded data. Measured in characters for
|
|
758
|
-
// numeric/alphanumeric/kanji mode, bytes for byte mode, and 0 for ECI mode.
|
|
759
|
-
// Always zero or positive. Not the same as the data's bit length.
|
|
760
|
-
numChars,
|
|
761
|
-
// The data bits of this segment. Accessed through getData().
|
|
762
|
-
bitData) {
|
|
763
|
-
this.mode = mode;
|
|
764
|
-
this.numChars = numChars;
|
|
765
|
-
this.bitData = bitData;
|
|
766
|
-
if (numChars < 0)
|
|
767
|
-
throw new RangeError('Invalid argument');
|
|
768
|
-
this.bitData = bitData.slice(); // Make defensive copy
|
|
769
|
-
}
|
|
770
|
-
/*-- Methods --*/
|
|
771
|
-
// Returns a new copy of the data bits of this segment.
|
|
772
|
-
getData() {
|
|
773
|
-
return this.bitData.slice(); // Make defensive copy
|
|
774
|
-
}
|
|
775
|
-
// (Package-private) Calculates and returns the number of bits needed to encode the given segments at
|
|
776
|
-
// the given version. The result is infinity if a segment has too many characters to fit its length field.
|
|
777
|
-
static getTotalBits(segs, version) {
|
|
778
|
-
let result = 0;
|
|
779
|
-
for (const seg of segs) {
|
|
780
|
-
const ccbits = seg.mode.numCharCountBits(version);
|
|
781
|
-
if (seg.numChars >= 1 << ccbits)
|
|
782
|
-
return Infinity; // The segment's length doesn't fit the field's bit width
|
|
783
|
-
result += 4 + ccbits + seg.bitData.length;
|
|
784
|
-
}
|
|
785
|
-
return result;
|
|
786
|
-
}
|
|
787
|
-
// Returns a new array of bytes representing the given string encoded in UTF-8.
|
|
788
|
-
static toUtf8ByteArray(str) {
|
|
789
|
-
str = encodeURI(str);
|
|
790
|
-
let result = [];
|
|
791
|
-
for (let i = 0; i < str.length; i++) {
|
|
792
|
-
if (str.charAt(i) != '%')
|
|
793
|
-
result.push(str.charCodeAt(i));
|
|
794
|
-
else {
|
|
795
|
-
result.push(parseInt(str.substring(i + 1, i + 3), 16));
|
|
796
|
-
i += 2;
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
return result;
|
|
800
|
-
}
|
|
801
|
-
/*-- Constants --*/
|
|
802
|
-
// Describes precisely all strings that are encodable in numeric mode.
|
|
803
|
-
static { this.NUMERIC_REGEX = /^[0-9]*$/; }
|
|
804
|
-
// Describes precisely all strings that are encodable in alphanumeric mode.
|
|
805
|
-
static { this.ALPHANUMERIC_REGEX = /^[A-Z0-9 $%*+.\/:-]*$/; }
|
|
806
|
-
// The set of all legal characters in alphanumeric mode,
|
|
807
|
-
// where each character value maps to the index in the string.
|
|
808
|
-
static { this.ALPHANUMERIC_CHARSET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:'; }
|
|
809
|
-
}
|
|
810
|
-
qrcodegen.QrSegment = QrSegment;
|
|
811
|
-
})(qrcodegen || (qrcodegen = {}));
|
|
812
|
-
/*---- Public helper enumeration ----*/
|
|
813
|
-
(function (qrcodegen) {
|
|
814
|
-
var QrCode;
|
|
815
|
-
(function (QrCode) {
|
|
816
|
-
/*
|
|
817
|
-
* The error correction level in a QR Code symbol. Immutable.
|
|
818
|
-
*/
|
|
819
|
-
class Ecc {
|
|
820
|
-
/*-- Constants --*/
|
|
821
|
-
static { this.LOW = new Ecc(0, 1); } // The QR Code can tolerate about 7% erroneous codewords
|
|
822
|
-
static { this.MEDIUM = new Ecc(1, 0); } // The QR Code can tolerate about 15% erroneous codewords
|
|
823
|
-
static { this.QUARTILE = new Ecc(2, 3); } // The QR Code can tolerate about 25% erroneous codewords
|
|
824
|
-
static { this.HIGH = new Ecc(3, 2); } // The QR Code can tolerate about 30% erroneous codewords
|
|
825
|
-
/*-- Constructor and fields --*/
|
|
826
|
-
constructor(
|
|
827
|
-
// In the range 0 to 3 (unsigned 2-bit integer).
|
|
828
|
-
ordinal,
|
|
829
|
-
// (Package-private) In the range 0 to 3 (unsigned 2-bit integer).
|
|
830
|
-
formatBits) {
|
|
831
|
-
this.ordinal = ordinal;
|
|
832
|
-
this.formatBits = formatBits;
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
QrCode.Ecc = Ecc;
|
|
836
|
-
})(QrCode = qrcodegen.QrCode || (qrcodegen.QrCode = {}));
|
|
837
|
-
})(qrcodegen || (qrcodegen = {}));
|
|
838
|
-
/*---- Public helper enumeration ----*/
|
|
839
|
-
(function (qrcodegen) {
|
|
840
|
-
var QrSegment;
|
|
841
|
-
(function (QrSegment) {
|
|
842
|
-
/*
|
|
843
|
-
* Describes how a segment's data bits are interpreted. Immutable.
|
|
844
|
-
*/
|
|
845
|
-
class Mode {
|
|
846
|
-
/*-- Constants --*/
|
|
847
|
-
static { this.NUMERIC = new Mode(0x1, [10, 12, 14]); }
|
|
848
|
-
static { this.ALPHANUMERIC = new Mode(0x2, [9, 11, 13]); }
|
|
849
|
-
static { this.BYTE = new Mode(0x4, [8, 16, 16]); }
|
|
850
|
-
static { this.KANJI = new Mode(0x8, [8, 10, 12]); }
|
|
851
|
-
static { this.ECI = new Mode(0x7, [0, 0, 0]); }
|
|
852
|
-
/*-- Constructor and fields --*/
|
|
853
|
-
constructor(
|
|
854
|
-
// The mode indicator bits, which is a uint4 value (range 0 to 15).
|
|
855
|
-
modeBits,
|
|
856
|
-
// Number of character count bits for three different version ranges.
|
|
857
|
-
numBitsCharCount) {
|
|
858
|
-
this.modeBits = modeBits;
|
|
859
|
-
this.numBitsCharCount = numBitsCharCount;
|
|
860
|
-
}
|
|
861
|
-
/*-- Method --*/
|
|
862
|
-
// (Package-private) Returns the bit width of the character count field for a segment in
|
|
863
|
-
// this mode in a QR Code at the given version number. The result is in the range [0, 16].
|
|
864
|
-
numCharCountBits(ver) {
|
|
865
|
-
return this.numBitsCharCount[Math.floor((ver + 7) / 17)];
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
QrSegment.Mode = Mode;
|
|
869
|
-
})(QrSegment = qrcodegen.QrSegment || (qrcodegen.QrSegment = {}));
|
|
870
|
-
})(qrcodegen || (qrcodegen = {}));
|
|
871
|
-
export default qrcodegen;
|
|
872
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXJjb2RlZ2VuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbGliL3FyY29kZS9xcmNvZGVnZW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUVILFlBQVksQ0FBQztBQUViLElBQVUsU0FBUyxDQTIxQmxCO0FBMzFCRCxXQUFVLFNBQVM7SUFLakIsa0NBQWtDO0lBRWxDOzs7Ozs7Ozs7Ozs7Ozs7T0FlRztJQUNILE1BQWEsTUFBTTtRQUNqQiwrQ0FBK0M7UUFFL0Msb0dBQW9HO1FBQ3BHLDJHQUEyRztRQUMzRywrR0FBK0c7UUFDL0csNkdBQTZHO1FBQzdHLGlFQUFpRTtRQUMxRCxNQUFNLENBQUMsVUFBVSxDQUFDLElBQVksRUFBRSxHQUFlO1lBQ3BELE1BQU0sSUFBSSxHQUFxQixTQUFTLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN0RSxPQUFPLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzFDLENBQUM7UUFFRCw0RkFBNEY7UUFDNUYsdUdBQXVHO1FBQ3ZHLHVHQUF1RztRQUN2RyxvSEFBb0g7UUFDN0csTUFBTSxDQUFDLFlBQVksQ0FBQyxJQUEyQixFQUFFLEdBQWU7WUFDckUsTUFBTSxHQUFHLEdBQWMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDM0QsT0FBTyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDM0MsQ0FBQztRQUVELDhDQUE4QztRQUU5Qyx3RkFBd0Y7UUFDeEYsZ0ZBQWdGO1FBQ2hGLGdGQUFnRjtRQUNoRiwrRUFBK0U7UUFDL0UsOEVBQThFO1FBQzlFLCtFQUErRTtRQUMvRSxzRkFBc0Y7UUFDdEYsOEVBQThFO1FBQzlFLGtGQUFrRjtRQUMzRSxNQUFN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LEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFO2dCQUM3RyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFO2FBQ25ELEVBQUUsTUFBTTtZQUNUO2dCQUNFLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRTtnQkFDOUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRTthQUNuRCxFQUFFLFNBQVM7WUFDWjtnQkFDRSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7Z0JBQzlHLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7YUFDbkQsRUFBRSxXQUFXO1lBQ2Q7Z0JBQ0UsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFO2dCQUM5RyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFO2FBQ25ELEVBQUUsT0FBTztTQUNYLEFBbkI4QyxDQW1CN0M7aUJBRXNCLGdDQUEyQixHQUFzQjtZQUN2RSw4RUFBOEU7WUFDOUUsbUxBQW1MO1lBQ25MO2dCQUNFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRTtnQkFDL0csRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRTthQUMzQixFQUFFLE1BQU07WUFDVDtnQkFDRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7Z0JBQzVHLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7YUFDdkMsRUFBRSxTQUFTO1lBQ1o7Z0JBQ0UsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFF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QzFDLFNBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7cUJBQ2xDLFVBQUssR0FBRyxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7cUJBQ25DLFFBQUcsR0FBRyxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFdEQsZ0NBQWdDO1lBRWhDO1lBQ0UsbUVBQW1FO1lBQ25ELFFBQWE7WUFDN0IscUVBQXFFO1lBQ3BELGdCQUFpQztnQkFGbEMsYUFBUSxHQUFSLFFBQVEsQ0FBSztnQkFFWixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWlCO1lBQ2pELENBQUM7WUFFSixnQkFBZ0I7WUFFaEIsd0ZBQXdGO1lBQ3hGLDBGQUEwRjtZQUNuRixnQkFBZ0IsQ0FBQyxHQUFRO2dCQUM5QixPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDM0QsQ0FBQzs7UUF4QlUsY0FBSSxPQXlCaEIsQ0FBQTtJQUNILENBQUMsRUFoQ21CLFNBQVMsR0FBVCxtQkFBUyxLQUFULG1CQUFTLFFBZ0M1QjtBQUFELENBQUMsRUFoQ1MsU0FBUyxLQUFULFNBQVMsUUFnQ2xCO0FBRUQsZUFBZSxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogUVIgQ29kZSBnZW5lcmF0b3IgbGlicmFyeSAoVHlwZVNjcmlwdClcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIFByb2plY3QgTmF5dWtpLiAoTUlUIExpY2Vuc2UpXG4gKiBodHRwczovL3d3dy5uYXl1a2kuaW8vcGFnZS9xci1jb2RlLWdlbmVyYXRvci1saWJyYXJ5XG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weSBvZlxuICogdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpblxuICogdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0b1xuICogdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2ZcbiAqIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbyxcbiAqIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICogLSBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuICogICBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqIC0gVGhlIFNvZnR3YXJlIGlzIHByb3ZpZGVkIFwiYXMgaXNcIiwgd2l0aG91dCB3YXJyYW50eSBvZiBhbnkga2luZCwgZXhwcmVzcyBvclxuICogICBpbXBsaWVkLCBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHRoZSB3YXJyYW50aWVzIG9mIG1lcmNoYW50YWJpbGl0eSxcbiAqICAgZml0bmVzcyBmb3IgYSBwYXJ0aWN1bGFyIHB1cnBvc2UgYW5kIG5vbmluZnJpbmdlbWVudC4gSW4gbm8gZXZlbnQgc2hhbGwgdGhlXG4gKiAgIGF1dGhvcnMgb3IgY29weXJpZ2h0IGhvbGRlcnMgYmUgbGlhYmxlIGZvciBhbnkgY2xhaW0sIGRhbWFnZXMgb3Igb3RoZXJcbiAqICAgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGFuIGFjdGlvbiBvZiBjb250cmFjdCwgdG9ydCBvciBvdGhlcndpc2UsIGFyaXNpbmcgZnJvbSxcbiAqICAgb3V0IG9mIG9yIGluIGNvbm5lY3Rpb24gd2l0aCB0aGUgU29mdHdhcmUgb3IgdGhlIHVzZSBvciBvdGhlciBkZWFsaW5ncyBpbiB0aGVcbiAqICAgU29mdHdhcmUuXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5uYW1lc3BhY2UgcXJjb2RlZ2VuIHtcbiAgdHlwZSBiaXQgPSBudW1iZXI7XG4gIHR5cGUgYnl0ZSA9IG51bWJlcjtcbiAgdHlwZSBpbnQgPSBudW1iZXI7XG5cbiAgLyotLS0tIFFSIENvZGUgc3ltYm9sIGNsYXNzIC0tLS0qL1xuXG4gIC8qXG4gICAqIEEgUVIgQ29kZSBzeW1ib2wsIHdoaWNoIGlzIGEgdHlwZSBvZiB0d28tZGltZW5zaW9uIGJhcmNvZGUuXG4gICAqIEludmVudGVkIGJ5IERlbnNvIFdhdmUgYW5kIGRlc2NyaWJlZCBpbiB0aGUgSVNPL0lFQyAxODAwNCBzdGFuZGFyZC5cbiAgICogSW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MgcmVwcmVzZW50IGFuIGltbXV0YWJsZSBzcXVhcmUgZ3JpZCBvZiBkYXJrIGFuZCBsaWdodCBjZWxscy5cbiAgICogVGhlIGNsYXNzIHByb3ZpZGVzIHN0YXRpYyBmYWN0b3J5IGZ1bmN0aW9ucyB0byBjcmVhdGUgYSBRUiBDb2RlIGZyb20gdGV4dCBvciBiaW5hcnkgZGF0YS5cbiAgICogVGhlIGNsYXNzIGNvdmVycyB0aGUgUVIgQ29kZSBNb2RlbCAyIHNwZWNpZmljYXRpb24sIHN1cHBvcnRpbmcgYWxsIHZlcnNpb25zIChzaXplcylcbiAgICogZnJvbSAxIHRvIDQwLCBhbGwgNCBlcnJvciBjb3JyZWN0aW9uIGxldmVscywgYW5kIDQgY2hhcmFjdGVyIGVuY29kaW5nIG1vZGVzLlxuICAgKlxuICAgKiBXYXlzIHRvIGNyZWF0ZSBhIFFSIENvZGUgb2JqZWN0OlxuICAgKiAtIEhpZ2ggbGV2ZWw6IFRha2UgdGhlIHBheWxvYWQgZGF0YSBhbmQgY2FsbCBRckNvZGUuZW5jb2RlVGV4dCgpIG9yIFFyQ29kZS5lbmNvZGVCaW5hcnkoKS5cbiAgICogLSBNaWQgbGV2ZWw6IEN1c3RvbS1tYWtlIHRoZSBsaXN0IG9mIHNlZ21lbnRzIGFuZCBjYWxsIFFyQ29kZS5lbmNvZGVTZWdtZW50cygpLlxuICAgKiAtIExvdyBsZXZlbDogQ3VzdG9tLW1ha2UgdGhlIGFycmF5IG9mIGRhdGEgY29kZXdvcmQgYnl0ZXMgKGluY2x1ZGluZ1xuICAgKiAgIHNlZ21lbnQgaGVhZGVycyBhbmQgZmluYWwgcGFkZGluZywgZXhjbHVkaW5nIGVycm9yIGNvcnJlY3Rpb24gY29kZXdvcmRzKSxcbiAgICogICBzdXBwbHkgdGhlIGFwcHJvcHJpYXRlIHZlcnNpb24gbnVtYmVyLCBhbmQgY2FsbCB0aGUgUXJDb2RlKCkgY29uc3RydWN0b3IuXG4gICAqIChOb3RlIHRoYXQgYWxsIHdheXMgcmVxdWlyZSBzdXBwbHlpbmcgdGhlIGRlc2lyZWQgZXJyb3IgY29ycmVjdGlvbiBsZXZlbC4pXG4gICAqL1xuICBleHBvcnQgY2xhc3MgUXJDb2RlIHtcbiAgICAvKi0tIFN0YXRpYyBmYWN0b3J5IGZ1bmN0aW9ucyAoaGlnaCBsZXZlbCkgLS0qL1xuXG4gICAgLy8gUmV0dXJucyBhIFFSIENvZGUgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiBVbmljb2RlIHRleHQgc3RyaW5nIGF0IHRoZSBnaXZlbiBlcnJvciBjb3JyZWN0aW9uIGxldmVsLlxuICAgIC8vIEFzIGEgY29uc2VydmF0aXZlIHVwcGVyIGJvdW5kLCB0aGlzIGZ1bmN0aW9uIGlzIGd1YXJhbnRlZWQgdG8gc3VjY2VlZCBmb3Igc3RyaW5ncyB0aGF0IGhhdmUgNzM4IG9yIGZld2VyXG4gICAgLy8gVW5pY29kZSBjb2RlIHBvaW50cyAobm90IFVURi0xNiBjb2RlIHVuaXRzKSBpZiB0aGUgbG93IGVycm9yIGNvcnJlY3Rpb24gbGV2ZWwgaXMgdXNlZC4gVGhlIHNtYWxsZXN0IHBvc3NpYmxlXG4gICAgLy8gUVIgQ29kZSB2ZXJzaW9uIGlzIGF1dG9tYXRpY2FsbHkgY2hvc2VuIGZvciB0aGUgb3V0cHV0LiBUaGUgRUNDIGxldmVsIG9mIHRoZSByZXN1bHQgbWF5IGJlIGhpZ2hlciB0aGFuIHRoZVxuICAgIC8vIGVjbCBhcmd1bWVudCBpZiBpdCBjYW4gYmUgZG9uZSB3aXRob3V0IGluY3JlYXNpbmcgdGhlIHZlcnNpb24uXG4gICAgcHVibGljIHN0YXRpYyBlbmNvZGVUZXh0KHRleHQ6IHN0cmluZywgZWNsOiBRckNvZGUuRWNjKTogUXJDb2RlIHtcbiAgICAgIGNvbnN0IHNlZ3M6IEFycmF5PFFyU2VnbWVudD4gPSBxcmNvZGVnZW4uUXJTZWdtZW50Lm1ha2VTZWdtZW50cyh0ZXh0KTtcbiAgICAgIHJldHVybiBRckNvZGUuZW5jb2RlU2VnbWVudHMoc2VncywgZWNsKTtcbiAgICB9XG5cbiAgICAvLyBSZXR1cm5zIGEgUVIgQ29kZSByZXByZXNlbnRpbmcgdGhlIGdpdmVuIGJpbmFyeSBkYXRhIGF0IHRoZSBnaXZlbiBlcnJvciBjb3JyZWN0aW9uIGxldmVsLlxuICAgIC8vIFRoaXMgZnVuY3Rpb24gYWx3YXlzIGVuY29kZXMgdXNpbmcgdGhlIGJpbmFyeSBzZWdtZW50IG1vZGUsIG5vdCBhbnkgdGV4dCBtb2RlLiBUaGUgbWF4aW11bSBudW1iZXIgb2ZcbiAgICAvLyBieXRlcyBhbGxvd2VkIGlzIDI5NTMuIFRoZSBzbWFsbGVzdCBwb3NzaWJsZSBRUiBDb2RlIHZlcnNpb24gaXMgYXV0b21hdGljYWxseSBjaG9zZW4gZm9yIHRoZSBvdXRwdXQuXG4gICAgLy8gVGhlIEVDQyBsZXZlbCBvZiB0aGUgcmVzdWx0IG1heSBiZSBoaWdoZXIgdGhhbiB0aGUgZWNsIGFyZ3VtZW50IGlmIGl0IGNhbiBiZSBkb25lIHdpdGhvdXQgaW5jcmVhc2luZyB0aGUgdmVyc2lvbi5cbiAgICBwdWJsaWMgc3RhdGljIGVuY29kZUJpbmFyeShkYXRhOiBSZWFkb25seTxBcnJheTxieXRlPj4sIGVjbDogUXJDb2RlLkVjYyk6IFFyQ29kZSB7XG4gICAgICBjb25zdCBzZWc6IFFyU2VnbWVudCA9IHFyY29kZWdlbi5RclNlZ21lbnQubWFrZUJ5dGVzKGRhdGEpO1xuICAgICAgcmV0dXJuIFFyQ29kZS5lbmNvZGVTZWdtZW50cyhbc2VnXSwgZWNsKTtcbiAgICB9XG5cbiAgICAvKi0tIFN0YXRpYyBmYWN0b3J5IGZ1bmN0aW9ucyAobWlkIGxldmVsKSAtLSovXG5cbiAgICAvLyBSZXR1cm5zIGEgUVIgQ29kZSByZXByZXNlbnRpbmcgdGhlIGdpdmVuIHNlZ21lbnRzIHdpdGggdGhlIGdpdmVuIGVuY29kaW5nIHBhcmFtZXRlcnMuXG4gICAgLy8gVGhlIHNtYWxsZXN0IHBvc3NpYmxlIFFSIENvZGUgdmVyc2lvbiB3aXRoaW4gdGhlIGdpdmVuIHJhbmdlIGlzIGF1dG9tYXRpY2FsbHlcbiAgICAvLyBjaG9zZW4gZm9yIHRoZSBvdXRwdXQuIElmZiBib29zdEVjbCBpcyB0cnVlLCB0aGVuIHRoZSBFQ0MgbGV2ZWwgb2YgdGhlIHJlc3VsdFxuICAgIC8vIG1heSBiZSBoaWdoZXIgdGhhbiB0aGUgZWNsIGFyZ3VtZW50IGlmIGl0IGNhbiBiZSBkb25lIHdpdGhvdXQgaW5jcmVhc2luZyB0aGVcbiAgICAvLyB2ZXJzaW9uLiBUaGUgbWFzayBudW1iZXIgaXMgZWl0aGVyIGJldHdlZW4gMCB0byA3IChpbmNsdXNpdmUpIHRvIGZvcmNlIHRoYXRcbiAgICAvLyBtYXNrLCBvciAtMSB0byBhdXRvbWF0aWNhbGx5IGNob29zZSBhbiBhcHByb3ByaWF0ZSBtYXNrICh3aGljaCBtYXkgYmUgc2xvdykuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBhbGxvd3MgdGhlIHVzZXIgdG8gY3JlYXRlIGEgY3VzdG9tIHNlcXVlbmNlIG9mIHNlZ21lbnRzIHRoYXQgc3dpdGNoZXNcbiAgICAvLyBiZXR3ZWVuIG1vZGVzIChzdWNoIGFzIGFscGhhbnVtZXJpYyBhbmQgYnl0ZSkgdG8gZW5jb2RlIHRleHQgaW4gbGVzcyBzcGFjZS5cbiAgICAvLyBUaGlzIGlzIGEgbWlkLWxldmVsIEFQSTsgdGhlIGhpZ2gtbGV2ZWwgQVBJIGlzIGVuY29kZVRleHQoKSBhbmQgZW5jb2RlQmluYXJ5KCkuXG4gICAgcHVibGljIHN0YXRpYyBlbmNvZGVTZWdtZW50cyhcbiAgICAgIHNlZ3M6IFJlYWRvbmx5PEFycmF5PFFyU2VnbWVudD4+LFxuICAgICAgZWNsOiBRckNvZGUuRWNjLFxuICAgICAgbWluVmVyc2lvbjogaW50ID0gMSxcbiAgICAgIG1heFZlcnNpb246IGludCA9IDQwLFxuICAgICAgbWFzazogaW50ID0gLTEsXG4gICAgICBib29zdEVjbDogYm9vbGVhbiA9IHRydWVcbiAgICApOiBRckNvZGUge1xuICAgICAgaWYgKFxuICAgICAgICAhKFFyQ29kZS5NSU5fVkVSU0lPTiA8PSBtaW5WZXJzaW9uICYmIG1pblZlcnNpb24gPD0gbWF4VmVyc2lvbiAmJiBtYXhWZXJzaW9uIDw9IFFyQ29kZS5NQVhfVkVSU0lPTikgfHxcbiAgICAgICAgbWFzayA8IC0xIHx8XG4gICAgICAgIG1hc2sgPiA3XG4gICAgICApXG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbnZhbGlkIHZhbHVlJyk7XG5cbiAgICAgIC8vIEZpbmQgdGhlIG1pbmltYWwgdmVyc2lvbiBudW1iZXIgdG8gdXNlXG4gICAgICBsZXQgdmVyc2lvbjogaW50O1xuICAgICAgbGV0IGRhdGFVc2VkQml0czogaW50O1xuICAgICAgZm9yICh2ZXJzaW9uID0gbWluVmVyc2lvbjsgOyB2ZXJzaW9uKyspIHtcbiAgICAgICAgY29uc3QgZGF0YUNhcGFjaXR5Qml0czogaW50ID0gUXJDb2RlLmdldE51bURhdGFDb2Rld29yZHModmVyc2lvbiwgZWNsKSAqIDg7IC8vIE51bWJlciBvZiBkYXRhIGJpdHMgYXZhaWxhYmxlXG4gICAgICAgIGNvbnN0IHVzZWRCaXRzOiBudW1iZXIgPSBRclNlZ21lbnQuZ2V0VG90YWxCaXRzKHNlZ3MsIHZlcnNpb24pO1xuICAgICAgICBpZiAodXNlZEJpdHMgPD0gZGF0YUNhcGFjaXR5Qml0cykge1xuICAgICAgICAgIGRhdGFVc2VkQml0cyA9IHVzZWRCaXRzO1xuICAgICAgICAgIGJyZWFrOyAvLyBUaGlzIHZlcnNpb24gbnVtYmVyIGlzIGZvdW5kIHRvIGJlIHN1aXRhYmxlXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZlcnNpb24gPj0gbWF4VmVyc2lvbilcbiAgICAgICAgICAvLyBBbGwgdmVyc2lvbnMgaW4gdGhlIHJhbmdlIGNvdWxkIG5vdCBmaXQgdGhlIGdpdmVuIGRhdGFcbiAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignRGF0YSB0b28gbG9uZycpO1xuICAgICAgfVxuXG4gICAgICAvLyBJbmNyZWFzZSB0aGUgZXJyb3IgY29ycmVjdGlvbiBsZXZlbCB3aGlsZSB0aGUgZGF0YSBzdGlsbCBmaXRzIGluIHRoZSBjdXJyZW50IHZlcnNpb24gbnVtYmVyXG4gICAgICBmb3IgKGNvbnN0IG5ld0VjbCBvZiBbUXJDb2RlLkVjYy5NRURJVU0sIFFyQ29kZS5FY2MuUVVBUlRJTEUsIFFyQ29kZS5FY2MuSElHSF0pIHtcbiAgICAgICAgLy8gRnJvbSBsb3cgdG8gaGlnaFxuICAgICAgICBpZiAoYm9vc3RFY2wgJiYgZGF0YVVzZWRCaXRzIDw9IFFyQ29kZS5nZXROdW1EYXRhQ29kZXdvcmRzKHZlcnNpb24sIG5ld0VjbCkgKiA4KSBlY2wgPSBuZXdFY2w7XG4gICAgICB9XG5cbiAgICAgIC8vIENvbmNhdGVuYXRlIGFsbCBzZWdtZW50cyB0byBjcmVhdGUgdGhlIGRhdGEgYml0IHN0cmluZ1xuICAgICAgbGV0IGJiOiBBcnJheTxiaXQ+ID0gW107XG4gICAgICBmb3IgKGNvbnN0IHNlZyBvZiBzZWdzKSB7XG4gICAgICAgIGFwcGVuZEJpdHMoc2VnLm1vZGUubW9kZUJpdHMsIDQsIGJiKTtcbiAgICAgICAgYXBwZW5kQml0cyhzZWcubnVtQ2hhcnMsIHNlZy5tb2RlLm51bUNoYXJDb3VudEJpdHModmVyc2lvbiksIGJiKTtcbiAgICAgICAgZm9yIChjb25zdCBiIG9mIHNlZy5nZXREYXRhKCkpIGJiLnB1c2goYik7XG4gICAgICB9XG4gICAgICBhc3NlcnQoYmIubGVuZ3RoID09IGRhdGFVc2VkQml0cyk7XG5cbiAgICAgIC8vIEFkZCB0ZXJtaW5hdG9yIGFuZCBwYWQgdXAgdG8gYSBieXRlIGlmIGFwcGxpY2FibGVcbiAgICAgIGNvbnN0IGRhdGFDYXBhY2l0eUJpdHM6IGludCA9IFFyQ29kZS5nZXROdW1EYXRhQ29kZXdvcmRzKHZlcnNpb24sIGVjbCkgKiA4O1xuICAgICAgYXNzZXJ0KGJiLmxlbmd0aCA8PSBkYXRhQ2FwYWNpdHlCaXRzKTtcbiAgICAgIGFwcGVuZEJpdHMoMCwgTWF0aC5taW4oNCwgZGF0YUNhcGFjaXR5Qml0cyAtIGJiLmxlbmd0aCksIGJiKTtcbiAgICAgIGFwcGVuZEJpdHMoMCwgKDggLSAoYmIubGVuZ3RoICUgOCkpICUgOCwgYmIpO1xuICAgICAgYXNzZXJ0KGJiLmxlbmd0aCAlIDggPT0gMCk7XG5cbiAgICAgIC8vIFBhZCB3aXRoIGFsdGVybmF0aW5nIGJ5dGVzIHVudGlsIGRhdGEgY2FwYWNpdHkgaXMgcmVhY2hlZFxuICAgICAgZm9yIChsZXQgcGFkQnl0ZSA9IDB4ZWM7IGJiLmxlbmd0aCA8IGRhdGFDYXBhY2l0eUJpdHM7IHBhZEJ5dGUgXj0gMHhlYyBeIDB4MTEpIGFwcGVuZEJpdHMocGFkQnl0ZSwgOCwgYmIpO1xuXG4gICAgICAvLyBQYWNrIGJpdHMgaW50byBieXRlcyBpbiBiaWcgZW5kaWFuXG4gICAgICBsZXQgZGF0YUNvZGV3b3JkczogQXJyYXk8Ynl0ZT4gPSBbXTtcbiAgICAgIHdoaWxlIChkYXRhQ29kZXdvcmRzLmxlbmd0aCAqIDggPCBiYi5sZW5ndGgpIGRhdGFDb2Rld29yZHMucHVzaCgwKTtcbiAgICAgIGJiLmZvckVhY2goKGI6IGJpdCwgaTogaW50KSA9PiAoZGF0YUNvZGV3b3Jkc1tpID4+PiAzXSB8PSBiIDw8ICg3IC0gKGkgJiA3KSkpKTtcblxuICAgICAgLy8gQ3JlYXRlIHRoZSBRUiBDb2RlIG9iamVjdFxuICAgICAgcmV0dXJuIG5ldyBRckNvZGUodmVyc2lvbiwgZWNsLCBkYXRhQ29kZXdvcmRzLCBtYXNrKTtcbiAgICB9XG5cbiAgICAvKi0tIEZpZWxkcyAtLSovXG5cbiAgICAvLyBUaGUgd2lkdGggYW5kIGhlaWdodCBvZiB0aGlzIFFSIENvZGUsIG1lYXN1cmVkIGluIG1vZHVsZXMsIGJldHdlZW5cbiAgICAvLyAyMSBhbmQgMTc3IChpbmNsdXNpdmUpLiBUaGlzIGlzIGVxdWFsIHRvIHZlcnNpb24gKiA0ICsgMTcuXG4gICAgcHVibGljIHJlYWRvbmx5IHNpemU6IGludDtcblxuICAgIC8vIFRoZSBpbmRleCBvZiB0aGUgbWFzayBwYXR0ZXJuIHVzZWQgaW4gdGhpcyBRUiBDb2RlLCB3aGljaCBpcyBiZXR3ZWVuIDAgYW5kIDcgKGluY2x1c2l2ZSkuXG4gICAgLy8gRXZlbiBpZiBhIFFSIENvZGUgaXMgY3JlYXRlZCB3aXRoIGF1dG9tYXRpYyBtYXNraW5nIHJlcXVlc3RlZCAobWFzayA9IC0xKSxcbiAgICAvLyB0aGUgcmVzdWx0aW5nIG9iamVjdCBzdGlsbCBoYXMgYSBtYXNrIHZhbHVlIGJldHdlZW4gMCBhbmQgNy5cbiAgICBwdWJsaWMgcmVhZG9ubHkgbWFzazogaW50O1xuXG4gICAgLy8gVGhlIG1vZHVsZXMgb2YgdGhpcyBRUiBDb2RlIChmYWxzZSA9IGxpZ2h0LCB0cnVlID0gZGFyaykuXG4gICAgLy8gSW1tdXRhYmxlIGFmdGVyIGNvbnN0cnVjdG9yIGZpbmlzaGVzLiBBY2Nlc3NlZCB0aHJvdWdoIGdldE1vZHVsZSgpLlxuICAgIHByaXZhdGUgcmVhZG9ubHkgbW9kdWxlczogQXJyYXk8QXJyYXk8Ym9vbGVhbj4+ID0gW107XG5cbiAgICAvLyBJbmRpY2F0ZXMgZnVuY3Rpb24gbW9kdWxlcyB0aGF0IGFyZSBub3Qgc3ViamVjdGVkIHRvIG1hc2tpbmcuIERpc2NhcmRlZCB3aGVuIGNvbnN0cnVjdG9yIGZpbmlzaGVzLlxuICAgIHByaXZhdGUgcmVhZG9ubHkgaXNGdW5jdGlvbjogQXJyYXk8QXJyYXk8Ym9vbGVhbj4+ID0gW107XG5cbiAgICAvKi0tIENvbnN0cnVjdG9yIChsb3cgbGV2ZWwpIGFuZCBmaWVsZHMgLS0qL1xuXG4gICAgLy8gQ3JlYXRlcyBhIG5ldyBRUiBDb2RlIHdpdGggdGhlIGdpdmVuIHZlcnNpb24gbnVtYmVyLFxuICAgIC8vIGVycm9yIGNvcnJlY3Rpb24gbGV2ZWwsIGRhdGEgY29kZXdvcmQgYnl0ZXMsIGFuZCBtYXNrIG51bWJlci5cbiAgICAvLyBUaGlzIGlzIGEgbG93LWxldmVsIEFQSSB0aGF0IG1vc3QgdXNlcnMgc2hvdWxkIG5vdCB1c2UgZGlyZWN0bHkuXG4gICAgLy8gQSBtaWQtbGV2ZWwgQVBJIGlzIHRoZSBlbmNvZGVTZWdtZW50cygpIGZ1bmN0aW9uLlxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICAgIC8vIFRoZSB2ZXJzaW9uIG51bWJlciBvZiB0aGlzIFFSIENvZGUsIHdoaWNoIGlzIGJldHdlZW4gMSBhbmQgNDAgKGluY2x1c2l2ZSkuXG4gICAgICAvLyBUaGlzIGRldGVybWluZXMgdGhlIHNpemUgb2YgdGhpcyBiYXJjb2RlLlxuICAgICAgcHVibGljIHJlYWRvbmx5IHZlcnNpb246IGludCxcblxuICAgICAgLy8gVGhlIGVycm9yIGNvcnJlY3Rpb24gbGV2ZWwgdXNlZCBpbiB0aGlzIFFSIENvZGUuXG4gICAgICBwdWJsaWMgcmVhZG9ubHkgZXJyb3JDb3JyZWN0aW9uTGV2ZWw6IFFyQ29kZS5FY2MsXG5cbiAgICAgIGRhdGFDb2Rld29yZHM6IFJlYWRvbmx5PEFycmF5PGJ5dGU+PixcblxuICAgICAgbXNrOiBpbnRcbiAgICApIHtcbiAgICAgIC8vIENoZWNrIHNjYWxhciBhcmd1bWVudHNcbiAgICAgIGlmICh2ZXJzaW9uIDwgUXJDb2RlLk1JTl9WRVJTSU9OIHx8IHZlcnNpb24gPiBRckNvZGUuTUFYX1ZFUlNJT04pXG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdWZXJzaW9uIHZhbHVlIG91dCBvZiByYW5nZScpO1xuICAgICAgaWYgKG1zayA8IC0xIHx8IG1zayA+IDcpIHRocm93IG5ldyBSYW5nZUVycm9yKCdNYXNrIHZhbHVlIG91dCBvZiByYW5nZScpO1xuICAgICAgdGhpcy5zaXplID0gdmVyc2lvbiAqIDQgKyAxNztcblxuICAgICAgLy8gSW5pdGlhbGl6ZSBib3RoIGdyaWRzIHRvIGJlIHNpemUqc2l6ZSBhcnJheXMgb2YgQm9vbGVhbiBmYWxzZVxuICAgICAgbGV0IHJvdzogQXJyYXk8Ym9vbGVhbj4gPSBbXTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zaXplOyBpKyspIHJvdy5wdXNoKGZhbHNlKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zaXplOyBpKyspIHtcbiAgICAgICAgdGhpcy5tb2R1bGVzLnB1c2gocm93LnNsaWNlKCkpOyAvLyBJbml0aWFsbHkgYWxsIGxpZ2h0XG4gICAgICAgIHRoaXMuaXNGdW5jdGlvbi5wdXNoKHJvdy5zbGljZSgpKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ29tcHV0ZSBFQ0MsIGRyYXcgbW9kdWxlc1xuICAgICAgdGhpcy5kcmF3RnVuY3Rpb25QYXR0ZXJucygpO1xuICAgICAgY29uc3QgYWxsQ29kZXdvcmRzOiBBcnJheTxieXRlPiA9IHRoaXMuYWRkRWNjQW5kSW50ZXJsZWF2ZShkYXRhQ29kZXdvcmRzKTtcbiAgICAgIHRoaXMuZHJhd0NvZGV3b3JkcyhhbGxDb2Rld29yZHMpO1xuXG4gICAgICAvLyBEbyBtYXNraW5nXG4gICAgICBpZiAobXNrID09IC0xKSB7XG4gICAgICAgIC8vIEF1dG9tYXRpY2FsbHkgY2hvb3NlIGJlc3QgbWFza1xuICAgICAgICBsZXQgbWluUGVuYWx0eTogaW50ID0gMTAwMDAwMDAwMDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA4OyBpKyspIHtcbiAgICAgICAgICB0aGlzLmFwcGx5TWFzayhpKTtcbiAgICAgICAgICB0aGlzLmRyYXdGb3JtYXRCaXRzKGkpO1xuICAgICAgICAgIGNvbnN0IHBlbmFsdHk6IGludCA9IHRoaXMuZ2V0UGVuYWx0eVNjb3JlKCk7XG4gICAgICAgICAgaWYgKHBlbmFsdHkgPCBtaW5QZW5hbHR5KSB7XG4gICAgICAgICAgICBtc2sgPSBpO1xuICAgICAgICAgICAgbWluUGVuYWx0eSA9IHBlbmFsdHk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuYXBwbHlNYXNrKGkpOyAvLyBVbmRvZXMgdGhlIG1hc2sgZHVlIHRvIFhPUlxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBhc3NlcnQobXNrID49IDAgJiYgbXNrIDw9IDcpO1xuICAgICAgdGhpcy5tYXNrID0gbXNrO1xuICAgICAgdGhpcy5hcHBseU1hc2sobXNrKTsgLy8gQXBwbHkgdGhlIGZpbmFsIGNob2ljZSBvZiBtYXNrXG4gICAgICB0aGlzLmRyYXdGb3JtYXRCaXRzKG1zayk7IC8vIE92ZXJ3cml0ZSBvbGQgZm9ybWF0IGJpdHNcblxuICAgICAgdGhpcy5pc0Z1bmN0aW9uID0gW107XG4gICAgfVxuXG4gICAgLyotLSBBY2Nlc3NvciBtZXRob2RzIC0tKi9cblxuICAgIC8vIFJldHVybnMgdGhlIGNvbG9yIG9mIHRoZSBtb2R1bGUgKHBpeGVsKSBhdCB0aGUgZ2l2ZW4gY29vcmRpbmF0ZXMsIHdoaWNoIGlzIGZhbHNlXG4gICAgLy8gZm9yIGxpZ2h0IG9yIHRydWUgZm9yIGRhcmsuIFRoZSB0b3AgbGVmdCBjb3JuZXIgaGFzIHRoZSBjb29yZGluYXRlcyAoeD0wLCB5PTApLlxuICAgIC8vIElmIHRoZSBnaXZlbiBjb29yZGluYXRlcyBhcmUgb3V0IG9mIGJvdW5kcywgdGhlbiBmYWxzZSAobGlnaHQpIGlzIHJldHVybmVkLlxuICAgIHB1YmxpYyBnZXRNb2R1bGUoeDogaW50LCB5OiBpbnQpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiB4ID49IDAgJiYgeCA8IHRoaXMuc2l6ZSAmJiB5ID49IDAgJiYgeSA8IHRoaXMuc2l6ZSAmJiB0aGlzLm1vZHVsZXNbeV1beF07XG4gICAgfVxuXG4gICAgLyotLSBQcml2YXRlIGhlbHBlciBtZXRob2RzIGZvciBjb25zdHJ1Y3RvcjogRHJhd2luZyBmdW5jdGlvbiBtb2R1bGVzIC0tKi9cblxuICAgIC8vIFJlYWRzIHRoaXMgb2JqZWN0J3MgdmVyc2lvbiBmaWVsZCwgYW5kIGRyYXdzIGFuZCBtYXJrcyBhbGwgZnVuY3Rpb24gbW9kdWxlcy5cbiAgICBwcml2YXRlIGRyYXdGdW5jdGlvblBhdHRlcm5zKCk6IHZvaWQge1xuICAgICAgLy8gRHJhdyBob3Jpem9udGFsIGFuZCB2ZXJ0aWNhbCB0aW1pbmcgcGF0dGVybnNcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zaXplOyBpKyspIHtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk1vZHVsZSg2LCBpLCBpICUgMiA9PSAwKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk1vZHVsZShpLCA2LCBpICUgMiA9PSAwKTtcbiAgICAgIH1cblxuICAgICAgLy8gRHJhdyAzIGZpbmRlciBwYXR0ZXJucyAoYWxsIGNvcm5lcnMgZXhjZXB0IGJvdHRvbSByaWdodDsgb3ZlcndyaXRlcyBzb21lIHRpbWluZyBtb2R1bGVzKVxuICAgICAgdGhpcy5kcmF3RmluZGVyUGF0dGVybigzLCAzKTtcbiAgICAgIHRoaXMuZHJhd0ZpbmRlclBhdHRlcm4odGhpcy5zaXplIC0gNCwgMyk7XG4gICAgICB0aGlzLmRyYXdGaW5kZXJQYXR0ZXJuKDMsIHRoaXMuc2l6ZSAtIDQpO1xuXG4gICAgICAvLyBEcmF3IG51bWVyb3VzIGFsaWdubWVudCBwYXR0ZXJuc1xuICAgICAgY29uc3QgYWxpZ25QYXRQb3M6IEFycmF5PGludD4gPSB0aGlzLmdldEFsaWdubWVudFBhdHRlcm5Qb3NpdGlvbnMoKTtcbiAgICAgIGNvbnN0IG51bUFsaWduOiBpbnQgPSBhbGlnblBhdFBvcy5sZW5ndGg7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bUFsaWduOyBpKyspIHtcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBudW1BbGlnbjsgaisrKSB7XG4gICAgICAgICAgLy8gRG9uJ3QgZHJhdyBvbiB0aGUgdGhyZWUgZmluZGVyIGNvcm5lcnNcbiAgICAgICAgICBpZiAoISgoaSA9PSAwICYmIGogPT0gMCkgfHwgKGkgPT0gMCAmJiBqID09IG51bUFsaWduIC0gMSkgfHwgKGkgPT0gbnVtQWxpZ24gLSAxICYmIGogPT0gMCkpKVxuICAgICAgICAgICAgdGhpcy5kcmF3QWxpZ25tZW50UGF0dGVybihhbGlnblBhdFBvc1tpXSwgYWxpZ25QYXRQb3Nbal0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIERyYXcgY29uZmlndXJhdGlvbiBkYXRhXG4gICAgICB0aGlzLmRyYXdGb3JtYXRCaXRzKDApOyAvLyBEdW1teSBtYXNrIHZhbHVlOyBvdmVyd3JpdHRlbiBsYXRlciBpbiB0aGUgY29uc3RydWN0b3JcbiAgICAgIHRoaXMuZHJhd1ZlcnNpb24oKTtcbiAgICB9XG5cbiAgICAvLyBEcmF3cyB0d28gY29waWVzIG9mIHRoZSBmb3JtYXQgYml0cyAod2l0aCBpdHMgb3duIGVycm9yIGNvcnJlY3Rpb24gY29kZSlcbiAgICAvLyBiYXNlZCBvbiB0aGUgZ2l2ZW4gbWFzayBhbmQgdGhpcyBvYmplY3QncyBlcnJvciBjb3JyZWN0aW9uIGxldmVsIGZpZWxkLlxuICAgIHByaXZhdGUgZHJhd0Zvcm1hdEJpdHMobWFzazogaW50KTogdm9pZCB7XG4gICAgICAvLyBDYWxjdWxhdGUgZXJyb3IgY29ycmVjdGlvbiBjb2RlIGFuZCBwYWNrIGJpdHNcbiAgICAgIGNvbnN0IGRhdGE6IGludCA9ICh0aGlzLmVycm9yQ29ycmVjdGlvbkxldmVsLmZvcm1hdEJpdHMgPDwgMykgfCBtYXNrOyAvLyBlcnJDb3JyTHZsIGlzIHVpbnQyLCBtYXNrIGlzIHVpbnQzXG4gICAgICBsZXQgcmVtOiBpbnQgPSBkYXRhO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAxMDsgaSsrKSByZW0gPSAocmVtIDw8IDEpIF4gKChyZW0gPj4+IDkpICogMHg1MzcpO1xuICAgICAgY29uc3QgYml0cyA9ICgoZGF0YSA8PCAxMCkgfCByZW0pIF4gMHg1NDEyOyAvLyB1aW50MTVcbiAgICAgIGFzc2VydChiaXRzID4+PiAxNSA9PSAwKTtcblxuICAgICAgLy8gRHJhdyBmaXJzdCBjb3B5XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8PSA1OyBpKyspIHRoaXMuc2V0RnVuY3Rpb25Nb2R1bGUoOCwgaSwgZ2V0Qml0KGJpdHMsIGkpKTtcbiAgICAgIHRoaXMuc2V0RnVuY3Rpb25Nb2R1bGUoOCwgNywgZ2V0Qml0KGJpdHMsIDYpKTtcbiAgICAgIHRoaXMuc2V0RnVuY3Rpb25Nb2R1bGUoOCwgOCwgZ2V0Qml0KGJpdHMsIDcpKTtcbiAgICAgIHRoaXMuc2V0RnVuY3Rpb25Nb2R1bGUoNywgOCwgZ2V0Qml0KGJpdHMsIDgpKTtcbiAgICAgIGZvciAobGV0IGkgPSA5OyBpIDwgMTU7IGkrKykgdGhpcy5zZXRGdW5jdGlvbk1vZHVsZSgxNCAtIGksIDgsIGdldEJpdChiaXRzLCBpKSk7XG5cbiAgICAgIC8vIERyYXcgc2Vjb25kIGNvcHlcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgODsgaSsrKSB0aGlzLnNldEZ1bmN0aW9uTW9kdWxlKHRoaXMuc2l6ZSAtIDEgLSBpLCA4LCBnZXRCaXQoYml0cywgaSkpO1xuICAgICAgZm9yIChsZXQgaSA9IDg7IGkgPCAxNTsgaSsrKSB0aGlzLnNldEZ1bmN0aW9uTW9kdWxlKDgsIHRoaXMuc2l6ZSAtIDE1ICsgaSwgZ2V0Qml0KGJpdHMsIGkpKTtcbiAgICAgIHRoaXMuc2V0RnVuY3Rpb25Nb2R1bGUoOCwgdGhpcy5zaXplIC0gOCwgdHJ1ZSk7IC8vIEFsd2F5cyBkYXJrXG4gICAgfVxuXG4gICAgLy8gRHJhd3MgdHdvIGNvcGllcyBvZiB0aGUgdmVyc2lvbiBiaXRzICh3aXRoIGl0cyBvd24gZXJyb3IgY29ycmVjdGlvbiBjb2RlKSxcbiAgICAvLyBiYXNlZCBvbiB0aGlzIG9iamVjdCdzIHZlcnNpb24gZmllbGQsIGlmZiA3IDw9IHZlcnNpb24gPD0gNDAuXG4gICAgcHJpdmF0ZSBkcmF3VmVyc2lvbigpOiB2b2lkIHtcbiAgICAgIGlmICh0aGlzLnZlcnNpb24gPCA3KSByZXR1cm47XG5cbiAgICAgIC8vIENhbGN1bGF0ZSBlcnJvciBjb3JyZWN0aW9uIGNvZGUgYW5kIHBhY2sgYml0c1xuICAgICAgbGV0IHJlbTogaW50ID0gdGhpcy52ZXJzaW9uOyAvLyB2ZXJzaW9uIGlzIHVpbnQ2LCBpbiB0aGUgcmFuZ2UgWzcsIDQwXVxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAxMjsgaSsrKSByZW0gPSAocmVtIDw8IDEpIF4gKChyZW0gPj4+IDExKSAqIDB4MWYyNSk7XG4gICAgICBjb25zdCBiaXRzOiBpbnQgPSAodGhpcy52ZXJzaW9uIDw8IDEyKSB8IHJlbTsgLy8gdWludDE4XG4gICAgICBhc3NlcnQoYml0cyA+Pj4gMTggPT0gMCk7XG5cbiAgICAgIC8vIERyYXcgdHdvIGNvcGllc1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAxODsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGNvbG9yOiBib29sZWFuID0gZ2V0Qml0KGJpdHMsIGkpO1xuICAgICAgICBjb25zdCBhOiBpbnQgPSB0aGlzLnNpemUgLSAxMSArIChpICUgMyk7XG4gICAgICAgIGNvbnN0IGI6IGludCA9IE1hdGguZmxvb3IoaSAvIDMpO1xuICAgICAgICB0aGlzLnNldEZ1bmN0aW9uTW9kdWxlKGEsIGIsIGNvbG9yKTtcbiAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk1vZHVsZShiLCBhLCBjb2xvcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRHJhd3MgYSA5KjkgZmluZGVyIHBhdHRlcm4gaW5jbHVkaW5nIHRoZSBib3JkZXIgc2VwYXJhdG9yLFxuICAgIC8vIHdpdGggdGhlIGNlbnRlciBtb2R1bGUgYXQgKHgsIHkpLiBNb2R1bGVzIGNhbiBiZSBvdXQgb2YgYm91bmRzLlxuICAgIHByaXZhdGUgZHJhd0ZpbmRlclBhdHRlcm4oeDogaW50LCB5OiBpbnQpOiB2b2lkIHtcbiAgICAgIGZvciAobGV0IGR5ID0gLTQ7IGR5IDw9IDQ7IGR5KyspIHtcbiAgICAgICAgZm9yIChsZXQgZHggPSAtNDsgZHggPD0gNDsgZHgrKykge1xuICAgICAgICAgIGNvbnN0IGRpc3Q6IGludCA9IE1hdGgubWF4KE1hdGguYWJzKGR4KSwgTWF0aC5hYnMoZHkpKTsgLy8gQ2hlYnlzaGV2L2luZmluaXR5IG5vcm1cbiAgICAgICAgICBjb25zdCB4eDogaW50ID0geCArIGR4O1xuICAgICAgICAgIGNvbnN0IHl5OiBpbnQgPSB5ICsgZHk7XG4gICAgICAgICAgaWYgKHh4ID49IDAgJiYgeHggPCB0aGlzLnNpemUgJiYgeXkgPj0gMCAmJiB5eSA8IHRoaXMuc2l6ZSlcbiAgICAgICAgICAgIHRoaXMuc2V0RnVuY3Rpb25Nb2R1bGUoeHgsIHl5LCBkaXN0ICE9IDIgJiYgZGlzdCAhPSA0KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIERyYXdzIGEgNSo1IGFsaWdubWVudCBwYXR0ZXJuLCB3aXRoIHRoZSBjZW50ZXIgbW9kdWxlXG4gICAgLy8gYXQgKHgsIHkpLiBBbGwgbW9kdWxlcyBtdXN0IGJlIGluIGJvdW5kcy5cbiAgICBwcml2YXRlIGRyYXdBbGlnbm1lbnRQYXR0ZXJuKHg6IGludCwgeTogaW50KTogdm9pZCB7XG4gICAgICBmb3IgKGxldCBkeSA9IC0yOyBkeSA8PSAyOyBkeSsrKSB7XG4gICAgICAgIGZvciAobGV0IGR4ID0gLTI7IGR4IDw9IDI7IGR4KyspXG4gICAgICAgICAgdGhpcy5zZXRGdW5jdGlvbk1vZHVsZSh4ICsgZHgsIHkgKyBkeSwgTWF0aC5tYXgoTWF0aC5hYnMoZHgpLCBNYXRoLmFicyhkeSkpICE9IDEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFNldHMgdGhlIGNvbG9yIG9mIGEgbW9kdWxlIGFuZCBtYXJrcyBpdCBhcyBhIGZ1bmN0aW9uIG1vZHVsZS5cbiAgICAvLyBPbmx5IHVzZWQgYnkgdGhlIGNvbnN0cnVjdG9yLiBDb29yZGluYXRlcyBtdXN0IGJlIGluIGJvdW5kcy5cbiAgICBwcml2YXRlIHNldEZ1bmN0aW9uTW9kdWxlKHg6IGludCwgeTogaW50LCBpc0Rhcms6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgIHRoaXMubW9kdWxlc1t5XVt4XSA9IGlzRGFyaztcbiAgICAgIHRoaXMuaXNGdW5jdGlvblt5XVt4XSA9IHRydWU7XG4gICAgfVxuXG4gICAgLyotLSBQcml2YXRlIGhlbHBlciBtZXRob2RzIGZvciBjb25zdHJ1Y3RvcjogQ29kZXdvcmRzIGFuZCBtYXNraW5nIC0tKi9cblxuICAgIC8vIFJldHVybnMgYSBuZXcgYnl0ZSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiBkYXRhIHdpdGggdGhlIGFwcHJvcHJpYXRlIGVycm9yIGNvcnJlY3Rpb25cbiAgICAvLyBjb2Rld29yZHMgYXBwZW5kZWQgdG8gaXQsIGJhc2VkIG9uIHRoaXMgb2JqZWN0J3MgdmVyc2lvbiBhbmQgZXJyb3IgY29ycmVjdGlvbiBsZXZlbC5cbiAgICBwcml2YXRlIGFkZEVjY0FuZEludGVybGVhdmUoZGF0YTogUmVhZG9ubHk8QXJyYXk8Ynl0ZT4+KTogQXJyYXk8Ynl0ZT4ge1xuICAgICAgY29uc3QgdmVyOiBpbnQgPSB0aGlzLnZlcnNpb247XG4gICAgICBjb25zdCBlY2w6IFFyQ29kZS5FY2MgPSB0aGlzLmVycm9yQ29ycmVjdGlvbkxldmVsO1xuICAgICAgaWYgKGRhdGEubGVuZ3RoICE9IFFyQ29kZS5nZXROdW1EYXRhQ29kZXdvcmRzKHZlciwgZWNsKSkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgYXJndW1lbnQnKTtcblxuICAgICAgLy8gQ2FsY3VsYXRlIHBhcmFtZXRlciBudW1iZXJzXG4gICAgICBjb25zdCBudW1CbG9ja3M6IGludCA9IFFyQ29kZS5OVU1fRVJST1JfQ09SUkVDVElPTl9CTE9DS1NbZWNsLm9yZGluYWxdW3Zlcl07XG4gICAgICBjb25zdCBibG9ja0VjY0xlbjogaW50ID0gUXJDb2RlLkVDQ19DT0RFV09SRFNfUEVSX0JMT0NLW2VjbC5vcmRpbmFsXVt2ZXJdO1xuICAgICAgY29uc3QgcmF3Q29kZXdvcmRzOiBpbnQgPSBNYXRoLmZsb29yKFFyQ29kZS5nZXROdW1SYXdEYXRhTW9kdWxlcyh2ZXIpIC8gOCk7XG4gICAgICBjb25zdCBudW1TaG9ydEJsb2NrczogaW50ID0gbnVtQmxvY2tzIC0gKHJhd0NvZGV3b3JkcyAlIG51bUJsb2Nrcyk7XG4gICAgICBjb25zdCBzaG9ydEJsb2NrTGVuOiBpbnQgPSBNYXRoLmZsb29yKHJhd0NvZGV3b3JkcyAvIG51bUJsb2Nrcyk7XG5cbiAgICAgIC8vIFNwbGl0IGRhdGEgaW50byBibG9ja3MgYW5kIGFwcGVuZCBFQ0MgdG8gZWFjaCBibG9ja1xuICAgICAgbGV0IGJsb2NrczogQXJyYXk8QXJyYXk8Ynl0ZT4+ID0gW107XG4gICAgICBjb25zdCByc0RpdjogQXJyYXk8Ynl0ZT4gPSBRckNvZGUucmVlZFNvbG9tb25Db21wdXRlRGl2aXNvcihibG9ja0VjY0xlbik7XG4gICAgICBmb3IgKGxldCBpID0gMCwgayA9IDA7IGkgPCBudW1CbG9ja3M7IGkrKykge1xuICAgICAgICBsZXQgZGF0OiBBcnJheTxieXRlPiA9IGRhdGEuc2xpY2UoaywgayArIHNob3J0QmxvY2tMZW4gLSBibG9ja0VjY0xlbiArIChpIDwgbnVtU2hvcnRCbG9ja3MgPyAwIDogMSkpO1xuICAgICAgICBrICs9IGRhdC5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGVjYzogQXJyYXk8Ynl0ZT4gPSBRckNvZGUucmVlZFNvbG9tb25Db21wdXRlUmVtYWluZGVyKGRhdCwgcnNEaXYpO1xuICAgICAgICBpZiAoaSA8IG51bVNob3J0QmxvY2tzKSBkYXQucHVzaCgwKTtcbiAgICAgICAgYmxvY2tzLnB1c2goZGF0LmNvbmNhdChlY2MpKTtcbiAgICAgIH1cblxuICAgICAgLy8gSW50ZXJsZWF2ZSAobm90IGNvbmNhdGVuYXRlKSB0aGUgYnl0ZXMgZnJvbSBldmVyeSBibG9jayBpbnRvIGEgc2luZ2xlIHNlcXVlbmNlXG4gICAgICBsZXQgcmVzdWx0OiBBcnJheTxieXRlPiA9IFtdO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBibG9ja3NbMF0ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYmxvY2tzLmZvckVhY2goKGJsb2NrLCBqKSA9PiB7XG4gICAgICAgICAgLy8gU2tpcCB0aGUgcGFkZGluZyBieXRlIGluIHNob3J0IGJsb2Nrc1xuICAgICAgICAgIGlmIChpICE9IHNob3J0QmxvY2tMZW4gLSBibG9ja0VjY0xlbiB8fCBqID49IG51bVNob3J0QmxvY2tzKSByZXN1bHQucHVzaChibG9ja1tpXSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgYXNzZXJ0KHJlc3VsdC5sZW5ndGggPT0gcmF3Q29kZXdvcmRzKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLy8gRHJhd3MgdGhlIGdpdmVuIHNlcXVlbmNlIG9mIDgtYml0IGNvZGV3b3JkcyAoZGF0YSBhbmQgZXJyb3IgY29ycmVjdGlvbikgb250byB0aGUgZW50aXJlXG4gICAgLy8gZGF0YSBhcmVhIG9mIHRoaXMgUVIgQ29kZS4gRnVuY3Rpb24gbW9kdWxlcyBuZWVkIHRvIGJlIG1hcmtlZCBvZmYgYmVmb3JlIHRoaXMgaXMgY2FsbGVkLlxuICAgIHByaXZhdGUgZHJhd0NvZGV3b3JkcyhkYXRhOiBSZWFkb25seTxBcnJheTxieXRlPj4pOiB2b2lkIHtcbiAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBNYXRoLmZsb29yKFFyQ29kZS5nZXROdW1SYXdEYXRhTW9kdWxlcyh0aGlzLnZlcnNpb24pIC8gOCkpXG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbnZhbGlkIGFyZ3VtZW50Jyk7XG4gICAgICBsZXQgaTogaW50ID0gMDsgLy8gQml0IGluZGV4IGludG8gdGhlIGRhdGFcbiAgICAgIC8vIERvIHRoZSBmdW5ueSB6aWd6YWcgc2NhblxuICAgICAgZm9yIChsZXQgcmlnaHQgPSB0aGlzLnNpemUgLSAxOyByaWdodCA+PSAxOyByaWdodCAtPSAyKSB7XG4gICAgICAgIC8vIEluZGV4IG9mIHJpZ2h0IGNvbHVtbiBpbiBlYWNoIGNvbHVtbiBwYWlyXG4gICAgICAgIGlmIChyaWdodCA9PSA2KSByaWdodCA9IDU7XG4gICAgICAgIGZvciAobGV0IHZlcnQgPSAwOyB2ZXJ0IDwgdGhpcy5zaXplOyB2ZXJ0KyspIHtcbiAgICAgICAgICAvLyBWZXJ0aWNhbCBjb3VudGVyXG4gICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCAyOyBqKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHg6IGludCA9IHJpZ2h0IC0gajsgLy8gQWN0dWFsIHggY29vcmRpbmF0ZVxuICAgICAgICAgICAgY29uc3QgdXB3YXJkOiBib29sZWFuID0gKChyaWdodCArIDEpICYgMikgPT0gMDtcbiAgICAgICAgICAgIGNvbnN0IHk6IGludCA9IHVwd2FyZCA/IHRoaXMuc2l6ZSAtIDEgLSB2ZXJ0IDogdmVydDsgLy8gQWN0dWFsIHkgY29vcmRpbmF0ZVxuICAgICAgICAgICAgaWYgKCF0aGlzLmlzRnVuY3Rpb25beV1beF0gJiYgaSA8IGRhdGEubGVuZ3RoICogOCkge1xuICAgICAgICAgICAgICB0aGlzLm1vZHVsZXNbeV1beF0gPSBnZXRCaXQoZGF0YVtpID4+PiAzXSwgNyAtIChpICYgNykpO1xuICAgICAgICAgICAgICBpKys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBJZiB0aGlzIFFSIENvZGUgaGFzIGFueSByZW1haW5kZXIgYml0cyAoMCB0byA3KSwgdGhleSB3ZXJlIGFzc2lnbmVkIGFzXG4gICAgICAgICAgICAvLyAwL2ZhbHNlL2xpZ2h0IGJ5IHRoZSBjb25zdHJ1Y3RvciBhbmQgYXJlIGxlZnQgdW5jaGFuZ2VkIGJ5IHRoaXMgbWV0aG9kXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBhc3NlcnQoaSA9PSBkYXRhLmxlbmd0aCAqIDgpO1xuICAgIH1cblxuICAgIC8vIFhPUnMgdGhlIGNvZGV3b3JkIG1vZHVsZXMgaW4gdGhpcyBRUiBDb2RlIHdpdGggdGhlIGdpdmVuIG1hc2sgcGF0dGVybi5cbiAgICAvLyBUaGUgZnVuY3Rpb24gbW9kdWxlcyBtdXN0IGJlIG1hcmtlZCBhbmQgdGhlIGNvZGV3b3JkIGJpdHMgbXVzdCBiZSBkcmF3blxuICAgIC8vIGJlZm9yZSBtYXNraW5nLiBEdWUgdG8gdGhlIGFyaXRobWV0aWMgb2YgWE9SLCBjYWxsaW5nIGFwcGx5TWFzaygpIHdpdGhcbiAgICAvLyB0aGUgc2FtZSBtYXNrIHZhbHVlIGEgc2Vjb25kIHRpbWUgd2lsbCB1bmRvIHRoZSBtYXNrLiBBIGZpbmFsIHdlbGwtZm9ybWVkXG4gICAgLy8gUVIgQ29kZSBuZWVkcyBleGFjdGx5IG9uZSAobm90IHplcm8sIHR3bywgZXRjLikgbWFzayBhcHBsaWVkLlxuICAgIHByaXZhdGUgYXBwbHlNYXNrKG1hc2s6IGludCk6IHZvaWQge1xuICAgICAgaWYgKG1hc2sgPCAwIHx8IG1hc2sgPiA3KSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignTWFzayB2YWx1ZSBvdXQgb2YgcmFuZ2UnKTtcbiAgICAgIGZvciAobGV0IHkgPSAwOyB5IDwgdGhpcy5zaXplOyB5KyspIHtcbiAgICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCB0aGlzLnNpemU7IHgrKykge1xuICAgICAgICAgIGxldCBpbnZlcnQ6IGJvb2xlYW47XG4gICAgICAgICAgc3dpdGNoIChtYXNrKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgIGludmVydCA9ICh4ICsgeSkgJSAyID09IDA7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICBpbnZlcnQgPSB5ICUgMiA9PSAwO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgaW52ZXJ0ID0geCAlIDMgPT0gMDtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgIGludmVydCA9ICh4ICsgeSkgJSAzID09IDA7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICBpbnZlcnQgPSAoTWF0aC5mbG9vcih4IC8gMykgKyBNYXRoLmZsb29yKHkgLyAyKSkgJSAyID09IDA7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICBpbnZlcnQgPSAoKHggKiB5KSAlIDIpICsgKCh4ICogeSkgJSAzKSA9PSAwO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgICAgaW52ZXJ0ID0gKCgoeCAqIHkpICUgMikgKyAoKHggKiB5KSAlIDMpKSAlIDIgPT0gMDtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICAgIGludmVydCA9ICgoKHggKyB5KSAlIDIpICsgKCh4ICogeSkgJSAzKSkgJSAyID09IDA7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnJlYWNoYWJsZScpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIXRoaXMuaXNGdW5jdGlvblt5XVt4XSAmJiBpbnZlcnQpIHRoaXMubW9kdWxlc1t5XVt4XSA9ICF0aGlzLm1vZHVsZXNbeV1beF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDYWxjdWxhdGVzIGFuZCByZXR1cm5zIHRoZSBwZW5hbHR5IHNjb3JlIGJhc2VkIG9uIHN0YXRlIG9mIHRoaXMgUVIgQ29kZSdzIGN1cnJlbnQgbW9kdWxlcy5cbiAgICAvLyBUaGlzIGlzIHVzZWQgYnkgdGhlIGF1dG9tYXRpYyBtYXNrIGNob2ljZSBhbGdvcml0aG0gdG8gZmluZCB0aGUgbWFzayBwYXR0ZXJuIHRoYXQgeWllbGRzIHRoZSBsb3dlc3Qgc2NvcmUuXG4gICAgcHJpdmF0ZSBnZXRQZW5hbHR5U2NvcmUoKTogaW50IHtcbiAgICAgIGxldCByZXN1bHQ6IGludCA9IDA7XG5cbiAgICAgIC8vIEFkamFjZW50IG1vZHVsZXMgaW4gcm93IGhhdmluZyBzYW1lIGNvbG9yLCBhbmQgZmluZGVyLWxpa2UgcGF0dGVybnNcbiAgICAgIGZvciAobGV0IHkgPSAwOyB5IDwgdGhpcy5zaXplOyB5KyspIHtcbiAgICAgICAgbGV0IHJ1bkNvbG9yID0gZmFsc2U7XG4gICAgICAgIGxldCBydW5YID0gMDtcbiAgICAgICAgbGV0IHJ1bkhpc3RvcnkgPSBbMCwgMCwgMCwgMCwgMCwgMCwgMF07XG4gICAgICAgIGZvciAobGV0IHggPSAwOyB4IDwgdGhpcy5zaXplOyB4KyspIHtcbiAgICAgICAgICBpZiAodGhpcy5tb2R1bGVzW3ldW3hdID09IHJ1bkNvbG9yKSB7XG4gICAgICAgICAgICBydW5YKys7XG4gICAgICAgICAgICBpZiAocnVuWCA9PSA1KSByZXN1bHQgKz0gUXJDb2RlLlBFTkFMVFlfTjE7XG4gICAgICAgICAgICBlbHNlIGlmIChydW5YID4gNSkgcmVzdWx0Kys7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZmluZGVyUGVuYWx0eUFkZEhpc3RvcnkocnVuWCwgcnVuSGlzdG9yeSk7XG4gICAgICAgICAgICBpZiAoIXJ1bkNvbG9yKSByZXN1bHQgKz0gdGhpcy5maW5kZXJQZW5hbHR5Q291bnRQYXR0ZXJucyhydW5IaXN0b3J5KSAqIFFyQ29kZS5QRU5BTFRZX04zO1xuICAgICAgICAgICAgcnVuQ29sb3IgPSB0aGlzLm1vZHVsZXNbeV1beF07XG4gICAgICAgICAgICBydW5YID0gMTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0ICs9IHRoaXMuZmluZGVyUGVuYWx0eVRlcm1pbmF0ZUFuZENvdW50KHJ1bkNvbG9yLCBydW5YLCBydW5IaXN0b3J5KSAqIFFyQ29kZS5QRU5BTFRZX04zO1xuICAgICAgfVxuICAgICAgLy8gQWRqYWNlbnQgbW9kdWxlcyBpbiBjb2x1bW4gaGF2aW5nIHNhbWUgY29sb3IsIGFuZCBmaW5kZXItbGlrZSBwYXR0ZXJuc1xuICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCB0aGlzLnNpemU7IHgrKykge1xuICAgICAgICBsZXQgcnVuQ29sb3IgPSBmYWxzZTtcbiAgICAgICAgbGV0IHJ1blkgPSAwO1xuICAgICAgICBsZXQgcnVuSGlzdG9yeSA9IFswLCAwLCAwLCAwLCAwLCAwLCAwXTtcbiAgICAgICAgZm9yIChsZXQgeSA9IDA7IHkgPCB0aGlzLnNpemU7IHkrKykge1xuICAgICAgICAgIGlmICh0aGlzLm1vZHVsZXNbeV1beF0gPT0gcnVuQ29sb3IpIHtcbiAgICAgICAgICAgIHJ1blkrKztcbiAgICAgICAgICAgIGlmIChydW5ZID09IDUpIHJlc3VsdCArPSBRckNvZGUuUEVOQUxUWV9OMTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHJ1blkgPiA1KSByZXN1bHQrKztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5maW5kZXJQZW5hbHR5QWRkSGlzdG9yeShydW5ZLCBydW5IaXN0b3J5KTtcbiAgICAgICAgICAgIGlmICghcnVuQ29sb3IpIHJlc3VsdCArPSB0aGlzLmZpbmRlclBlbmFsdHlDb3VudFBhdHRlcm5zKHJ1bkhpc3RvcnkpICogUXJDb2RlLlBFTkFMVFlfTjM7XG4gICAgICAgICAgICBydW5Db2xvciA9IHRoaXMubW9kdWxlc1t5XVt4XTtcbiAgICAgICAgICAgIHJ1blkgPSAxO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXN1bHQgKz0gdGhpcy5maW5kZXJQZW5hbHR5VGVybWluYXRlQW5kQ291bnQocnVuQ29sb3IsIHJ1blksIHJ1bkhpc3RvcnkpICogUXJDb2RlLlBFTkFMVFlfTjM7XG4gICAgICB9XG5cbiAgICAgIC8vIDIqMiBibG9ja3Mgb2YgbW9kdWxlcyBoYXZpbmcgc2FtZSBjb2xvclxuICAgICAgZm9yIChsZXQgeSA9IDA7IHkgPCB0aGlzLnNpemUgLSAxOyB5KyspIHtcbiAgICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCB0aGlzLnNpemUgLSAxOyB4KyspIHtcbiAgICAgICAgICBjb25zdCBjb2xvcjogYm9vbGVhbiA9IHRoaXMubW9kdWxlc1t5XVt4XTtcbiAgICAgICAgICBpZiAoY29sb3IgPT0gdGhpcy5tb2R1bGVzW3ldW3ggKyAxXSAmJiBjb2xvciA9PSB0aGlzLm1vZHVsZXNbeSArIDFdW3hdICYmIGNvbG9yID09IHRoaXMubW9kdWxlc1t5ICsgMV1beCArIDFdKVxuICAgICAgICAgICAgcmVzdWx0ICs9IFFyQ29kZS5QRU5BTFRZX04yO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEJhbGFuY2Ugb2YgZGFyayBhbmQgbGlnaHQgbW9kdWxlc1xuICAgICAgbGV0IGRhcms6IGludCA9IDA7XG4gICAgICBmb3IgKGNvbnN0IHJvdyBvZiB0aGlzLm1vZHVsZXMpIGRhcmsgPSByb3cucmVkdWNlKChzdW0sIGNvbG9yKSA9PiBzdW0gKyAoY29sb3IgPyAxIDogMCksIGRhcmspO1xuICAgICAgY29uc3QgdG90YWw6IGludCA9IHRoaXMuc2l6ZSAqIHRoaXMuc2l6ZTsgLy8gTm90ZSB0aGF0IHNpemUgaXMgb2RkLCBzbyBkYXJrL3RvdGFsICE9IDEvMlxuICAgICAgLy8gQ29tcHV0ZSB0aGUgc21hbGxlc3QgaW50ZWdlciBrID49IDAgc3VjaCB0aGF0ICg0NS01ayklIDw9IGRhcmsvdG90YWwgPD0gKDU1KzVrKSVcbiAgICAgIGNvbnN0IGs6IGludCA9IE1hdGguY2VpbChNYXRoLmFicyhkYXJrICogMjAgLSB0b3RhbCAqIDEwKSAvIHRvdGFsKSAtIDE7XG4gICAgICBhc3NlcnQoayA+PSAwICYmIGsgPD0gOSk7XG4gICAgICByZXN1bHQgKz0gayAqIFFyQ29kZS5QRU5BTFRZX040O1xuICAgICAgYXNzZXJ0KHJlc3VsdCA+PSAwICYmIHJlc3VsdCA8PSAyNTY4ODg4KTsgLy8gTm9uLXRpZ2h0IHVwcGVyIGJvdW5kIGJhc2VkIG9uIGRlZmF1bHQgdmFsdWVzIG9mIFBFTkFMVFlfTjEsIC4uLiwgTjRcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyotLSBQcml2YXRlIGhlbHBlciBmdW5jdGlvbnMgLS0qL1xuXG4gICAgLy8gUmV0dXJucyBhbiBhc2NlbmRpbmcgbGlzdCBvZiBwb3NpdGlvbnMgb2YgYWxpZ25tZW50IHBhdHRlcm5zIGZvciB0aGlzIHZlcnNpb24gbnVtYmVyLlxuICAgIC8vIEVhY2ggcG9zaXRpb24gaXMgaW4gdGhlIHJhbmdlIFswLDE3NyksIGFuZCBhcmUgdXNlZCBvbiBib3RoIHRoZSB4IGFuZCB5IGF4ZXMuXG4gICAgLy8gVGhpcyBjb3VsZCBiZSBpbXBsZW1lbnRlZCBhcyBsb29rdXAgdGFibGUgb2YgNDAgdmFyaWFibGUtbGVuZ3RoIGxpc3RzIG9mIGludGVnZXJzLlxuICAgIHByaXZhdGUgZ2V0QWxpZ25tZW50UGF0dGVyblBvc2l0aW9ucygpOiBBcnJheTxpbnQ+IHtcbiAgICAgIGlmICh0aGlzLnZlcnNpb24gPT0gMSkgcmV0dXJuIFtdO1xuICAgICAgZWxzZSB7XG4gICAgICAgIGNvbnN0IG51bUFsaWduOiBpbnQgPSBNYXRoLmZsb29yKHRoaXMudmVyc2lvbiAvIDcpICsgMjtcbiAgICAgICAgY29uc3Qgc3RlcDogaW50ID0gdGhpcy52ZXJzaW9uID09IDMyID8gMjYgOiBNYXRoLmNlaWwoKHRoaXMudmVyc2lvbiAqIDQgKyA0KSAvIChudW1BbGlnbiAqIDIgLSAyKSkgKiAyO1xuICAgICAgICBsZXQgcmVzdWx0OiBBcnJheTxpbnQ+ID0gWzZdO1xuICAgICAgICBmb3IgKGxldCBwb3MgPSB0aGlzLnNpemUgLSA3OyByZXN1bHQubGVuZ3RoIDwgbnVtQWxpZ247IHBvcyAtPSBzdGVwKSByZXN1bHQuc3BsaWNlKDEsIDAsIHBvcyk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGRhdGEgYml0cyB0aGF0IGNhbiBiZSBzdG9yZWQgaW4gYSBRUiBDb2RlIG9mIHRoZSBnaXZlbiB2ZXJzaW9uIG51bWJlciwgYWZ0ZXJcbiAgICAvLyBhbGwgZnVuY3Rpb24gbW9kdWxlcyBhcmUgZXhjbHVkZWQuIFRoaXMgaW5jbHVkZXMgcmVtYWluZGVyIGJpdHMsIHNvIGl0IG1pZ2h0IG5vdCBiZSBhIG11bHRpcGxlIG9mIDguXG4gICAgLy8gVGhlIHJlc3VsdCBpcyBpbiB0aGUgcmFuZ2UgWzIwOCwgMjk2NDhdLiBUaGlzIGNvdWxkIGJlIGltcGxlbWVudGVkIGFzIGEgNDAtZW50cnkgbG9va3VwIHRhYmxlLlxuICAgIHByaXZhdGUgc3RhdGljIGdldE51bVJhd0RhdGFNb2R1bGVzKHZlcjogaW50KTogaW50IHtcbiAgICAgIGlmICh2ZXIgPCBRckNvZGUuTUlOX1ZFUlNJT04gfHwgdmVyID4gUXJDb2RlLk1BWF9WRVJTSU9OKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVmVyc2lvbiBudW1iZXIgb3V0IG9mIHJhbmdlJyk7XG4gICAgICBsZXQgcmVzdWx0OiBpbnQgPSAoMTYgKiB2ZXIgKyAxMjgpICogdmVyICsgNjQ7XG4gICAgICBpZiAodmVyID49IDIpIHtcbiAgICAgICAgY29uc3QgbnVtQWxpZ246IGludCA9IE1hdGguZmxvb3IodmVyIC8gNykgKyAyO1xuICAgICAgICByZXN1bHQgLT0gKDI1ICogbnVtQWxpZ24gLSAxMCkgKiBudW1BbGlnbiAtIDU1O1xuICAgICAgICBpZiAodmVyID49IDcpIHJlc3VsdCAtPSAzNjtcbiAgICAgIH1cbiAgICAgIGFzc2VydChyZXN1bHQgPj0gMjA4ICYmIHJlc3VsdCA8PSAyOTY0OCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8vIFJldHVybnMgdGhlIG51bWJlciBvZiA4LWJpdCBkYXRhIChpLmUuIG5vdCBlcnJvciBjb3JyZWN0aW9uKSBjb2Rld29yZHMgY29udGFpbmVkIGluIGFueVxuICAgIC8vIFFSIENvZGUgb2YgdGhlIGdpdmVuIHZlcnNpb24gbnVtYmVyIGFuZCBlcnJvciBjb3JyZWN0aW9uIGxldmVsLCB3aXRoIHJlbWFpbmRlciBiaXRzIGRpc2NhcmRlZC5cbiAgICAvLyBUaGlzIHN0YXRlbGVzcyBwdXJlIGZ1bmN0aW9uIGNvdWxkIGJlIGltcGxlbWVudGVkIGFzIGEgKDQwKjQpLWNlbGwgbG9va3VwIHRhYmxlLlxuICAgIHByaXZhdGUgc3RhdGljIGdldE51bURhdGFDb2Rld29yZHModmVyOiBpbnQsIGVjbDogUXJDb2RlLkVjYyk6IGludCB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICBNYXRoLmZsb29yKFFyQ29kZS5nZXROdW1SYXdEYXRhTW9kdWxlcyh2ZXIpIC8gOCkgLVxuICAgICAgICBRckNvZGUuRUNDX0NPREVXT1JEU19QRVJfQkxPQ0tbZWNsLm9yZGluYWxdW3Zlcl0gKiBRckNvZGUuTlVNX0VSUk9SX0NPUlJFQ1RJT05fQkxPQ0tTW2VjbC5vcmRpbmFsXVt2ZXJdXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIFJldHVybnMgYSBSZWVkLVNvbG9tb24gRUNDIGdlbmVyYXRvciBwb2x5bm9taWFsIGZvciB0aGUgZ2l2ZW4gZGVncmVlLiBUaGlzIGNvdWxkIGJlXG4gICAgLy8gaW1wbGVtZW50ZWQgYXMgYSBsb29rdXAgdGFibGUgb3ZlciBhbGwgcG9zc2libGUgcGFyYW1ldGVyIHZhbHVlcywgaW5zdGVhZCBvZiBhcyBhbiBhbGdvcml0aG0uXG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVlZFNvbG9tb25Db21wdXRlRGl2aXNvcihkZWdyZWU6IGludCk6IEFycmF5PGJ5dGU+IHtcbiAgICAgIGlmIChkZWdyZWUgPCAxIHx8IGRlZ3JlZSA+IDI1NSkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0RlZ3JlZSBvdXQgb2YgcmFuZ2UnKTtcbiAgICAgIC8vIFBvbHlub21pYWwgY29lZmZpY2llbnRzIGFyZSBzdG9yZWQgZnJvbSBoaWdoZXN0IHRvIGxvd2VzdCBwb3dlciwgZXhjbHVkaW5nIHRoZSBsZWFkaW5nIHRlcm0gd2hpY2ggaXMgYWx3YXlzIDEuXG4gICAgICAvLyBGb3IgZXhhbXBsZSB0aGUgcG9seW5vbWlhbCB4XjMgKyAyNTV4XjIgKyA4eCArIDkzIGlzIHN0b3JlZCBhcyB0aGUgdWludDggYXJyYXkgWzI1NSwgOCwgOTNdLlxuICAgICAgbGV0IHJlc3VsdDogQXJyYXk8Ynl0ZT4gPSBbXTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGVncmVlIC0gMTsgaSsrKSByZXN1bHQucHVzaCgwKTtcbiAgICAgIHJlc3VsdC5wdXNoKDEpOyAvLyBTdGFydCBvZmYgd2l0aCB0aGUgbW9ub21pYWwgeF4wXG5cbiAgICAgIC8vIENvbXB1dGUgdGhlIHByb2R1Y3QgcG9seW5vbWlhbCAoeCAtIHJeMCkgKiAoeCAtIHJeMSkgKiAoeCAtIHJeMikgKiAuLi4gKiAoeCAtIHJee2RlZ3JlZS0xfSksXG4gICAgICAvLyBhbmQgZHJvcCB0aGUgaGlnaGVzdCBtb25vbWlhbCB0ZXJtIHdoaWNoIGlzIGFsd2F5cyAxeF5kZWdyZWUuXG4gICAgICAvLyBOb3RlIHRoYXQgciA9IDB4MDIsIHdoaWNoIGlzIGEgZ2VuZXJhdG9yIGVsZW1lbnQgb2YgdGhpcyBmaWVsZCBHRigyXjgvMHgxMUQpLlxuICAgICAgbGV0IHJvb3QgPSAxO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkZWdyZWU7IGkrKykge1xuICAgICAgICAvLyBNdWx0aXBseSB0aGUgY3VycmVudCBwcm9kdWN0IGJ5ICh4IC0gcl5pKVxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHJlc3VsdC5sZW5ndGg7IGorKykge1xuICAgICAgICAgIHJlc3VsdFtqXSA9IFFyQ29kZS5yZWVkU29sb21vbk11bHRpcGx5KHJlc3VsdFtqXSwgcm9vdCk7XG4gICAgICAgICAgaWYgKGogKyAxIDwgcmVzdWx0Lmxlbmd0aCkgcmVzdWx0W2pdIF49IHJlc3VsdFtqICsgMV07XG4gICAgICAgIH1cbiAgICAgICAgcm9vdCA9IFFyQ29kZS5yZWVkU29sb21vbk11bHRpcGx5KHJvb3QsIDB4MDIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvLyBSZXR1cm5zIHRoZSBSZWVkLVNvbG9tb24gZXJyb3IgY29ycmVjdGlvbiBjb2Rld29yZCBmb3IgdGhlIGdpdmVuIGRhdGEgYW5kIGRpdmlzb3IgcG9seW5vbWlhbHMuXG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVlZFNvbG9tb25Db21wdXRlUmVtYWluZGVyKFxuICAgICAgZGF0YTogUmVhZG9ubHk8QXJyYXk8Ynl0ZT4+LFxuICAgICAgZGl2aXNvcjogUmVhZG9ubHk8QXJyYXk8Ynl0ZT4+XG4gICAgKTogQXJyYXk8Ynl0ZT4ge1xuICAgICAgbGV0IHJlc3VsdDogQXJyYXk8Ynl0ZT4gPSBkaXZpc29yLm1hcChfID0+IDApO1xuICAgICAgZm9yIChjb25zdCBiIG9mIGRhdGEpIHtcbiAgICAgICAgLy8gUG9seW5vbWlhbCBkaXZpc2lvblxuICAgICAgICBjb25zdCBmYWN0b3I6IGJ5dGUgPSBiIF4gKHJlc3VsdC5zaGlmdCgpIGFzIGJ5dGUpO1xuICAgICAgICByZXN1bHQucHVzaCgwKTtcbiAgICAgICAgZGl2aXNvci5mb3JFYWNoKChjb2VmLCBpKSA9PiAocmVzdWx0W2ldIF49IFFyQ29kZS5yZWVkU29sb21vbk11bHRpcGx5KGNvZWYsIGZhY3RvcikpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLy8gUmV0dXJucyB0aGUgcHJvZHVjdCBvZiB0aGUgdHdvIGdpdmVuIGZpZWxkIGVsZW1lbnRzIG1vZHVsbyBHRigyXjgvMHgxMUQpLiBUaGUgYXJndW1lbnRzIGFuZCByZXN1bHRcbiAgICAvLyBhcmUgdW5zaWduZWQgOC1iaXQgaW50ZWdlcnMuIFRoaXMgY291bGQgYmUgaW1wbGVtZW50ZWQgYXMgYSBsb29rdXAgdGFibGUgb2YgMjU2KjI1NiBlbnRyaWVzIG9mIHVpbnQ4LlxuICAgIHByaXZhdGUgc3RhdGljIHJlZWRTb2xvbW9uTXVsdGlwbHkoeDogYnl0ZSwgeTogYnl0ZSk6IGJ5dGUge1xuICAgICAgaWYgKHggPj4+IDggIT0gMCB8fCB5ID4+PiA4ICE9IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdCeXRlIG91dCBvZiByYW5nZScpO1xuICAgICAgLy8gUnVzc2lhbiBwZWFzYW50IG11bHRpcGxpY2F0aW9uXG4gICAgICBsZXQgejogaW50ID0gMDtcbiAgICAgIGZvciAobGV0IGkgPSA3OyBpID49IDA7IGktLSkge1xuICAgICAgICB6ID0gKHogPDwgMSkgXiAoKHogPj4+IDcpICogMHgxMWQpO1xuICAgICAgICB6IF49ICgoeSA+Pj4gaSkgJiAxKSAqIHg7XG4gICAgICB9XG4gICAgICBhc3NlcnQoeiA+Pj4gOCA9PSAwKTtcbiAgICAgIHJldHVybiB6IGFzIGJ5dGU7XG4gICAgfVxuXG4gICAgLy8gQ2FuIG9ubHkgYmUgY2FsbGVkIGltbWVkaWF0ZWx5IGFmdGVyIGEgbGlnaHQgcnVuIGlzIGFkZGVkLCBhbmRcbiAgICAvLyByZXR1cm5zIGVpdGhlciAwLCAxLCBvciAyLiBBIGhlbHBlciBmdW5jdGlvbiBmb3IgZ2V0UGVuYWx0eVNjb3JlKCkuXG4gICAgcHJpdmF0ZSBmaW5kZXJQZW5hbHR5Q291bnRQYXR0ZXJucyhydW5IaXN0b3J5OiBSZWFkb25seTxBcnJheTxpbnQ+Pik6IGludCB7XG4gICAgICBjb25zdCBuOiBpbnQgPSBydW5IaXN0b3J5WzFdO1xuICAgICAgYXNzZXJ0KG4gPD0gdGhpcy5zaXplICogMyk7XG4gICAgICBjb25zdCBjb3JlOiBib29sZWFuID1cbiAgICAgICAgbiA+IDAgJiYgcnVuSGlzdG9yeVsyXSA9PSBuICYmIHJ1bkhpc3RvcnlbM10gPT0gbiAqIDMgJiYgcnVuSGlzdG9yeVs0XSA9PSBuICYmIHJ1bkhpc3RvcnlbNV0gPT0gbjtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIChjb3JlICYmIHJ1bkhpc3RvcnlbMF0gPj0gbiAqIDQgJiYgcnVuSGlzdG9yeVs2XSA+PSBuID8gMSA6IDApICtcbiAgICAgICAgKGNvcmUgJiYgcnVuSGlzdG9yeVs2XSA+PSBuICogNCAmJiBydW5IaXN0b3J5WzBdID49IG4gPyAxIDogMClcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gTXVzdCBiZSBjYWxsZWQgYXQgdGhlIGVuZCBvZiBhIGxpbmUgKHJvdyBvciBjb2x1bW4pIG9mIG1vZHVsZXMuIEEgaGVscGVyIGZ1bmN0aW9uIGZvciBnZXRQZW5hbHR5U2NvcmUoKS5cbiAgICBwcml2YXRlIGZpbmRlclBlbmFsdHlUZXJtaW5hdGVBbmRDb3VudChcbiAgICAgIGN1cnJlbnRSdW5Db2xvcjogYm9vbGVhbixcbiAgICAgIGN1cnJlbnRSdW5MZW5ndGg6IGludCxcbiAgICAgIHJ1bkhpc3Rvcnk6IEFycmF5PGludD5cbiAgICApOiBpbnQge1xuICAgICAgaWYgKGN1cnJlbnRSdW5Db2xvcikge1xuICAgICAgICAvLyBUZXJtaW5hdGUgZGFyayBydW5cbiAgICAgICAgdGhpcy5maW5kZXJQZW5hbHR5QWRkSGlzdG9yeShjdXJyZW50UnVuTGVuZ3RoLCBydW5IaXN0b3J5KTtcbiAgICAgICAgY3VycmVudFJ1bkxlbmd0aCA9IDA7XG4gICAgICB9XG4gICAgICBjdXJyZW50UnVuTGVuZ3RoICs9IHRoaXMuc2l6ZTsgLy8gQWRkIGxpZ2h0IGJvcmRlciB0byBmaW5hbCBydW5cbiAgICAgIHRoaXMuZmluZGVyUGVuYWx0eUFkZEhpc3RvcnkoY3VycmVudFJ1bkxlbmd0aCwgcnVuSGlzdG9yeSk7XG4gICAgICByZXR1cm4gdGhpcy5maW5kZXJQZW5hbHR5Q291bnRQYXR0ZXJucyhydW5IaXN0b3J5KTtcbiAgICB9XG5cbiAgICAvLyBQdXNoZXMgdGhlIGdpdmVuIHZhbHVlIHRvIHRoZSBmcm9udCBhbmQgZHJvcHMgdGhlIGxhc3QgdmFsdWUuIEEgaGVscGVyIGZ1bmN0aW9uIGZvciBnZXRQZW5hbHR5U2NvcmUoKS5cbiAgICBwcml2YXRlIGZpbmRlclBlbmFsdHlBZGRIaXN0b3J5KGN1cnJlbnRSdW5MZW5ndGg6IGludCwgcnVuSGlzdG9yeTogQXJyYXk8aW50Pik6IHZvaWQge1xuICAgICAgaWYgKHJ1bkhpc3RvcnlbMF0gPT0gMCkgY3VycmVudFJ1bkxlbmd0aCArPSB0aGlzLnNpemU7IC8vIEFkZCBsaWdodCBib3JkZXIgdG8gaW5pdGlhbCBydW5cbiAgICAgIHJ1bkhpc3RvcnkucG9wKCk7XG4gICAgICBydW5IaXN0b3J5LnVuc2hpZnQoY3VycmVudFJ1bkxlbmd0aCk7XG4gICAgfVxuXG4gICAgLyotLSBDb25zdGFudHMgYW5kIHRhYmxlcyAtLSovXG5cbiAgICAvLyBUaGUgbWluaW11bSB2ZXJzaW9uIG51bWJlciBzdXBwb3J0ZWQgaW4gdGhlIFFSIENvZGUgTW9kZWwgMiBzdGFuZGFyZC5cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IE1JTl9WRVJTSU9OOiBpbnQgPSAxO1xuICAgIC8vIFRoZSBtYXhpbXVtIHZlcnNpb24gbnVtYmVyIHN1cHBvcnRlZCBpbiB0aGUgUVIgQ29kZSBNb2RlbCAyIHN0YW5kYXJkLlxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgTUFYX1ZFUlNJT046IGludCA9IDQwO1xuXG4gICAgLy8gRm9yIHVzZSBpbiBnZXRQZW5hbHR5U2NvcmUoKSwgd2hlbiBldmFsdWF0aW5nIHdoaWNoIG1hc2sgaXMgYmVzdC5cbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBQRU5BTFRZX04xOiBpbnQgPSAzO1xuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IFBFTkFMVFlfTjI6IGludCA9IDM7XG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgUEVOQUxUWV9OMzogaW50ID0gNDA7XG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgUEVOQUxUWV9ONDogaW50ID0gMTA7XG5cbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBFQ0NfQ09ERVdPUkRTX1BFUl9CTE9DSzogQXJyYXk8QXJyYXk8aW50Pj4gPSBbXG4gICAgICAvLyBWZXJzaW9uOiAobm90ZSB0aGF0IGluZGV4IDAgaXMgZm9yIHBhZGRpbmcsIGFuZCBpcyBzZXQgdG8gYW4gaWxsZWdhbCB2YWx1ZSlcbiAgICAgIC8vMCwgIDEsICAyLCAgMywgIDQsICA1LCAgNiwgIDcsICA4LCAgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwgMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAgICAgRXJyb3IgY29ycmVjdGlvbiBsZXZlbFxuICAgICAgW1xuICAgICAgICAtMSwgNywgMTAsIDE1LCAyMCwgMjYsIDE4LCAyMCwgMjQsIDMwLCAxOCwgMjAsIDI0LCAyNiwgMzAsIDIyLCAyNCwgMjgsIDMwLCAyOCwgMjgsIDI4LCAyOCwgMzAsIDMwLCAyNiwgMjgsIDMwLFxuICAgICAgICAzMCwgMzAsIDMwLCAzMCwgMzAsIDMwLCAzMCwgMzAsIDMwLCAzMCwgMzAsIDMwLCAzMCxcbiAgICAgIF0sIC8vIExvd1xuICAgICAgW1xuICAgICAgICAtMSwgMTAsIDE2LCAyNiwgMTgsIDI0LCAxNiwgMTgsIDIyLCAyMiwgMjYsIDMwLCAyMiwgMjIsIDI0LCAyNCwgMjgsIDI4LCAyNiwgMjYsIDI2LCAyNiwgMjgsIDI4LCAyOCwgMjgsIDI4LCAyOCxcbiAgICAgICAgMjgsIDI4LCAyOCwgMjgsIDI4LCAyOCwgMjgsIDI4LCAyOCwgMjgsIDI4LCAyOCwgMjgsXG4gICAgICBdLCAvLyBNZWRpdW1cbiAgICAgIFtcbiAgICAgICAgLTEsIDEzLCAyMiwgMTgsIDI2LCAxOCwgMjQsIDE4LCAyMiwgMjAsIDI0LCAyOCwgMjYsIDI0LCAyMCwgMzAsIDI0LCAyOCwgMjgsIDI2LCAzMCwgMjgsIDMwLCAzMCwgMzAsIDMwLCAyOCwgMzAsXG4gICAgICAgIDMwLCAzMCwgMzAsIDMwLCAzMCwgMzAsIDMwLCAzMCwgMzAsIDMwLCAzMCwgMzAsIDMwLFxuICAgICAgXSwgLy8gUXVhcnRpbGVcbiAgICAgIFtcbiAgICAgICAgLTEsIDE3LCAyOCwgMjIsIDE2LCAyMiwgMjgsIDI2LCAyNiwgMjQsIDI4LCAyNCwgMjgsIDIyLCAyNCwgMjQsIDMwLCAyOCwgMjgsIDI2LCAyOCwgMzAsIDI0LCAzMCwgMzAsIDMwLCAzMCwgMzAsXG4gICAgICAgIDMwLCAzMCwgMzAsIDMwLCAzMCwgMzAsIDMwLCAzMCwgMzAsIDMwLCAzMCwgMzAsIDMwLFxuICAgICAgXSwgLy8gSGlnaFxuICAgIF07XG5cbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBOVU1fRVJST1JfQ09SUkVDVElPTl9CTE9DS1M6IEFycmF5PEFycmF5PGludD4+ID0gW1xuICAgICAgLy8gVmVyc2lvbjogKG5vdGUgdGhhdCBpbmRleCAwIGlzIGZvciBwYWRkaW5nLCBhbmQgaXMgc2V0IHRvIGFuIGlsbGVnYWwgdmFsdWUpXG4gICAgICAvLzAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwgMTYsIDE3LCAxOCwgMTksIDIwLCAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAgICAgRXJyb3IgY29ycmVjdGlvbiBsZXZlbFxuICAgICAgW1xuICAgICAgICAtMSwgMSwgMSwgMSwgMSwgMSwgMiwgMiwgMiwgMiwgNCwgNCwgNCwgNCwgNCwgNiwgNiwgNiwgNiwgNywgOCwgOCwgOSwgOSwgMTAsIDEyLCAxMiwgMTIsIDEzLCAxNCwgMTUsIDE2LCAxNywgMTgsXG4gICAgICAgIDE5LCAxOSwgMjAsIDIxLCAyMiwgMjQsIDI1LFxuICAgICAgXSwgLy8gTG93XG4gICAgICBbXG4gICAgICAgIC0xLCAxLCAxLCAxLCAyLCAyLCA0LCA0LCA0LCA1LCA1LCA1LCA4LCA5LCA5LCAxMCwgMTAsIDExLCAxMywgMTQsIDE2LCAxNywgMTcsIDE4LCAyMCwgMjEsIDIzLCAyNSwgMjYsIDI4LCAyOSxcbiAgICAgICAgMzEsIDMzLCAzNSwgMzcsIDM4LCA0MCwgNDMsIDQ1LCA0NywgNDksXG4gICAgICBdLCAvLyBNZWRpdW1cbiAgICAgIFtcbiAgICAgICAgLTEsIDEsIDEsIDIsIDIsIDQsIDQsIDYsIDYsIDgsIDgsIDgsIDEwLCAxMiwgMTYsIDEyLCAxNywgMTYsIDE4LCAyMSwgMjAsIDIzLCAyMywgMjUsIDI3LCAyOSwgMzQsIDM0LCAzNSwgMzgsIDQwLFxuICAgICAgICA0MywgNDUsIDQ4LCA1MSwgNTMsIDU2LCA1OSwgNjIsIDY1LCA2OCxcbiAgICAgIF0sIC8vIFF1YXJ0aWxlXG4gICAgICBbXG4gICAgICAgIC0xLCAxLCAxLCAyLCA0LCA0LCA0LCA1LCA2LCA4LCA4LCAxMSwgMTEsIDE2LCAxNiwgMTgsIDE2LCAxOSwgMjEsIDI1LCAyNSwgMjUsIDM0LCAzMCwgMzIsIDM1LCAzNywgNDAsIDQyLCA0NSxcbiAgICAgICAgNDgsIDUxLCA1NCwgNTcsIDYwLCA2MywgNjYsIDcwLCA3NCwgNzcsIDgxLFxuICAgICAgXSwgLy8gSGlnaFxuICAgIF07XG4gIH1cblxuICAvLyBBcHBlbmRzIHRoZSBnaXZlbiBudW1iZXIgb2YgbG93LW9yZGVyIGJpdHMgb2YgdGhlIGdpdmVuIHZhbHVlXG4gIC8vIHRvIHRoZSBnaXZlbiBidWZmZXIuIFJlcXVpcmVzIDAgPD0gbGVuIDw9IDMxIGFuZCAwIDw9IHZhbCA8IDJebGVuLlxuICBmdW5jdGlvbiBhcHBlbmRCaXRzKHZhbDogaW50LCBsZW46IGludCwgYmI6IEFycmF5PGJpdD4pOiB2b2lkIHtcbiAgICBpZiAobGVuIDwgMCB8fCBsZW4gPiAzMSB8fCB2YWwgPj4+IGxlbiAhPSAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVmFsdWUgb3V0IG9mIHJhbmdlJyk7XG4gICAgZm9yIChcbiAgICAgIGxldCBpID0gbGVuIC0gMTtcbiAgICAgIGkgPj0gMDtcbiAgICAgIGktLSAvLyBBcHBlbmQgYml0IGJ5IGJpdFxuICAgIClcbiAgICAgIGJiLnB1c2goKHZhbCA+Pj4gaSkgJiAxKTtcbiAgfVxuXG4gIC8vIFJldHVybnMgdHJ1ZSBpZmYgdGhlIGkndGggYml0IG9mIHggaXMgc2V0IHRvIDEuXG4gIGZ1bmN0aW9uIGdldEJpdCh4OiBpbnQsIGk6IGludCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoKHggPj4+IGkpICYgMSkgIT0gMDtcbiAgfVxuXG4gIC8vIFRocm93cyBhbiBleGNlcHRpb24gaWYgdGhlIGdpdmVuIGNvbmRpdGlvbiBpcyBmYWxzZS5cbiAgZnVuY3Rpb24gYXNzZXJ0KGNvbmQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAoIWNvbmQpIHRocm93IG5ldyBFcnJvcignQXNzZXJ0aW9uIGVycm9yJyk7XG4gIH1cblxuICAvKi0tLS0gRGF0YSBzZWdtZW50IGNsYXNzIC0tLS0qL1xuXG4gIC8qXG4gICAqIEEgc2VnbWVudCBvZiBjaGFyYWN0ZXIvYmluYXJ5L2NvbnRyb2wgZGF0YSBpbiBhIFFSIENvZGUgc3ltYm9sLlxuICAgKiBJbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyBhcmUgaW1tdXRhYmxlLlxuICAgKiBUaGUgbWlkLWxldmVsIHdheSB0byBjcmVhdGUgYSBzZWdtZW50IGlzIHRvIHRha2UgdGhlIHBheWxvYWQgZGF0YVxuICAgKiBhbmQgY2FsbCBhIHN0YXRpYyBmYWN0b3J5IGZ1bmN0aW9uIHN1Y2ggYXMgUXJTZWdtZW50Lm1ha2VOdW1lcmljKCkuXG4gICAqIFRoZSBsb3ctbGV2ZWwgd2F5IHRvIGNyZWF0ZSBhIHNlZ21lbnQgaXMgdG8gY3VzdG9tLW1ha2UgdGhlIGJpdCBidWZmZXJcbiAgICogYW5kIGNhbGwgdGhlIFFyU2VnbWVudCgpIGNvbnN0cnVjdG9yIHdpdGggYXBwcm9wcmlhdGUgdmFsdWVzLlxuICAgKiBUaGlzIHNlZ21lbnQgY2xhc3MgaW1wb3NlcyBubyBsZW5ndGggcmVzdHJpY3Rpb25zLCBidXQgUVIgQ29kZXMgaGF2ZSByZXN0cmljdGlvbnMuXG4gICAqIEV2ZW4gaW4gdGhlIG1vc3QgZmF2b3JhYmxlIGNvbmRpdGlvbnMsIGEgUVIgQ29kZSBjYW4gb25seSBob2xkIDcwODkgY2hhcmFjdGVycyBvZiBkYXRhLlxuICAgKiBBbnkgc2VnbWVudCBsb25nZXIgdGhhbiB0aGlzIGlzIG1lYW5pbmdsZXNzIGZvciB0aGUgcHVycG9zZSBvZiBnZW5lcmF0aW5nIFFSIENvZGVzLlxuICAgKi9cbiAgZXhwb3J0IGNsYXNzIFFyU2VnbWVudCB7XG4gICAgLyotLSBTdGF0aWMgZmFjdG9yeSBmdW5jdGlvbnMgKG1pZCBsZXZlbCkgLS0qL1xuXG4gICAgLy8gUmV0dXJucyBhIHNlZ21lbnQgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiBiaW5hcnkgZGF0YSBlbmNvZGVkIGluXG4gICAgLy8gYnl0ZSBtb2RlLiBBbGwgaW5wdXQgYnl0ZSBhcnJheXMgYXJlIGFjY2VwdGFibGUuIEFueSB0ZXh0IHN0cmluZ1xuICAgIC8vIGNhbiBiZSBjb252ZXJ0ZWQgdG8gVVRGLTggYnl0ZXMgYW5kIGVuY29kZWQgYXMgYSBieXRlIG1vZGUgc2VnbWVudC5cbiAgICBwdWJsaWMgc3RhdGljIG1ha2VCeXRlcyhkYXRhOiBSZWFkb25seTxBcnJheTxieXRlPj4pOiBRclNlZ21lbnQge1xuICAgICAgbGV0IGJiOiBBcnJheTxiaXQ+ID0gW107XG4gICAgICBmb3IgKGNvbnN0IGIgb2YgZGF0YSkgYXBwZW5kQml0cyhiLCA4LCBiYik7XG4gICAgICByZXR1cm4gbmV3IFFyU2VnbWVudChRclNlZ21lbnQuTW9kZS5CWVRFLCBkYXRhLmxlbmd0aCwgYmIpO1xuICAgIH1cblxuICAgIC8vIFJldHVybnMgYSBzZWdtZW50IHJlcHJlc2VudGluZyB0aGUgZ2l2ZW4gc3RyaW5nIG9mIGRlY2ltYWwgZGlnaXRzIGVuY29kZWQgaW4gbnVtZXJpYyBtb2RlLlxuICAgIHB1YmxpYyBzdGF0aWMgbWFrZU51bWVyaWMoZGlnaXRzOiBzdHJpbmcpOiBRclNlZ21lbnQge1xuICAgICAgaWYgKCFRclNlZ21lbnQuaXNOdW1lcmljKGRpZ2l0cykpIHRocm93IG5ldyBSYW5nZUVycm9yKCdTdHJpbmcgY29udGFpbnMgbm9uLW51bWVyaWMgY2hhcmFjdGVycycpO1xuICAgICAgbGV0IGJiOiBBcnJheTxiaXQ+ID0gW107XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpZ2l0cy5sZW5ndGg7ICkge1xuICAgICAgICAvLyBDb25zdW1lIHVwIHRvIDMgZGlnaXRzIHBlciBpdGVyYXRpb25cbiAgICAgICAgY29uc3QgbjogaW50ID0gTWF0aC5taW4oZGlnaXRzLmxlbmd0aCAtIGksIDMpO1xuICAgICAgICBhcHBlbmRCaXRzKHBhcnNlSW50KGRpZ2l0cy5zdWJzdHJpbmcoaSwgaSArIG4pLCAxMCksIG4gKiAzICsgMSwgYmIpO1xuICAgICAgICBpICs9IG47XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IFFyU2VnbWVudChRclNlZ21lbnQuTW9kZS5OVU1FUklDLCBkaWdpdHMubGVuZ3RoLCBiYik7XG4gICAgfVxuXG4gICAgLy8gUmV0dXJucyBhIHNlZ21lbnQgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiB0ZXh0IHN0cmluZyBlbmNvZGVkIGluIGFscGhhbnVtZXJpYyBtb2RlLlxuICAgIC8vIFRoZSBjaGFyYWN0ZXJzIGFsbG93ZWQgYXJlOiAwIHRvIDksIEEgdG8gWiAodXBwZXJjYXNlIG9ubHkpLCBzcGFjZSxcbiAgICAvLyBkb2xsYXIsIHBlcmNlbnQsIGFzdGVyaXNrLCBwbHVzLCBoeXBoZW4sIHBlcmlvZCwgc2xhc2gsIGNvbG9uLlxuICAgIHB1YmxpYyBzdGF0aWMgbWFrZUFscGhhbnVtZXJpYyh0ZXh0OiBzdHJpbmcpOiBRclNlZ21lbnQge1xuICAgICAgaWYgKCFRclNlZ21lbnQuaXNBbHBoYW51bWVyaWModGV4dCkpXG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdTdHJpbmcgY29udGFpbnMgdW5lbmNvZGFibGUgY2hhcmFjdGVycyBpbiBhbHBoYW51bWVyaWMgbW9kZScpO1xuICAgICAgbGV0IGJiOiBBcnJheTxiaXQ+ID0gW107XG4gICAgICBsZXQgaTogaW50O1xuICAgICAgZm9yIChpID0gMDsgaSArIDIgPD0gdGV4dC5sZW5ndGg7IGkgKz0gMikge1xuICAgICAgICAvLyBQcm9jZXNzIGdyb3VwcyBvZiAyXG4gICAgICAgIGxldCB0ZW1wOiBpbnQgPSBRclNlZ21lbnQuQUxQSEFOVU1FUklDX0NIQVJTRVQuaW5kZXhPZih0ZXh0LmNoYXJBdChpKSkgKiA0NTtcbiAgICAgICAgdGVtcCArPSBRclNlZ21lbnQuQUxQSEFOVU1FUklDX0NIQVJTRVQuaW5kZXhPZih0ZXh0LmNoYXJBdChpICsgMSkpO1xuICAgICAgICBhcHBlbmRCaXRzKHRlbXAsIDExLCBiYik7XG4gICAgICB9XG4gICAgICBpZiAoaSA8IHRleHQubGVuZ3RoKVxuICAgICAgICAvLyAxIGNoYXJhY3RlciByZW1haW5pbmdcbiAgICAgICAgYXBwZW5kQml0cyhRclNlZ21lbnQuQUxQSEFOVU1FUklDX0NIQVJTRVQuaW5kZXhPZih0ZXh0LmNoYXJBdChpKSksIDYsIGJiKTtcbiAgICAgIHJldHVybiBuZXcgUXJTZWdtZW50KFFyU2VnbWVudC5Nb2RlLkFMUEhBTlVNRVJJQywgdGV4dC5sZW5ndGgsIGJiKTtcbiAgICB9XG5cbiAgICAvLyBSZXR1cm5zIGEgbmV3IG11dGFibGUgbGlzdCBvZiB6ZXJvIG9yIG1vcmUgc2VnbWVudHMgdG8gcmVwcmVzZW50IHRoZSBnaXZlbiBVbmljb2RlIHRleHQgc3RyaW5nLlxuICAgIC8vIFRoZSByZXN1bHQgbWF5IHVzZSB2YXJpb3VzIHNlZ21lbnQgbW9kZXMgYW5kIHN3aXRjaCBtb2RlcyB0byBvcHRpbWl6ZSB0aGUgbGVuZ3RoIG9mIHRoZSBiaXQgc3RyZWFtLlxuICAgIHB1YmxpYyBzdGF0aWMgbWFrZVNlZ21lbnRzKHRleHQ6IHN0cmluZyk6IEFycmF5PFFyU2VnbWVudD4ge1xuICAgICAgLy8gU2VsZWN0IHRoZSBtb3N0IGVmZmljaWVudCBzZWdtZW50IGVuY29kaW5nIGF1dG9tYXRpY2FsbHlcbiAgICAgIGlmICh0ZXh0ID09ICcnKSByZXR1cm4gW107XG4gICAgICBlbHNlIGlmIChRclNlZ21lbnQuaXNOdW1lcmljKHRleHQpKSByZXR1cm4gW1FyU2VnbWVudC5tYWtlTnVtZXJpYyh0ZXh0KV07XG4gICAgICBlbHNlIGlmIChRclNlZ21lbnQuaXNBbHBoYW51bWVyaWModGV4dCkpIHJldHVybiBbUXJTZWdtZW50Lm1ha2VBbHBoYW51bWVyaWModGV4dCldO1xuICAgICAgZWxzZSByZXR1cm4gW1FyU2VnbWVudC5tYWtlQnl0ZXMoUXJTZWdtZW50LnRvVXRmOEJ5dGVBcnJheSh0ZXh0KSldO1xuICAgIH1cblxuICAgIC8vIFJldHVybnMgYSBzZWdtZW50IHJlcHJlc2VudGluZyBhbiBFeHRlbmRlZCBDaGFubmVsIEludGVycHJldGF0aW9uXG4gICAgLy8gKEVDSSkgZGVzaWduYXRvciB3aXRoIHRoZSBnaXZlbiBhc3NpZ25tZW50IHZhbHVlLlxuICAgIHB1YmxpYyBzdGF0aWMgbWFrZUVjaShhc3NpZ25WYWw6IGludCk6IFFyU2VnbWVudCB7XG4gICAgICBsZXQgYmI6IEFycmF5PGJpdD4gPSBbXTtcbiAgICAgIGlmIChhc3NpZ25WYWwgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignRUNJIGFzc2lnbm1lbnQgdmFsdWUgb3V0IG9mIHJhbmdlJyk7XG4gICAgICBlbHNlIGlmIChhc3NpZ25WYWwgPCAxIDw8IDcpIGFwcGVuZEJpdHMoYXNzaWduVmFsLCA4LCBiYik7XG4gICAgICBlbHNlIGlmIChhc3NpZ25WYWwgPCAxIDw8IDE0KSB7XG4gICAgICAgIGFwcGVuZEJpdHMoMGIxMCwgMiwgYmIpO1xuICAgICAgICBhcHBlbmRCaXRzKGFzc2lnblZhbCwgMTQsIGJiKTtcbiAgICAgIH0gZWxzZSBpZiAoYXNzaWduVmFsIDwgMTAwMDAwMCkge1xuICAgICAgICBhcHBlbmRCaXRzKDBiMTEwLCAzLCBiYik7XG4gICAgICAgIGFwcGVuZEJpdHMoYXNzaWduVmFsLCAyMSwgYmIpO1xuICAgICAgfSBlbHNlIHRocm93IG5ldyBSYW5nZUVycm9yKCdFQ0kgYXNzaWdubWVudCB2YWx1ZSBvdXQgb2YgcmFuZ2UnKTtcbiAgICAgIHJldHVybiBuZXcgUXJTZWdtZW50KFFyU2VnbWVudC5Nb2RlLkVDSSwgMCwgYmIpO1xuICAgIH1cblxuICAgIC8vIFRlc3RzIHdoZXRoZXIgdGhlIGdpdmVuIHN0cmluZyBjYW4gYmUgZW5jb2RlZCBhcyBhIHNlZ21lbnQgaW4gbnVtZXJpYyBtb2RlLlxuICAgIC8vIEEgc3RyaW5nIGlzIGVuY29kYWJsZSBpZmYgZWFjaCBjaGFyYWN0ZXIgaXMgaW4gdGhlIHJhbmdlIDAgdG8gOS5cbiAgICBwdWJsaWMgc3RhdGljIGlzTnVtZXJpYyh0ZXh0OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiBRclNlZ21lbnQuTlVNRVJJQ19SRUdFWC50ZXN0KHRleHQpO1xuICAgIH1cblxuICAgIC8vIFRlc3RzIHdoZXRoZXIgdGhlIGdpdmVuIHN0cmluZyBjYW4gYmUgZW5jb2RlZCBhcyBhIHNlZ21lbnQgaW4gYWxwaGFudW1lcmljIG1vZGUuXG4gICAgLy8gQSBzdHJpbmcgaXMgZW5jb2RhYmxlIGlmZiBlYWNoIGNoYXJhY3RlciBpcyBpbiB0aGUgZm9sbG93aW5nIHNldDogMCB0byA5LCBBIHRvIFpcbiAgICAvLyAodXBwZXJjYXNlIG9ubHkpLCBzcGFjZSwgZG9sbGFyLCBwZXJjZW50LCBhc3RlcmlzaywgcGx1cywgaHlwaGVuLCBwZXJpb2QsIHNsYXNoLCBjb2xvbi5cbiAgICBwdWJsaWMgc3RhdGljIGlzQWxwaGFudW1lcmljKHRleHQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIFFyU2VnbWVudC5BTFBIQU5VTUVSSUNfUkVHRVgudGVzdCh0ZXh0KTtcbiAgICB9XG5cbiAgICAvKi0tIENvbnN0cnVjdG9yIChsb3cgbGV2ZWwpIGFuZCBmaWVsZHMgLS0qL1xuXG4gICAgLy8gQ3JlYXRlcyBhIG5ldyBRUiBDb2RlIHNlZ21lbnQgd2l0aCB0aGUgZ2l2ZW4gYXR0cmlidXRlcyBhbmQgZGF0YS5cbiAgICAvLyBUaGUgY2hhcmFjdGVyIGNvdW50IChudW1DaGFycykgbXVzdCBhZ3JlZSB3aXRoIHRoZSBtb2RlIGFuZCB0aGUgYml0IGJ1ZmZlciBsZW5ndGgsXG4gICAgLy8gYnV0IHRoZSBjb25zdHJhaW50IGlzbid0IGNoZWNrZWQuIFRoZSBnaXZlbiBiaXQgYnVmZmVyIGlzIGNsb25lZCBhbmQgc3RvcmVkLlxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICAgIC8vIFRoZSBtb2RlIGluZGljYXRvciBvZiB0aGlzIHNlZ21lbnQuXG4gICAgICBwdWJsaWMgcmVhZG9ubHkgbW9kZTogUXJTZWdtZW50Lk1vZGUsXG5cbiAgICAgIC8vIFRoZSBsZW5ndGggb2YgdGhpcyBzZWdtZW50J3MgdW5lbmNvZGVkIGRhdGEuIE1lYXN1cmVkIGluIGNoYXJhY3RlcnMgZm9yXG4gICAgICAvLyBudW1lcmljL2FscGhhbnVtZXJpYy9rYW5qaSBtb2RlLCBieXRlcyBmb3IgYnl0ZSBtb2RlLCBhbmQgMCBmb3IgRUNJIG1vZGUuXG4gICAgICAvLyBBbHdheXMgemVybyBvciBwb3NpdGl2ZS4gTm90IHRoZSBzYW1lIGFzIHRoZSBkYXRhJ3MgYml0IGxlbmd0aC5cbiAgICAgIHB1YmxpYyByZWFkb25seSBudW1DaGFyczogaW50LFxuXG4gICAgICAvLyBUaGUgZGF0YSBiaXRzIG9mIHRoaXMgc2VnbWVudC4gQWNjZXNzZWQgdGhyb3VnaCBnZXREYXRhKCkuXG4gICAgICBwcml2YXRlIHJlYWRvbmx5IGJpdERhdGE6IEFycmF5PGJpdD5cbiAgICApIHtcbiAgICAgIGlmIChudW1DaGFycyA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbnZhbGlkIGFyZ3VtZW50Jyk7XG4gICAgICB0aGlzLmJpdERhdGEgPSBiaXREYXRhLnNsaWNlKCk7IC8vIE1ha2UgZGVmZW5zaXZlIGNvcHlcbiAgICB9XG5cbiAgICAvKi0tIE1ldGhvZHMgLS0qL1xuXG4gICAgLy8gUmV0dXJucyBhIG5ldyBjb3B5IG9mIHRoZSBkYXRhIGJpdHMgb2YgdGhpcyBzZWdtZW50LlxuICAgIHB1YmxpYyBnZXREYXRhKCk6IEFycmF5PGJpdD4ge1xuICAgICAgcmV0dXJuIHRoaXMuYml0RGF0YS5zbGljZSgpOyAvLyBNYWtlIGRlZmVuc2l2ZSBjb3B5XG4gICAgfVxuXG4gICAgLy8gKFBhY2thZ2UtcHJpdmF0ZSkgQ2FsY3VsYXRlcyBhbmQgcmV0dXJucyB0aGUgbnVtYmVyIG9mIGJpdHMgbmVlZGVkIHRvIGVuY29kZSB0aGUgZ2l2ZW4gc2VnbWVudHMgYXRcbiAgICAvLyB0aGUgZ2l2ZW4gdmVyc2lvbi4gVGhlIHJlc3VsdCBpcyBpbmZpbml0eSBpZiBhIHNlZ21lbnQgaGFzIHRvbyBtYW55IGNoYXJhY3RlcnMgdG8gZml0IGl0cyBsZW5ndGggZmllbGQuXG4gICAgcHVibGljIHN0YXRpYyBnZXRUb3RhbEJpdHMoc2VnczogUmVhZG9ubHk8QXJyYXk8UXJTZWdtZW50Pj4sIHZlcnNpb246IGludCk6IG51bWJlciB7XG4gICAgICBsZXQgcmVzdWx0ID0gMDtcbiAgICAgIGZvciAoY29uc3Qgc2VnIG9mIHNlZ3MpIHtcbiAgICAgICAgY29uc3QgY2NiaXRzOiBpbnQgPSBzZWcubW9kZS5udW1DaGFyQ291bnRCaXRzKHZlcnNpb24pO1xuICAgICAgICBpZiAoc2VnLm51bUNoYXJzID49IDEgPDwgY2NiaXRzKSByZXR1cm4gSW5maW5pdHk7IC8vIFRoZSBzZWdtZW50J3MgbGVuZ3RoIGRvZXNuJ3QgZml0IHRoZSBmaWVsZCdzIGJpdCB3aWR0aFxuICAgICAgICByZXN1bHQgKz0gNCArIGNjYml0cyArIHNlZy5iaXREYXRhLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLy8gUmV0dXJucyBhIG5ldyBhcnJheSBvZiBieXRlcyByZXByZXNlbnRpbmcgdGhlIGdpdmVuIHN0cmluZyBlbmNvZGVkIGluIFVURi04LlxuICAgIHByaXZhdGUgc3RhdGljIHRvVXRmOEJ5dGVBcnJheShzdHI6IHN0cmluZyk6IEFycmF5PGJ5dGU+IHtcbiAgICAgIHN0ciA9IGVuY29kZVVSSShzdHIpO1xuICAgICAgbGV0IHJlc3VsdDogQXJyYXk8Ynl0ZT4gPSBbXTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChzdHIuY2hhckF0KGkpICE9ICclJykgcmVzdWx0LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICByZXN1bHQucHVzaChwYXJzZUludChzdHIuc3Vic3RyaW5nKGkgKyAxLCBpICsgMyksIDE2KSk7XG4gICAgICAgICAgaSArPSAyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qLS0gQ29uc3RhbnRzIC0tKi9cblxuICAgIC8vIERlc2NyaWJlcyBwcmVjaXNlbHkgYWxsIHN0cmluZ3MgdGhhdCBhcmUgZW5jb2RhYmxlIGluIG51bWVyaWMgbW9kZS5cbiAgICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBOVU1FUklDX1JFR0VYOiBSZWdFeHAgPSAvXlswLTldKiQvO1xuXG4gICAgLy8gRGVzY3JpYmVzIHByZWNpc2VseSBhbGwgc3RyaW5ncyB0aGF0IGFyZSBlbmNvZGFibGUgaW4gYWxwaGFudW1lcmljIG1vZGUuXG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgQUxQSEFOVU1FUklDX1JFR0VYOiBSZWdFeHAgPSAvXltBLVowLTkgJCUqKy5cXC86LV0qJC87XG5cbiAgICAvLyBUaGUgc2V0IG9mIGFsbCBsZWdhbCBjaGFyYWN0ZXJzIGluIGFscGhhbnVtZXJpYyBtb2RlLFxuICAgIC8vIHdoZXJlIGVhY2ggY2hhcmFjdGVyIHZhbHVlIG1hcHMgdG8gdGhlIGluZGV4IGluIHRoZSBzdHJpbmcuXG4gICAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgQUxQSEFOVU1FUklDX0NIQVJTRVQ6IHN0cmluZyA9ICcwMTIzNDU2Nzg5QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVogJCUqKy0uLzonO1xuICB9XG59XG5cbi8qLS0tLSBQdWJsaWMgaGVscGVyIGVudW1lcmF0aW9uIC0tLS0qL1xuXG5uYW1lc3BhY2UgcXJjb2RlZ2VuLlFyQ29kZSB7XG4gIHR5cGUgaW50ID0gbnVtYmVyO1xuXG4gIC8qXG4gICAqIFRoZSBlcnJvciBjb3JyZWN0aW9uIGxldmVsIGluIGEgUVIgQ29kZSBzeW1ib2wuIEltbXV0YWJsZS5cbiAgICovXG4gIGV4cG9ydCBjbGFzcyBFY2Mge1xuICAgIC8qLS0gQ29uc3RhbnRzIC0tKi9cblxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgTE9XID0gbmV3IEVjYygwLCAxKTsgLy8gVGhlIFFSIENvZGUgY2FuIHRvbGVyYXRlIGFib3V0ICA3JSBlcnJvbmVvdXMgY29kZXdvcmRzXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBNRURJVU0gPSBuZXcgRWNjKDEsIDApOyAvLyBUaGUgUVIgQ29kZSBjYW4gdG9sZXJhdGUgYWJvdXQgMTUlIGVycm9uZW91cyBjb2Rld29yZHNcbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFFVQVJUSUxFID0gbmV3IEVjYygyLCAzKTsgLy8gVGhlIFFSIENvZGUgY2FuIHRvbGVyYXRlIGFib3V0IDI1JSBlcnJvbmVvdXMgY29kZXdvcmRzXG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBISUdIID0gbmV3IEVjYygzLCAyKTsgLy8gVGhlIFFSIENvZGUgY2FuIHRvbGVyYXRlIGFib3V0IDMwJSBlcnJvbmVvdXMgY29kZXdvcmRzXG5cbiAgICAvKi0tIENvbnN0cnVjdG9yIGFuZCBmaWVsZHMgLS0qL1xuXG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihcbiAgICAgIC8vIEluIHRoZSByYW5nZSAwIHRvIDMgKHVuc2lnbmVkIDItYml0IGludGVnZXIpLlxuICAgICAgcHVibGljIHJlYWRvbmx5IG9yZGluYWw6IGludCxcbiAgICAgIC8vIChQYWNrYWdlLXByaXZhdGUpIEluIHRoZSByYW5nZSAwIHRvIDMgKHVuc2lnbmVkIDItYml0IGludGVnZXIpLlxuICAgICAgcHVibGljIHJlYWRvbmx5IGZvcm1hdEJpdHM6IGludFxuICAgICkge31cbiAgfVxufVxuXG4vKi0tLS0gUHVibGljIGhlbHBlciBlbnVtZXJhdGlvbiAtLS0tKi9cblxubmFtZXNwYWNlIHFyY29kZWdlbi5RclNlZ21lbnQge1xuICB0eXBlIGludCA9IG51bWJlcjtcblxuICAvKlxuICAgKiBEZXNjcmliZXMgaG93IGEgc2VnbWVudCdzIGRhdGEgYml0cyBhcmUgaW50ZXJwcmV0ZWQuIEltbXV0YWJsZS5cbiAgICovXG4gIGV4cG9ydCBjbGFzcyBNb2RlIHtcbiAgICAvKi0tIENvbnN0YW50cyAtLSovXG5cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IE5VTUVSSUMgPSBuZXcgTW9kZSgweDEsIFsxMCwgMTIsIDE0XSk7XG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBBTFBIQU5VTUVSSUMgPSBuZXcgTW9kZSgweDIsIFs5LCAxMSwgMTNdKTtcbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IEJZVEUgPSBuZXcgTW9kZSgweDQsIFs4LCAxNiwgMTZdKTtcbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IEtBTkpJID0gbmV3IE1vZGUoMHg4LCBbOCwgMTAsIDEyXSk7XG4gICAgcHVibGljIHN0YXRpYyByZWFkb25seSBFQ0kgPSBuZXcgTW9kZSgweDcsIFswLCAwLCAwXSk7XG5cbiAgICAvKi0tIENvbnN0cnVjdG9yIGFuZCBmaWVsZHMgLS0qL1xuXG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihcbiAgICAgIC8vIFRoZSBtb2RlIGluZGljYXRvciBiaXRzLCB3aGljaCBpcyBhIHVpbnQ0IHZhbHVlIChyYW5nZSAwIHRvIDE1KS5cbiAgICAgIHB1YmxpYyByZWFkb25seSBtb2RlQml0czogaW50LFxuICAgICAgLy8gTnVtYmVyIG9mIGNoYXJhY3RlciBjb3VudCBiaXRzIGZvciB0aHJlZSBkaWZmZXJlbnQgdmVyc2lvbiByYW5nZXMuXG4gICAgICBwcml2YXRlIHJlYWRvbmx5IG51bUJpdHNDaGFyQ291bnQ6IFtpbnQsIGludCwgaW50XVxuICAgICkge31cblxuICAgIC8qLS0gTWV0aG9kIC0tKi9cblxuICAgIC8vIChQYWNrYWdlLXByaXZhdGUpIFJldHVybnMgdGhlIGJpdCB3aWR0aCBvZiB0aGUgY2hhcmFjdGVyIGNvdW50IGZpZWxkIGZvciBhIHNlZ21lbnQgaW5cbiAgICAvLyB0aGlzIG1vZGUgaW4gYSBRUiBDb2RlIGF0IHRoZSBnaXZlbiB2ZXJzaW9uIG51bWJlci4gVGhlIHJlc3VsdCBpcyBpbiB0aGUgcmFuZ2UgWzAsIDE2XS5cbiAgICBwdWJsaWMgbnVtQ2hhckNvdW50Qml0cyh2ZXI6IGludCk6IGludCB7XG4gICAgICByZXR1cm4gdGhpcy5udW1CaXRzQ2hhckNvdW50W01hdGguZmxvb3IoKHZlciArIDcpIC8gMTcpXTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgcXJjb2RlZ2VuO1xuIl19
|