@dereekb/dbx-form 9.25.16 → 10.0.1
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/_index.scss +1 -0
- package/calendar/lib/calendar.module.d.ts +1 -1
- package/calendar/lib/calendar.schedule.selection.cell.component.d.ts +1 -1
- package/calendar/lib/calendar.schedule.selection.component.d.ts +4 -4
- package/calendar/lib/calendar.schedule.selection.d.ts +1 -1
- package/calendar/lib/calendar.schedule.selection.days.component.d.ts +1 -1
- package/calendar/lib/calendar.schedule.selection.days.form.component.d.ts +2 -2
- package/calendar/lib/calendar.schedule.selection.dialog.button.component.d.ts +1 -6
- package/calendar/lib/calendar.schedule.selection.dialog.component.d.ts +1 -11
- package/calendar/lib/calendar.schedule.selection.popover.button.component.d.ts +2 -2
- package/calendar/lib/calendar.schedule.selection.popover.component.d.ts +1 -1
- package/calendar/lib/calendar.schedule.selection.popover.content.component.d.ts +1 -1
- package/calendar/lib/calendar.schedule.selection.range.component.d.ts +1 -1
- package/calendar/lib/calendar.schedule.selection.store.d.ts +4 -32
- package/calendar/lib/calendar.schedule.selection.store.provide.d.ts +1 -1
- package/calendar/lib/calendar.schedule.selection.toggle.button.component.d.ts +1 -1
- package/calendar/lib/field/schedule/calendar.schedule.field.component.d.ts +2 -8
- package/esm2022/calendar/lib/calendar.module.mjs +155 -0
- package/{esm2020 → esm2022}/calendar/lib/calendar.schedule.selection.cell.component.mjs +10 -10
- package/{esm2020 → esm2022}/calendar/lib/calendar.schedule.selection.component.mjs +6 -6
- package/{esm2020 → esm2022}/calendar/lib/calendar.schedule.selection.days.component.mjs +6 -6
- package/{esm2020 → esm2022}/calendar/lib/calendar.schedule.selection.days.form.component.mjs +6 -6
- package/esm2022/calendar/lib/calendar.schedule.selection.dialog.button.component.mjs +36 -0
- package/esm2022/calendar/lib/calendar.schedule.selection.dialog.component.mjs +56 -0
- package/{esm2020 → esm2022}/calendar/lib/calendar.schedule.selection.mjs +1 -1
- package/{esm2020 → esm2022}/calendar/lib/calendar.schedule.selection.popover.button.component.mjs +6 -6
- package/esm2022/calendar/lib/calendar.schedule.selection.popover.component.mjs +38 -0
- package/{esm2020 → esm2022}/calendar/lib/calendar.schedule.selection.popover.content.component.mjs +6 -6
- package/esm2022/calendar/lib/calendar.schedule.selection.range.component.mjs +188 -0
- package/esm2022/calendar/lib/calendar.schedule.selection.store.mjs +785 -0
- package/{esm2020 → esm2022}/calendar/lib/calendar.schedule.selection.store.provide.mjs +7 -7
- package/{esm2020 → esm2022}/calendar/lib/calendar.schedule.selection.toggle.button.component.mjs +6 -6
- package/esm2022/calendar/lib/field/schedule/calendar.schedule.field.component.mjs +158 -0
- package/esm2022/calendar/lib/field/schedule/calendar.schedule.field.mjs +28 -0
- package/esm2022/calendar/lib/field/schedule/calendar.schedule.module.mjs +58 -0
- package/{esm2020 → esm2022}/lib/form/action/form.action.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/form/action/form.action.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/form/action/transition/form.action.transition.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/form/action/transition/form.action.transition.safety.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/form/form.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/form/io/form.changes.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/form/io/form.input.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/form/io/form.io.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/form/io/form.loading.directive.mjs +4 -4
- package/{esm2020 → esm2022}/lib/form.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/formly/field/checklist/checklist.item.field.component.mjs +9 -9
- package/{esm2020 → esm2022}/lib/formly/field/checklist/checklist.item.field.content.default.component.mjs +6 -6
- package/esm2022/lib/formly/field/checklist/checklist.item.field.module.mjs +67 -0
- package/{esm2020 → esm2022}/lib/formly/field/component/component.field.component.mjs +6 -6
- package/esm2022/lib/formly/field/component/component.field.module.mjs +32 -0
- package/esm2022/lib/formly/field/field.mjs +97 -0
- package/{esm2020 → esm2022}/lib/formly/field/form.field.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/formly/field/selection/list/list.field.component.mjs +4 -4
- package/esm2022/lib/formly/field/selection/list/list.field.module.mjs +76 -0
- package/esm2022/lib/formly/field/selection/pickable/pickable.chip.field.component.mjs +33 -0
- package/{esm2020 → esm2022}/lib/formly/field/selection/pickable/pickable.field.directive.mjs +4 -4
- package/esm2022/lib/formly/field/selection/pickable/pickable.field.module.mjs +93 -0
- package/esm2022/lib/formly/field/selection/pickable/pickable.list.field.component.mjs +116 -0
- package/{esm2020 → esm2022}/lib/formly/field/selection/pickable/pickable.mjs +1 -1
- package/esm2022/lib/formly/field/selection/searchable/searchable.chip.field.component.mjs +68 -0
- package/esm2022/lib/formly/field/selection/searchable/searchable.field.autocomplete.item.component.mjs +95 -0
- package/esm2022/lib/formly/field/selection/searchable/searchable.field.directive.mjs +278 -0
- package/esm2022/lib/formly/field/selection/searchable/searchable.field.module.mjs +91 -0
- package/{esm2020 → esm2022}/lib/formly/field/selection/searchable/searchable.text.field.component.mjs +4 -4
- package/esm2022/lib/formly/field/selection/selection.field.mjs +39 -0
- package/{esm2020 → esm2022}/lib/formly/field/selection/selection.mjs +1 -1
- package/{esm2020 → esm2022}/lib/formly/field/selection/selection.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/formly/field/selection/sourceselect/sourceselect.field.component.mjs +4 -4
- package/esm2022/lib/formly/field/selection/sourceselect/sourceselect.field.module.mjs +93 -0
- package/{esm2020 → esm2022}/lib/formly/field/texteditor/texteditor.field.component.mjs +6 -6
- package/esm2022/lib/formly/field/texteditor/texteditor.field.module.mjs +51 -0
- package/{esm2020 → esm2022}/lib/formly/field/value/array/array.field.component.mjs +8 -8
- package/esm2022/lib/formly/field/value/array/array.field.module.mjs +62 -0
- package/esm2022/lib/formly/field/value/boolean/boolean.field.mjs +47 -0
- package/{esm2020 → esm2022}/lib/formly/field/value/boolean/boolean.field.module.mjs +5 -5
- package/esm2022/lib/formly/field/value/date/date.field.module.mjs +96 -0
- package/esm2022/lib/formly/field/value/date/datetime.field.component.mjs +488 -0
- package/esm2022/lib/formly/field/value/date/datetime.field.mjs +141 -0
- package/{esm2020 → esm2022}/lib/formly/field/value/date/datetime.field.service.mjs +9 -9
- package/esm2022/lib/formly/field/value/date/fixeddaterange.field.component.mjs +506 -0
- package/{esm2020 → esm2022}/lib/formly/field/value/number/number.field.module.mjs +5 -5
- package/esm2022/lib/formly/field/value/phone/phone.field.component.mjs +100 -0
- package/esm2022/lib/formly/field/value/phone/phone.field.module.mjs +66 -0
- package/{esm2020 → esm2022}/lib/formly/field/value/text/text.field.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/formly/field/value/value.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/formly/field/wrapper/autotouch.wrapper.component.mjs +6 -6
- package/{esm2020 → esm2022}/lib/formly/field/wrapper/expandable.wrapper.component.mjs +6 -6
- package/{esm2020 → esm2022}/lib/formly/field/wrapper/expandable.wrapper.delegate.mjs +4 -4
- package/{esm2020 → esm2022}/lib/formly/field/wrapper/flex.wrapper.component.mjs +6 -6
- package/esm2022/lib/formly/field/wrapper/form.wrapper.module.mjs +86 -0
- package/{esm2020 → esm2022}/lib/formly/field/wrapper/info.wrapper.component.mjs +7 -7
- package/esm2022/lib/formly/field/wrapper/section.wrapper.component.mjs +27 -0
- package/{esm2020 → esm2022}/lib/formly/field/wrapper/style.wrapper.component.mjs +7 -7
- package/esm2022/lib/formly/field/wrapper/subsection.wrapper.component.mjs +27 -0
- package/{esm2020 → esm2022}/lib/formly/field/wrapper/toggle.wrapper.component.mjs +6 -6
- package/{esm2020 → esm2022}/lib/formly/field/wrapper/working.wrapper.component.mjs +6 -6
- package/esm2022/lib/formly/field/wrapper/wrapper.mjs +73 -0
- package/{esm2020 → esm2022}/lib/formly/form/form.form.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/formly/form/search.form.component.mjs +6 -6
- package/{esm2020 → esm2022}/lib/formly/formly.context.directive.mjs +4 -4
- package/esm2022/lib/formly/formly.context.mjs +100 -0
- package/{esm2020 → esm2022}/lib/formly/formly.directive.mjs +16 -16
- package/{esm2020 → esm2022}/lib/formly/formly.form.component.mjs +6 -6
- package/{esm2020 → esm2022}/lib/formly/formly.module.mjs +16 -16
- package/{esm2020 → esm2022}/lib/layout/form.layout.module.mjs +5 -5
- package/{esm2020 → esm2022}/lib/layout/form.spacer.component.mjs +6 -6
- package/{esm2020 → esm2022}/mapbox/lib/field/latlng/latlng.field.component.mjs +10 -10
- package/{esm2020 → esm2022}/mapbox/lib/field/latlng/latlng.field.marker.component.mjs +6 -6
- package/esm2022/mapbox/lib/field/latlng/latlng.field.mjs +35 -0
- package/esm2022/mapbox/lib/field/latlng/latlng.module.mjs +59 -0
- package/{mapbox/esm2020 → esm2022/mapbox}/lib/field/zoom/zoom.field.component.mjs +10 -10
- package/esm2022/mapbox/lib/field/zoom/zoom.field.mjs +23 -0
- package/esm2022/mapbox/lib/field/zoom/zoom.module.mjs +57 -0
- package/{mapbox/esm2020 → esm2022/mapbox}/lib/mapbox.module.mjs +5 -5
- package/{fesm2020 → fesm2022}/dereekb-dbx-form-calendar.mjs +188 -228
- package/fesm2022/dereekb-dbx-form-calendar.mjs.map +1 -0
- package/{mapbox/fesm2020 → fesm2022}/dereekb-dbx-form-mapbox.mjs +76 -76
- package/fesm2022/dereekb-dbx-form-mapbox.mjs.map +1 -0
- package/{fesm2020 → fesm2022}/dereekb-dbx-form.mjs +820 -831
- package/fesm2022/dereekb-dbx-form.mjs.map +1 -0
- package/lib/extension/_extension.scss +11 -6
- package/lib/extension/calendar/_calendar.scss +7 -5
- package/lib/form/_form.scss +3 -2
- package/lib/form/action/form.action.directive.d.ts +2 -2
- package/lib/form/action/transition/form.action.transition.safety.directive.d.ts +1 -1
- package/lib/form/form.angular.util.d.ts +1 -1
- package/lib/form/form.d.ts +1 -1
- package/lib/form/io/form.changes.directive.d.ts +1 -1
- package/lib/form/io/form.input.directive.d.ts +2 -2
- package/lib/form/io/form.loading.directive.d.ts +1 -1
- package/lib/formly/_formly.scss +7 -9
- package/lib/formly/field/_field.scss +7 -7
- package/lib/formly/field/checklist/_checklist.scss +3 -2
- package/lib/formly/field/checklist/checklist.field.d.ts +4 -4
- package/lib/formly/field/checklist/checklist.item.d.ts +1 -1
- package/lib/formly/field/checklist/checklist.item.field.component.d.ts +2 -2
- package/lib/formly/field/checklist/checklist.item.field.content.default.component.d.ts +4 -4
- package/lib/formly/field/checklist/checklist.item.field.d.ts +1 -1
- package/lib/formly/field/component/_component.scss +3 -2
- package/lib/formly/field/component/component.field.component.d.ts +2 -2
- package/lib/formly/field/component/component.field.d.ts +1 -1
- package/lib/formly/field/field.d.ts +5 -11
- package/lib/formly/field/selection/_selection.scss +5 -5
- package/lib/formly/field/selection/list/_list.scss +3 -2
- package/lib/formly/field/selection/list/list.field.component.d.ts +1 -1
- package/lib/formly/field/selection/pickable/_pickable.scss +3 -9
- package/lib/formly/field/selection/pickable/pickable.chip.field.component.d.ts +1 -1
- package/lib/formly/field/selection/pickable/pickable.d.ts +6 -22
- package/lib/formly/field/selection/pickable/pickable.field.directive.d.ts +3 -3
- package/lib/formly/field/selection/pickable/pickable.list.field.component.d.ts +4 -4
- package/lib/formly/field/selection/pickable/pickable.util.d.ts +2 -2
- package/lib/formly/field/selection/searchable/_searchable.scss +5 -5
- package/lib/formly/field/selection/searchable/searchable.chip.field.component.d.ts +1 -1
- package/lib/formly/field/selection/searchable/searchable.d.ts +4 -4
- package/lib/formly/field/selection/searchable/searchable.field.autocomplete.item.component.d.ts +3 -3
- package/lib/formly/field/selection/searchable/searchable.field.d.ts +1 -1
- package/lib/formly/field/selection/searchable/searchable.field.directive.d.ts +1 -1
- package/lib/formly/field/selection/searchable/searchable.text.field.component.d.ts +1 -1
- package/lib/formly/field/selection/selection.d.ts +1 -5
- package/lib/formly/field/selection/selection.field.d.ts +1 -1
- package/lib/formly/field/selection/sourceselect/_sourceselect.scss +6 -15
- package/lib/formly/field/selection/sourceselect/sourceselect.d.ts +6 -6
- package/lib/formly/field/selection/sourceselect/sourceselect.field.component.d.ts +1 -1
- package/lib/formly/field/selection/sourceselect/sourceselect.field.module.d.ts +1 -1
- package/lib/formly/field/texteditor/_texteditor.scss +3 -2
- package/lib/formly/field/texteditor/texteditor.field.component.d.ts +2 -2
- package/lib/formly/field/value/_value.scss +10 -6
- package/lib/formly/field/value/array/_array.scss +7 -2
- package/lib/formly/field/value/array/array.field.component.d.ts +2 -2
- package/lib/formly/field/value/boolean/_boolean.scss +5 -4
- package/lib/formly/field/value/date/_date.scss +20 -37
- package/lib/formly/field/value/date/date.field.module.d.ts +1 -1
- package/lib/formly/field/value/date/datetime.field.component.d.ts +3 -13
- package/lib/formly/field/value/date/datetime.field.d.ts +5 -5
- package/lib/formly/field/value/date/fixeddaterange.field.component.d.ts +7 -7
- package/lib/formly/field/value/hidden.field.d.ts +1 -1
- package/lib/formly/field/value/number/_number.scss +35 -0
- package/lib/formly/field/value/number/number.field.d.ts +3 -3
- package/lib/formly/field/value/phone/_phone.scss +4 -3
- package/lib/formly/field/value/phone/phone.field.component.d.ts +1 -1
- package/lib/formly/field/value/phone/phone.field.module.d.ts +1 -1
- package/lib/formly/field/value/text/_text.scss +3 -2
- package/lib/formly/field/value/text/text.additional.field.d.ts +3 -3
- package/lib/formly/field/value/text/text.field.d.ts +2 -2
- package/lib/formly/field/wrapper/_wrapper.scss +5 -4
- package/lib/formly/field/wrapper/autotouch.wrapper.component.d.ts +1 -1
- package/lib/formly/field/wrapper/expandable.wrapper.component.d.ts +2 -2
- package/lib/formly/field/wrapper/expandable.wrapper.delegate.d.ts +1 -1
- package/lib/formly/field/wrapper/flex.wrapper.component.d.ts +1 -1
- package/lib/formly/field/wrapper/form.wrapper.module.d.ts +1 -1
- package/lib/formly/field/wrapper/info.wrapper.component.d.ts +1 -1
- package/lib/formly/field/wrapper/section.wrapper.component.d.ts +2 -2
- package/lib/formly/field/wrapper/style.wrapper.component.d.ts +2 -2
- package/lib/formly/field/wrapper/subsection.wrapper.component.d.ts +2 -2
- package/lib/formly/field/wrapper/toggle.wrapper.component.d.ts +1 -1
- package/lib/formly/field/wrapper/working.wrapper.component.d.ts +2 -2
- package/lib/formly/field/wrapper/wrapper.d.ts +1 -1
- package/lib/formly/form/_form.scss +17 -4
- package/lib/formly/form/search.form.component.d.ts +1 -1
- package/lib/formly/formly.context.directive.d.ts +1 -1
- package/lib/formly/formly.directive.d.ts +4 -4
- package/lib/formly/formly.form.component.d.ts +1 -1
- package/lib/formly/template/login.d.ts +1 -1
- package/lib/formly/template/timezone.d.ts +1 -1
- package/lib/layout/_layout.scss +3 -2
- package/lib/layout/form.spacer.component.d.ts +1 -1
- package/lib/style/_all-typography.scss +11 -3
- package/lib/style/_core.scss +1 -2
- package/lib/style/_mixin.scss +10 -0
- package/lib/style/_theming.scss +1 -1
- package/lib/validator/available.d.ts +1 -1
- package/mapbox/{esm2020 → esm2022}/lib/field/latlng/latlng.field.component.mjs +10 -10
- package/mapbox/{esm2020 → esm2022}/lib/field/latlng/latlng.field.marker.component.mjs +6 -6
- package/mapbox/esm2022/lib/field/latlng/latlng.field.mjs +35 -0
- package/mapbox/esm2022/lib/field/latlng/latlng.module.mjs +59 -0
- package/{esm2020/mapbox → mapbox/esm2022}/lib/field/zoom/zoom.field.component.mjs +10 -10
- package/mapbox/esm2022/lib/field/zoom/zoom.field.mjs +23 -0
- package/mapbox/esm2022/lib/field/zoom/zoom.module.mjs +57 -0
- package/{esm2020/mapbox → mapbox/esm2022}/lib/mapbox.module.mjs +5 -5
- package/{fesm2020 → mapbox/fesm2022}/dereekb-dbx-form-mapbox.mjs +76 -76
- package/mapbox/fesm2022/dereekb-dbx-form-mapbox.mjs.map +1 -0
- package/mapbox/lib/field/latlng/latlng.field.component.d.ts +1 -1
- package/mapbox/lib/field/latlng/latlng.field.marker.component.d.ts +1 -1
- package/mapbox/lib/field/zoom/zoom.field.component.d.ts +1 -1
- package/mapbox/package.json +10 -28
- package/package.json +31 -31
- package/esm2020/calendar/lib/calendar.module.mjs +0 -155
- package/esm2020/calendar/lib/calendar.schedule.selection.dialog.button.component.mjs +0 -38
- package/esm2020/calendar/lib/calendar.schedule.selection.dialog.component.mjs +0 -65
- package/esm2020/calendar/lib/calendar.schedule.selection.popover.component.mjs +0 -37
- package/esm2020/calendar/lib/calendar.schedule.selection.range.component.mjs +0 -188
- package/esm2020/calendar/lib/calendar.schedule.selection.store.mjs +0 -814
- package/esm2020/calendar/lib/field/schedule/calendar.schedule.field.component.mjs +0 -158
- package/esm2020/calendar/lib/field/schedule/calendar.schedule.field.mjs +0 -29
- package/esm2020/calendar/lib/field/schedule/calendar.schedule.module.mjs +0 -58
- package/esm2020/lib/formly/field/checklist/checklist.item.field.module.mjs +0 -67
- package/esm2020/lib/formly/field/component/component.field.module.mjs +0 -32
- package/esm2020/lib/formly/field/field.mjs +0 -103
- package/esm2020/lib/formly/field/selection/list/list.field.module.mjs +0 -76
- package/esm2020/lib/formly/field/selection/pickable/pickable.chip.field.component.mjs +0 -33
- package/esm2020/lib/formly/field/selection/pickable/pickable.field.module.mjs +0 -93
- package/esm2020/lib/formly/field/selection/pickable/pickable.list.field.component.mjs +0 -116
- package/esm2020/lib/formly/field/selection/searchable/searchable.chip.field.component.mjs +0 -68
- package/esm2020/lib/formly/field/selection/searchable/searchable.field.autocomplete.item.component.mjs +0 -95
- package/esm2020/lib/formly/field/selection/searchable/searchable.field.directive.mjs +0 -278
- package/esm2020/lib/formly/field/selection/searchable/searchable.field.module.mjs +0 -91
- package/esm2020/lib/formly/field/selection/selection.field.mjs +0 -39
- package/esm2020/lib/formly/field/selection/sourceselect/sourceselect.field.module.mjs +0 -93
- package/esm2020/lib/formly/field/texteditor/texteditor.field.module.mjs +0 -51
- package/esm2020/lib/formly/field/value/array/array.field.module.mjs +0 -62
- package/esm2020/lib/formly/field/value/boolean/boolean.field.mjs +0 -47
- package/esm2020/lib/formly/field/value/date/date.field.module.mjs +0 -96
- package/esm2020/lib/formly/field/value/date/datetime.field.component.mjs +0 -488
- package/esm2020/lib/formly/field/value/date/datetime.field.mjs +0 -143
- package/esm2020/lib/formly/field/value/date/fixeddaterange.field.component.mjs +0 -506
- package/esm2020/lib/formly/field/value/phone/phone.field.component.mjs +0 -100
- package/esm2020/lib/formly/field/value/phone/phone.field.module.mjs +0 -66
- package/esm2020/lib/formly/field/wrapper/form.wrapper.module.mjs +0 -86
- package/esm2020/lib/formly/field/wrapper/section.wrapper.component.mjs +0 -26
- package/esm2020/lib/formly/field/wrapper/subsection.wrapper.component.mjs +0 -26
- package/esm2020/lib/formly/field/wrapper/wrapper.mjs +0 -78
- package/esm2020/lib/formly/formly.context.mjs +0 -100
- package/esm2020/mapbox/lib/field/latlng/latlng.field.mjs +0 -35
- package/esm2020/mapbox/lib/field/latlng/latlng.module.mjs +0 -59
- package/esm2020/mapbox/lib/field/zoom/zoom.field.mjs +0 -23
- package/esm2020/mapbox/lib/field/zoom/zoom.module.mjs +0 -57
- package/fesm2015/dereekb-dbx-form-calendar.mjs +0 -1955
- package/fesm2015/dereekb-dbx-form-calendar.mjs.map +0 -1
- package/fesm2015/dereekb-dbx-form-mapbox.mjs +0 -585
- package/fesm2015/dereekb-dbx-form-mapbox.mjs.map +0 -1
- package/fesm2015/dereekb-dbx-form.mjs +0 -6205
- package/fesm2015/dereekb-dbx-form.mjs.map +0 -1
- package/fesm2020/dereekb-dbx-form-calendar.mjs.map +0 -1
- package/fesm2020/dereekb-dbx-form-mapbox.mjs.map +0 -1
- package/fesm2020/dereekb-dbx-form.mjs.map +0 -1
- package/mapbox/esm2020/lib/field/latlng/latlng.field.mjs +0 -35
- package/mapbox/esm2020/lib/field/latlng/latlng.module.mjs +0 -59
- package/mapbox/esm2020/lib/field/zoom/zoom.field.mjs +0 -23
- package/mapbox/esm2020/lib/field/zoom/zoom.module.mjs +0 -57
- package/mapbox/fesm2015/dereekb-dbx-form-mapbox.mjs +0 -585
- package/mapbox/fesm2015/dereekb-dbx-form-mapbox.mjs.map +0 -1
- package/mapbox/fesm2020/dereekb-dbx-form-mapbox.mjs.map +0 -1
- /package/{esm2020 → esm2022}/calendar/dereekb-dbx-form-calendar.mjs +0 -0
- /package/{esm2020 → esm2022}/calendar/index.mjs +0 -0
- /package/{esm2020 → esm2022}/calendar/lib/calendar.schedule.selection.form.mjs +0 -0
- /package/{esm2020 → esm2022}/calendar/lib/field/index.mjs +0 -0
- /package/{esm2020 → esm2022}/calendar/lib/field/schedule/index.mjs +0 -0
- /package/{esm2020 → esm2022}/calendar/lib/index.mjs +0 -0
- /package/{esm2020 → esm2022}/dereekb-dbx-form.mjs +0 -0
- /package/{esm2020 → esm2022}/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/form/action/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/form/action/transition/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/form/form.angular.util.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/form/form.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/form/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/form/io/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/config/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/config/validation.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/checklist/checklist.field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/checklist/checklist.item.field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/checklist/checklist.item.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/checklist/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/component/component.field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/component/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/selection/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/selection/list/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/selection/list/list.field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/selection/pickable/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/selection/pickable/pickable.field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/selection/pickable/pickable.util.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/selection/searchable/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/selection/searchable/searchable.field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/selection/searchable/searchable.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/selection/searchable/text.chip.field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/selection/sourceselect/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/selection/sourceselect/sourceselect.field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/selection/sourceselect/sourceselect.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/texteditor/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/texteditor/texteditor.field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/array/array.field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/array/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/boolean/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/date/date.value.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/date/datetime.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/date/datetime.preset.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/date/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/hidden.field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/number/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/number/number.field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/phone/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/phone/phone.field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/text/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/text/text.additional.field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/text/text.address.field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/value/text/text.field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/field/wrapper/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/form/form.form.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/form/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/template/available.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/template/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/template/login.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/formly/template/timezone.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/layout/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/validator/available.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/validator/boolean.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/validator/email.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/validator/field.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/validator/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/validator/number.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/validator/phone.mjs +0 -0
- /package/{esm2020 → esm2022}/mapbox/dereekb-dbx-form-mapbox.mjs +0 -0
- /package/{esm2020 → esm2022}/mapbox/index.mjs +0 -0
- /package/{esm2020 → esm2022}/mapbox/lib/field/index.mjs +0 -0
- /package/{esm2020 → esm2022}/mapbox/lib/field/latlng/index.mjs +0 -0
- /package/{esm2020 → esm2022}/mapbox/lib/field/zoom/index.mjs +0 -0
- /package/mapbox/{esm2020 → esm2022}/dereekb-dbx-form-mapbox.mjs +0 -0
- /package/mapbox/{esm2020 → esm2022}/index.mjs +0 -0
- /package/mapbox/{esm2020 → esm2022}/lib/field/index.mjs +0 -0
- /package/mapbox/{esm2020 → esm2022}/lib/field/latlng/index.mjs +0 -0
- /package/mapbox/{esm2020 → esm2022}/lib/field/zoom/index.mjs +0 -0
|
@@ -1,814 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@angular/core';
|
|
2
|
-
import { dateCellDayOfWeekFactory, dateCellTimingDateFactory, dateCellScheduleDateFilter, copyDateCellScheduleDateFilterConfig, DateCellScheduleDayCode, dateCellScheduleEncodedWeek, dateCellTimingRelativeIndexFactory, expandDateCellScheduleDayCodes, expandDateCellScheduleDayCodesToDayOfWeekSet, findMaxDate, findMinDate, isDateInDateRangeFunction, isDateWithinDateCellRangeFunction, isSameDate, isSameDateDay, isSameDateRange, dateCellTimingRelativeIndexArrayFactory, isInfiniteDateRange, dateTimezoneUtcNormal, expandDateCellScheduleRange, formatToISO8601DayString, dateCellScheduleDayCodesAreSetsEquivalent, simplifyDateCellScheduleDayCodes, fullWeekDateCellScheduleDayCodes, dateCellTimingStartDateFactory, dateCellTimingStartsAtForStartOfDay, isSameDateCellScheduleDateRange, fullDateCellScheduleRange, dateCellTimingTimezoneNormalInstance, changeDateCellScheduleDateRangeToTimezone, SYSTEM_DATE_TIMEZONE_UTC_NORMAL_INSTANCE } from '@dereekb/date';
|
|
3
|
-
import { distinctUntilHasDifferentValues, filterMaybe } from '@dereekb/rxjs';
|
|
4
|
-
import { iterableToArray, addToSet, toggleInSet, isIndexNumberInIndexRangeFunction, minAndMaxNumber, range, unique, mergeArrays, mapValuesToSet, isInAllowedDaysOfWeekSet, firstValueFromIterable, isIterable, removeFromSet } from '@dereekb/util';
|
|
5
|
-
import { ComponentStore } from '@ngrx/component-store';
|
|
6
|
-
import { startOfDay, endOfDay, isBefore } from 'date-fns';
|
|
7
|
-
import { distinctUntilChanged, map, shareReplay, switchMap, tap, first, combineLatestWith, of } from 'rxjs';
|
|
8
|
-
import { defaultCalendarScheduleSelectionCellContentFactory } from './calendar.schedule.selection';
|
|
9
|
-
import * as i0 from "@angular/core";
|
|
10
|
-
export function initialCalendarScheduleSelectionState() {
|
|
11
|
-
const defaultScheduleDays = new Set([DateCellScheduleDayCode.WEEKDAY, DateCellScheduleDayCode.WEEKEND]);
|
|
12
|
-
const allowedDaysOfWeek = expandDateCellScheduleDayCodesToDayOfWeekSet(defaultScheduleDays);
|
|
13
|
-
const defaultStartsAt = dateCellTimingStartsAtForStartOfDay(); // get midnight of the current timezone
|
|
14
|
-
const { startsAt, timezone: systemTimezone } = defaultStartsAt;
|
|
15
|
-
const indexFactory = dateCellTimingRelativeIndexFactory(defaultStartsAt);
|
|
16
|
-
const indexDayOfWeek = dateCellDayOfWeekFactory(startsAt);
|
|
17
|
-
return {
|
|
18
|
-
selectionMode: 'multiple',
|
|
19
|
-
start: startsAt,
|
|
20
|
-
systemTimezone,
|
|
21
|
-
indexFactory,
|
|
22
|
-
toggledIndexes: new Set(),
|
|
23
|
-
defaultScheduleDays,
|
|
24
|
-
effectiveScheduleDays: defaultScheduleDays,
|
|
25
|
-
allowedDaysOfWeek,
|
|
26
|
-
indexDayOfWeek,
|
|
27
|
-
isEnabledFilterDay: () => true,
|
|
28
|
-
isEnabledDay: () => false,
|
|
29
|
-
computeSelectionResultRelativeToFilter: true,
|
|
30
|
-
cellContentFactory: defaultCalendarScheduleSelectionCellContentFactory
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* This is used in cases where the dates in the min/max date range need to be shifted to the filter's timezone.
|
|
35
|
-
*
|
|
36
|
-
* This is because the index factory is always in system timezone, but when selecting all/none with a filter we need to use the filter's timezone.
|
|
37
|
-
*
|
|
38
|
-
* @param x
|
|
39
|
-
* @returns
|
|
40
|
-
*/
|
|
41
|
-
function calendarScheduleMinAndMaxDateRangeRelativeToFilter(x) {
|
|
42
|
-
let input = x;
|
|
43
|
-
if (x.filter?.timezone && x.minMaxDateRange != null) {
|
|
44
|
-
const filterNormal = dateTimezoneUtcNormal(x.filter.timezone);
|
|
45
|
-
const transformFn = filterNormal.transformFunction('systemDateToTargetDate');
|
|
46
|
-
input = {
|
|
47
|
-
filter: x.filter,
|
|
48
|
-
minMaxDateRange: {
|
|
49
|
-
start: x.minMaxDateRange.start ? transformFn(x.minMaxDateRange.start) : undefined,
|
|
50
|
-
end: x.minMaxDateRange.end ? transformFn(x.minMaxDateRange.end) : undefined
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
return calendarScheduleMinAndMaxDateRange(input);
|
|
55
|
-
}
|
|
56
|
-
export function calendarScheduleMinAndMaxDateRange(x) {
|
|
57
|
-
return {
|
|
58
|
-
start: calendarScheduleMinDate(x) || undefined,
|
|
59
|
-
end: calendarScheduleMaxDate(x) || undefined
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
export function calendarScheduleMinDate(x) {
|
|
63
|
-
return findMaxDate([x.filter?.start, x.minMaxDateRange?.start]);
|
|
64
|
-
}
|
|
65
|
-
export function calendarScheduleMaxDate(x) {
|
|
66
|
-
return findMinDate([x.filter?.end, x.minMaxDateRange?.end]);
|
|
67
|
-
}
|
|
68
|
-
export function calendarScheduleStartBeingUsedFromFilter(x) {
|
|
69
|
-
return x.computeSelectionResultRelativeToFilter && x.filter?.start != null; // may be using either
|
|
70
|
-
}
|
|
71
|
-
export class DbxCalendarScheduleSelectionStore extends ComponentStore {
|
|
72
|
-
constructor() {
|
|
73
|
-
super(initialCalendarScheduleSelectionState());
|
|
74
|
-
// MARK:
|
|
75
|
-
this.toggleSelection = this.effect((input) => {
|
|
76
|
-
return input.pipe(switchMap(() => this.nextToggleSelection$.pipe(first(), filterMaybe(), tap((x) => {
|
|
77
|
-
this.selectAllDates(x);
|
|
78
|
-
}))));
|
|
79
|
-
});
|
|
80
|
-
// MARK: Accessors
|
|
81
|
-
this.selectionMode$ = this.state$.pipe(map((x) => x.selectionMode), distinctUntilChanged(), shareReplay(1));
|
|
82
|
-
this.filter$ = this.state$.pipe(map((x) => x.filter), distinctUntilChanged(), shareReplay(1));
|
|
83
|
-
this.minMaxDateRange$ = this.state$.pipe(map(calendarScheduleMinAndMaxDateRange), distinctUntilChanged(isSameDateRange), shareReplay(1));
|
|
84
|
-
this.minDate$ = this.minMaxDateRange$.pipe(map((x) => x?.start), distinctUntilChanged(isSameDateDay), shareReplay(1));
|
|
85
|
-
this.maxDate$ = this.minMaxDateRange$.pipe(map((x) => x?.end), distinctUntilChanged(isSameDateDay), shareReplay(1));
|
|
86
|
-
this.hasConfiguredMinMaxRange$ = this.minMaxDateRange$.pipe(map((x) => x != null && x.start != null && x.end != null), distinctUntilChanged(), shareReplay(1));
|
|
87
|
-
this.inputStart$ = this.state$.pipe(map((x) => x.inputStart), distinctUntilChanged(isSameDate), shareReplay(1));
|
|
88
|
-
this.inputEnd$ = this.state$.pipe(map((x) => x.inputEnd), distinctUntilChanged(isSameDate), shareReplay(1));
|
|
89
|
-
this.currentInputRange$ = this.state$.pipe(map(({ inputStart, inputEnd }) => ({ start: inputStart, end: inputEnd })), distinctUntilChanged((a, b) => isSameDateRange(a, b)), map((x) => ({ inputStart: x.start, inputEnd: x.end })), map((x) => {
|
|
90
|
-
if (x.inputStart && x.inputEnd) {
|
|
91
|
-
return x;
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
return undefined;
|
|
95
|
-
}
|
|
96
|
-
}), shareReplay(1));
|
|
97
|
-
this.inputRange$ = this.currentInputRange$.pipe(filterMaybe(), shareReplay(1));
|
|
98
|
-
/**
|
|
99
|
-
* @deprecated This is not the same as the current selection value. This is the set of manually togged off dates. It will be removed in a future update.
|
|
100
|
-
*/
|
|
101
|
-
this.selectedDates$ = this.state$.pipe(map((x) => x.toggledIndexes), distinctUntilChanged(), shareReplay(1));
|
|
102
|
-
this.isEnabledFilterDayFunction$ = this.state$.pipe(map((x) => x.isEnabledFilterDay), distinctUntilChanged(), shareReplay(1));
|
|
103
|
-
this.isEnabledDayFunction$ = this.state$.pipe(map((x) => x.isEnabledDay), distinctUntilChanged(), shareReplay(1));
|
|
104
|
-
this.currentDateRange$ = this.state$.pipe(map(computeCalendarScheduleSelectionRange), distinctUntilChanged((a, b) => isSameDateRange(a, b)), shareReplay(1));
|
|
105
|
-
this.computeSelectionResultRelativeToFilter$ = this.state$.pipe(map((x) => x.computeSelectionResultRelativeToFilter), shareReplay(1));
|
|
106
|
-
this.startBeingUsedFromFilter$ = this.state$.pipe(
|
|
107
|
-
//
|
|
108
|
-
map(calendarScheduleStartBeingUsedFromFilter), distinctUntilChanged(), shareReplay(1));
|
|
109
|
-
this.dateRange$ = this.currentDateRange$.pipe(filterMaybe(), shareReplay(1));
|
|
110
|
-
this.allowedDaysOfWeek$ = this.state$.pipe(map((x) => x.allowedDaysOfWeek), distinctUntilHasDifferentValues(), shareReplay(1));
|
|
111
|
-
this.isInAllowedDaysOfWeekFunction$ = this.allowedDaysOfWeek$.pipe(map((x) => isInAllowedDaysOfWeekSet(x)), shareReplay(1));
|
|
112
|
-
this.scheduleDays$ = this.state$.pipe(map((x) => x.effectiveScheduleDays), distinctUntilHasDifferentValues(), shareReplay(1));
|
|
113
|
-
this.outputTimezone$ = this.state$.pipe(map((x) => x.outputTimezone), distinctUntilChanged(), shareReplay(1));
|
|
114
|
-
/**
|
|
115
|
-
* The timezone of the output values.
|
|
116
|
-
*
|
|
117
|
-
* If an outputTimezone is not specified, this defaults to the system timezone.
|
|
118
|
-
*/
|
|
119
|
-
this.effectiveOutputTimezone$ = this.state$.pipe(map((x) => x.outputTimezone || x.systemTimezone), distinctUntilChanged(), shareReplay(1));
|
|
120
|
-
/**
|
|
121
|
-
* An outputTimezoneNormal to use.
|
|
122
|
-
*
|
|
123
|
-
* If an outputTimezone is not specified, this is undefined.
|
|
124
|
-
*/
|
|
125
|
-
this.effectiveOutputTimezoneNormal$ = this.state$.pipe(map((x) => (x.outputTimezoneNormal ? x.outputTimezoneNormal : undefined)), distinctUntilChanged(), shareReplay(1));
|
|
126
|
-
this.currentSelectionValue$ = this.state$.pipe(map((x) => x.currentSelectionValue), distinctUntilChanged(), shareReplay(1));
|
|
127
|
-
this.currentSelectionValueStart$ = this.currentSelectionValue$.pipe(map((x) => x?.dateScheduleRange.start), distinctUntilChanged(isSameDate), shareReplay(1));
|
|
128
|
-
this.currentSelectionValueDateCellTimingDateFactory$ = this.currentSelectionValue$.pipe(map((x) => (x ? dateCellTimingDateFactory({ startsAt: x.dateScheduleRange.start, timezone: x.dateScheduleRange.timezone }) : undefined)), shareReplay(1));
|
|
129
|
-
this.currentSelectionValueDateCellDurationSpanExpansion$ = this.currentSelectionValue$.pipe(map((x) => (x ? expandDateCellScheduleRange({ dateCellScheduleRange: x.dateScheduleRange }) : [])), shareReplay(1));
|
|
130
|
-
this.selectionValueSelectedIndexes$ = this.currentSelectionValueDateCellDurationSpanExpansion$.pipe(map((x) => new Set(x.map((y) => y.i))), distinctUntilHasDifferentValues(), shareReplay(1));
|
|
131
|
-
this.selectionValueSelectedDates$ = this.currentSelectionValueDateCellTimingDateFactory$.pipe(switchMap((dateFactory) => {
|
|
132
|
-
return dateFactory ? this.selectionValueSelectedIndexes$.pipe(map((x) => mapValuesToSet(x, (y) => formatToISO8601DayString(dateFactory(y))))) : of(new Set());
|
|
133
|
-
}), shareReplay(1));
|
|
134
|
-
this.selectionValue$ = this.currentSelectionValue$.pipe(filterMaybe(), shareReplay(1));
|
|
135
|
-
this.currentSelectionValueWithTimezone$ = this.currentSelectionValue$.pipe(combineLatestWith(this.effectiveOutputTimezoneNormal$), map(([x, timezoneNormal]) => {
|
|
136
|
-
let currentValueWithTimezone = x;
|
|
137
|
-
if (x && timezoneNormal) {
|
|
138
|
-
currentValueWithTimezone = {
|
|
139
|
-
dateScheduleRange: changeDateCellScheduleDateRangeToTimezone(x.dateScheduleRange, timezoneNormal),
|
|
140
|
-
minMaxRange: x.minMaxRange
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
return currentValueWithTimezone;
|
|
144
|
-
}), distinctUntilChanged(), shareReplay(1));
|
|
145
|
-
this.selectionValueWithTimezone$ = this.currentSelectionValueWithTimezone$.pipe(filterMaybe(), shareReplay(1));
|
|
146
|
-
this.selectionValueWithTimezoneDateCellDurationSpanExpansion$ = this.selectionValueWithTimezone$.pipe(map((x) => expandDateCellScheduleRange({ dateCellScheduleRange: x.dateScheduleRange })), shareReplay(1));
|
|
147
|
-
this.nextToggleSelection$ = this.hasConfiguredMinMaxRange$.pipe(switchMap((hasConfiguredMinMaxRange) => {
|
|
148
|
-
let obs;
|
|
149
|
-
if (hasConfiguredMinMaxRange) {
|
|
150
|
-
obs = this.currentSelectionValue$.pipe(map((x) => (x ? 'none' : 'all')));
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
obs = this.currentSelectionValue$.pipe(map((x) => (x ? 'none' : undefined)));
|
|
154
|
-
}
|
|
155
|
-
return obs;
|
|
156
|
-
}), shareReplay(1));
|
|
157
|
-
this.currentDateCellScheduleRangeValue$ = this.currentSelectionValueWithTimezone$.pipe(map((x) => x?.dateScheduleRange), distinctUntilChanged(isSameDateCellScheduleDateRange), shareReplay(1));
|
|
158
|
-
this.dateCellScheduleRangeValue$ = this.currentDateCellScheduleRangeValue$.pipe(filterMaybe(), shareReplay(1));
|
|
159
|
-
this.cellContentFactory$ = this.state$.pipe(map((x) => x.cellContentFactory), distinctUntilChanged(), shareReplay(1));
|
|
160
|
-
this.isCustomized$ = this.state$.pipe(map((x) => x.toggledIndexes.size > 0), distinctUntilChanged(), shareReplay(1));
|
|
161
|
-
this.isViewReadonly$ = this.state$.pipe(map((x) => x.isViewReadonly), distinctUntilChanged(), shareReplay(1));
|
|
162
|
-
// MARK: State Changes
|
|
163
|
-
this.setMinMaxDateRange = this.updater(updateStateWithMinMaxDateRange);
|
|
164
|
-
this.setDefaultWeek = this.updater(updateStateWithMinMaxDateRange);
|
|
165
|
-
this.setFilter = this.updater(updateStateWithFilter);
|
|
166
|
-
this.setExclusions = this.updater(updateStateWithExclusions);
|
|
167
|
-
this.setComputeSelectionResultRelativeToFilter = this.updater(updateStateWithComputeSelectionResultRelativeToFilter);
|
|
168
|
-
this.clearFilter = this.updater((state) => updateStateWithFilter(state, undefined));
|
|
169
|
-
this.setOutputTimezone = this.updater(updateStateWithTimezoneValue);
|
|
170
|
-
/**
|
|
171
|
-
* Sets the "input" date range. This is the range that gets displayed on the date range picker.
|
|
172
|
-
*/
|
|
173
|
-
this.setInputRange = this.updater(updateStateWithChangedRange);
|
|
174
|
-
// NOTE: Selected dates are NOT selected indexes. They are the internal selected dates that are excluded from the selection.
|
|
175
|
-
this.toggleSelectedDates = this.updater((state, toggle) => updateStateWithChangedDates(state, { toggle }));
|
|
176
|
-
this.addSelectedDates = this.updater((state, add) => updateStateWithChangedDates(state, { add }));
|
|
177
|
-
this.removeSelectedDates = this.updater((state, remove) => updateStateWithChangedDates(state, { remove }));
|
|
178
|
-
this.setSelectedDates = this.updater((state, set) => updateStateWithChangedDates(state, { set }));
|
|
179
|
-
this.selectAllDates = this.updater((state, selectAll = 'all') => updateStateWithChangedDates(state, { selectAll }));
|
|
180
|
-
// NOTE: Selected indexes are the typical/expected indexes that are selected or not.
|
|
181
|
-
this.setSelectedIndexes = this.updater((state, set) => updateStateWithChangedDates(state, { set, invertSetBehavior: true }));
|
|
182
|
-
this.setInitialSelectionState = this.updater(updateStateWithInitialSelectionState);
|
|
183
|
-
this.setDefaultScheduleDays = this.updater(updateStateWithChangedDefaultScheduleDays);
|
|
184
|
-
this.setScheduleDays = this.updater(updateStateWithChangedScheduleDays);
|
|
185
|
-
this.setAllowAllScheduleDays = this.updater((state) => updateStateWithChangedScheduleDays(state, [DateCellScheduleDayCode.WEEKDAY, DateCellScheduleDayCode.WEEKEND]));
|
|
186
|
-
this.setDateScheduleRangeValue = this.updater((state, value) => updateStateWithDateCellScheduleRangeValue(state, value));
|
|
187
|
-
this.setCellContentFactory = this.updater((state, cellContentFactory) => ({ ...state, cellContentFactory }));
|
|
188
|
-
/**
|
|
189
|
-
* Sets the selection mode.
|
|
190
|
-
*/
|
|
191
|
-
this.setSelectionMode = this.updater(updateStateWithSelectionMode);
|
|
192
|
-
/**
|
|
193
|
-
* Used by the parent view to propogate a readonly state.
|
|
194
|
-
*
|
|
195
|
-
* Should typically not be used by the user directly with the intention of the parent synchronizing to this state.
|
|
196
|
-
*/
|
|
197
|
-
this.setViewReadonlyState = this.updater((state, isViewReadonly) => ({ ...state, isViewReadonly }));
|
|
198
|
-
// MARK: Compat
|
|
199
|
-
/**
|
|
200
|
-
* @deprecated use setOutputTimezone instead.
|
|
201
|
-
*/
|
|
202
|
-
this.setTimezone = this.setOutputTimezone;
|
|
203
|
-
/**
|
|
204
|
-
* @deprecated use ouputTimezone$
|
|
205
|
-
*/
|
|
206
|
-
this.currentTimezone$ = this.outputTimezone$;
|
|
207
|
-
/**
|
|
208
|
-
* @deprecated use effectiveOuputTimezone$
|
|
209
|
-
*/
|
|
210
|
-
this.effectiveTimezone$ = this.effectiveOutputTimezone$;
|
|
211
|
-
/**
|
|
212
|
-
* @deprecated use effectiveOuputTimezoneNormal$
|
|
213
|
-
*/
|
|
214
|
-
this.effectiveTimezoneNormal$ = this.effectiveOutputTimezoneNormal$;
|
|
215
|
-
/**
|
|
216
|
-
* @deprecated use currentSelectionValueDateCellDurationSpanExpansion$
|
|
217
|
-
*/
|
|
218
|
-
this.currentSelectionValueDateBlockDurationSpan$ = this.currentSelectionValueDateCellDurationSpanExpansion$;
|
|
219
|
-
/**
|
|
220
|
-
* @deprecated use selectionValueWithTimezoneDateCellDurationSpanExpansion$
|
|
221
|
-
*/
|
|
222
|
-
this.selectionValueWithTimezoneDateBlockDurationSpan$ = this.selectionValueWithTimezoneDateCellDurationSpanExpansion$;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
DbxCalendarScheduleSelectionStore.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: DbxCalendarScheduleSelectionStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
226
|
-
DbxCalendarScheduleSelectionStore.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: DbxCalendarScheduleSelectionStore });
|
|
227
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: DbxCalendarScheduleSelectionStore, decorators: [{
|
|
228
|
-
type: Injectable
|
|
229
|
-
}], ctorParameters: function () { return []; } });
|
|
230
|
-
export function updateStateWithInitialSelectionState(state, initialSelectionState) {
|
|
231
|
-
const { toggledIndexes } = state;
|
|
232
|
-
if (toggledIndexes.size === 0 && initialSelectionState === 'all') {
|
|
233
|
-
state = updateStateWithChangedDates(state, { selectAll: initialSelectionState });
|
|
234
|
-
}
|
|
235
|
-
return { ...state, initialSelectionState };
|
|
236
|
-
}
|
|
237
|
-
export function updateStateWithComputeSelectionResultRelativeToFilter(currentState, computeSelectionResultRelativeToFilter) {
|
|
238
|
-
let state = { ...currentState, computeSelectionResultRelativeToFilter };
|
|
239
|
-
if (Boolean(currentState.computeSelectionResultRelativeToFilter) !== Boolean(computeSelectionResultRelativeToFilter)) {
|
|
240
|
-
state = updateStateWithChangedDates(state, {}); // recalculate if change occurs as it will affect the output value
|
|
241
|
-
}
|
|
242
|
-
return state;
|
|
243
|
-
}
|
|
244
|
-
export function updateStateWithExclusions(state, inputExclusions) {
|
|
245
|
-
let computedExclusions;
|
|
246
|
-
if (inputExclusions) {
|
|
247
|
-
const { indexFactory } = state;
|
|
248
|
-
const indexArrayFactory = dateCellTimingRelativeIndexArrayFactory(indexFactory);
|
|
249
|
-
computedExclusions = indexArrayFactory(inputExclusions);
|
|
250
|
-
}
|
|
251
|
-
state = { ...state, inputExclusions, computedExclusions };
|
|
252
|
-
return updateStateWithFilter(state, state.filter);
|
|
253
|
-
}
|
|
254
|
-
export function updateStateWithMinMaxDateRange(state, minMaxDateRange) {
|
|
255
|
-
if (minMaxDateRange != null && !isInfiniteDateRange(minMaxDateRange)) {
|
|
256
|
-
state = {
|
|
257
|
-
...state,
|
|
258
|
-
minMaxDateRange: {
|
|
259
|
-
start: minMaxDateRange.start != null ? startOfDay(minMaxDateRange.start) : undefined,
|
|
260
|
-
end: minMaxDateRange.end != null ? endOfDay(minMaxDateRange.end) : undefined
|
|
261
|
-
}
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
else {
|
|
265
|
-
state = { ...state, minMaxDateRange: undefined };
|
|
266
|
-
}
|
|
267
|
-
return updateStateWithFilter(state, state.filter);
|
|
268
|
-
}
|
|
269
|
-
export function updateStateWithFilter(currentState, inputFilter) {
|
|
270
|
-
const { computedExclusions: exclusions, minMaxDateRange, systemTimezone } = currentState;
|
|
271
|
-
let isEnabledFilterDay = () => true;
|
|
272
|
-
let filter = null;
|
|
273
|
-
// create the filter using inputFilter, exclusions, and minMaxDateRange
|
|
274
|
-
if (inputFilter || exclusions?.length || minMaxDateRange) {
|
|
275
|
-
let enabledFilter;
|
|
276
|
-
let filterStart = null; // the start date that will be used/set on the filter.
|
|
277
|
-
if (inputFilter) {
|
|
278
|
-
filter = copyDateCellScheduleDateFilterConfig(inputFilter); // copy filter
|
|
279
|
-
let nextFilterTimezone; // only set if inputFilter.start or inputFilter.startsAt
|
|
280
|
-
// configure filter start
|
|
281
|
-
if (inputFilter.start) {
|
|
282
|
-
filterStart = inputFilter.start;
|
|
283
|
-
// if no timezone is specified, then use the system timezone and align filterStart to the start of the day.
|
|
284
|
-
if (!inputFilter.timezone) {
|
|
285
|
-
filterStart = SYSTEM_DATE_TIMEZONE_UTC_NORMAL_INSTANCE.startOfDayInTargetTimezone(inputFilter.startsAt);
|
|
286
|
-
nextFilterTimezone = systemTimezone;
|
|
287
|
-
}
|
|
288
|
-
else {
|
|
289
|
-
nextFilterTimezone = inputFilter.timezone;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
else if (inputFilter.startsAt) {
|
|
293
|
-
if (inputFilter.timezone) {
|
|
294
|
-
// if no timezone is provided, use startsAt as-is
|
|
295
|
-
const timezoneNormal = dateTimezoneUtcNormal(inputFilter.timezone);
|
|
296
|
-
filterStart = timezoneNormal.startOfDayInTargetTimezone(inputFilter.startsAt);
|
|
297
|
-
nextFilterTimezone = inputFilter.timezone;
|
|
298
|
-
}
|
|
299
|
-
else {
|
|
300
|
-
// set to the start of today in the system timezone.
|
|
301
|
-
filterStart = SYSTEM_DATE_TIMEZONE_UTC_NORMAL_INSTANCE.startOfDayInTargetTimezone(inputFilter.startsAt);
|
|
302
|
-
nextFilterTimezone = systemTimezone;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
filter.start = filterStart ?? undefined;
|
|
306
|
-
filter.timezone = nextFilterTimezone;
|
|
307
|
-
// configure exclusions
|
|
308
|
-
if (exclusions?.length) {
|
|
309
|
-
enabledFilter = {
|
|
310
|
-
...filter,
|
|
311
|
-
ex: unique(mergeArrays([filter.ex, exclusions]))
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
else {
|
|
315
|
-
enabledFilter = filter;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
else {
|
|
319
|
-
enabledFilter = {
|
|
320
|
-
w: '89',
|
|
321
|
-
ex: exclusions
|
|
322
|
-
};
|
|
323
|
-
}
|
|
324
|
-
if (minMaxDateRange) {
|
|
325
|
-
enabledFilter.minMaxDateRange = minMaxDateRange;
|
|
326
|
-
enabledFilter.setStartAsMinDate = filterStart ? true : false; // If a start date is set, then it becomes the floor.
|
|
327
|
-
}
|
|
328
|
-
/**
|
|
329
|
-
* If the input filter has a start date, use that as the relative start to ensure indexes are compared the same,
|
|
330
|
-
* otherwise use the state's start. This is important for the index calculations.
|
|
331
|
-
*/
|
|
332
|
-
let finalEnabledStart;
|
|
333
|
-
let finalEnabledTimezone;
|
|
334
|
-
// filter?.start ?? state.start;
|
|
335
|
-
if (!enabledFilter.start) {
|
|
336
|
-
// use the current state's start, but make sure it is in the proper timezone.
|
|
337
|
-
if (enabledFilter.timezone) {
|
|
338
|
-
const timezoneNormal = dateTimezoneUtcNormal(enabledFilter.timezone);
|
|
339
|
-
finalEnabledStart = timezoneNormal.startOfDayInTargetTimezone(currentState.start); // get the start of the day for the current start
|
|
340
|
-
finalEnabledTimezone = enabledFilter.timezone;
|
|
341
|
-
}
|
|
342
|
-
else {
|
|
343
|
-
finalEnabledStart = currentState.start;
|
|
344
|
-
finalEnabledTimezone = systemTimezone;
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
else if (!enabledFilter.timezone) {
|
|
348
|
-
finalEnabledTimezone = systemTimezone;
|
|
349
|
-
const timezoneNormal = dateTimezoneUtcNormal(finalEnabledTimezone);
|
|
350
|
-
finalEnabledStart = timezoneNormal.startOfDayInTargetTimezone(enabledFilter.start); // get the start of the day for the target timezone
|
|
351
|
-
}
|
|
352
|
-
else {
|
|
353
|
-
finalEnabledStart = enabledFilter.start;
|
|
354
|
-
finalEnabledTimezone = enabledFilter.timezone;
|
|
355
|
-
}
|
|
356
|
-
enabledFilter.start = finalEnabledStart;
|
|
357
|
-
enabledFilter.timezone = finalEnabledTimezone;
|
|
358
|
-
// create the filter
|
|
359
|
-
isEnabledFilterDay = dateCellScheduleDateFilter(enabledFilter);
|
|
360
|
-
}
|
|
361
|
-
let nextState = { ...currentState, filter, isEnabledFilterDay };
|
|
362
|
-
// For the same reason as above, use the filter's start date as the relative start if applicable.
|
|
363
|
-
if (filter && filter.start) {
|
|
364
|
-
let startForSystemTimezone = filter.start;
|
|
365
|
-
if (filter.timezone) {
|
|
366
|
-
const timezoneNormal = dateTimezoneUtcNormal(filter.timezone);
|
|
367
|
-
startForSystemTimezone = timezoneNormal.systemDateToTargetDate(filter.start); // get the start of the day for the system timezone
|
|
368
|
-
}
|
|
369
|
-
nextState.start = startForSystemTimezone;
|
|
370
|
-
nextState.indexFactory = dateCellTimingRelativeIndexFactory({ startsAt: startForSystemTimezone, timezone: systemTimezone });
|
|
371
|
-
nextState.indexDayOfWeek = dateCellDayOfWeekFactory(startForSystemTimezone);
|
|
372
|
-
}
|
|
373
|
-
// attempt to re-apply the initial selection state once filter is applied
|
|
374
|
-
if (nextState.initialSelectionState) {
|
|
375
|
-
nextState = updateStateWithInitialSelectionState(nextState, nextState.initialSelectionState);
|
|
376
|
-
}
|
|
377
|
-
// re-calculate the selection given the filter
|
|
378
|
-
const { inputStart, inputEnd } = nextState;
|
|
379
|
-
if (inputStart && inputEnd) {
|
|
380
|
-
nextState = updateStateWithChangedRange(nextState, { inputStart, inputEnd });
|
|
381
|
-
}
|
|
382
|
-
return nextState;
|
|
383
|
-
}
|
|
384
|
-
export function updateStateWithTimezoneValue(state, timezone) {
|
|
385
|
-
const { currentSelectionValue } = state;
|
|
386
|
-
const timezoneNormal = timezone ? dateTimezoneUtcNormal({ timezone }) : undefined;
|
|
387
|
-
if (timezoneNormal && currentSelectionValue) {
|
|
388
|
-
// update the selection value to reflect the timezone changes.
|
|
389
|
-
const { dateScheduleRange: currentDateCellScheduleRange } = currentSelectionValue;
|
|
390
|
-
const start = timezoneNormal.targetDateToSystemDate(currentDateCellScheduleRange.start);
|
|
391
|
-
const end = timezoneNormal.targetDateToSystemDate(currentDateCellScheduleRange.end);
|
|
392
|
-
const newRange = {
|
|
393
|
-
...currentSelectionValue.dateScheduleRange,
|
|
394
|
-
start,
|
|
395
|
-
end
|
|
396
|
-
};
|
|
397
|
-
return updateStateWithDateCellScheduleRangeValue({ ...state, outputTimezone: timezone, outputTimezoneNormal: timezoneNormal }, newRange);
|
|
398
|
-
}
|
|
399
|
-
else {
|
|
400
|
-
return { ...state, outputTimezone: timezone, outputTimezoneNormal: timezoneNormal }; // no change in value
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
export function updateStateWithDateCellScheduleRangeValue(state, inputChange) {
|
|
404
|
-
const { currentSelectionValue, systemTimezone } = state;
|
|
405
|
-
const currentDateCellScheduleRange = currentSelectionValue?.dateScheduleRange; // current range is always in system time
|
|
406
|
-
let change;
|
|
407
|
-
// When using timezones, always return from the start of the day. Inputs are converted to the system time and used as the start of the day.
|
|
408
|
-
// Outputs remain accurate.
|
|
409
|
-
if (inputChange) {
|
|
410
|
-
// make sure a timezone is set. Input may not have a timezone attached. Default to system time.
|
|
411
|
-
const inputChangeWithTimezoneSet = {
|
|
412
|
-
...inputChange,
|
|
413
|
-
timezone: inputChange.timezone ?? systemTimezone
|
|
414
|
-
};
|
|
415
|
-
// calculate the schedule range
|
|
416
|
-
const fullChange = fullDateCellScheduleRange({ dateCellScheduleRange: inputChangeWithTimezoneSet });
|
|
417
|
-
const inputNormal = dateCellTimingTimezoneNormalInstance(fullChange);
|
|
418
|
-
const startInSystemTz = inputNormal.systemDateToTargetDate(fullChange.start);
|
|
419
|
-
const endInSystemTz = startOfDay(inputNormal.systemDateToTargetDate(fullChange.end));
|
|
420
|
-
// convert the start/end to system time
|
|
421
|
-
change = {
|
|
422
|
-
start: startInSystemTz,
|
|
423
|
-
end: endInSystemTz,
|
|
424
|
-
w: fullChange.w,
|
|
425
|
-
ex: fullChange.ex,
|
|
426
|
-
timezone: fullChange.timezone
|
|
427
|
-
};
|
|
428
|
-
}
|
|
429
|
-
const isSameValue = isSameDateCellScheduleDateRange(currentDateCellScheduleRange, change);
|
|
430
|
-
if (isSameValue) {
|
|
431
|
-
return state;
|
|
432
|
-
}
|
|
433
|
-
else {
|
|
434
|
-
if (change != null) {
|
|
435
|
-
const nextState = { ...state, inputStart: change.start, inputEnd: change.end, toggledIndexes: new Set(change.ex) };
|
|
436
|
-
return updateStateWithChangedScheduleDays(finalizeNewCalendarScheduleSelectionState(nextState), expandDateCellScheduleDayCodes(change.w || '89'));
|
|
437
|
-
}
|
|
438
|
-
else {
|
|
439
|
-
return noSelectionCalendarScheduleSelectionState(state); // clear selection, retain disabled days
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
export function updateStateWithChangedDefaultScheduleDays(state, change) {
|
|
444
|
-
const { defaultScheduleDays: currentDefaultScheduleDays } = state;
|
|
445
|
-
const defaultScheduleDays = new Set(change ?? fullWeekDateCellScheduleDayCodes());
|
|
446
|
-
if (dateCellScheduleDayCodesAreSetsEquivalent(defaultScheduleDays, currentDefaultScheduleDays)) {
|
|
447
|
-
return state; // no change
|
|
448
|
-
}
|
|
449
|
-
else {
|
|
450
|
-
return finalizeUpdateStateWithChangedScheduleDays(state, { ...state, defaultScheduleDays });
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
export function updateStateWithChangedScheduleDays(state, change) {
|
|
454
|
-
const { scheduleDays: currentScheduleDays } = state;
|
|
455
|
-
const scheduleDays = new Set(change ?? []);
|
|
456
|
-
let newScheduleDays;
|
|
457
|
-
if (currentScheduleDays != null && change != null) {
|
|
458
|
-
if (dateCellScheduleDayCodesAreSetsEquivalent(scheduleDays, currentScheduleDays)) {
|
|
459
|
-
newScheduleDays = undefined; //no change
|
|
460
|
-
}
|
|
461
|
-
else {
|
|
462
|
-
newScheduleDays = scheduleDays;
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
else if (currentScheduleDays !== change) {
|
|
466
|
-
newScheduleDays = change ? scheduleDays : null; // set the new one, or clear it
|
|
467
|
-
}
|
|
468
|
-
if (newScheduleDays === undefined) {
|
|
469
|
-
return state;
|
|
470
|
-
}
|
|
471
|
-
else {
|
|
472
|
-
return finalizeUpdateStateWithChangedScheduleDays(state, { ...state, scheduleDays: newScheduleDays ?? undefined });
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
export function updateStateWithSelectionMode(state, selectionMode) {
|
|
476
|
-
const { selectionMode: currentSelectionMode } = state;
|
|
477
|
-
if (currentSelectionMode !== selectionMode) {
|
|
478
|
-
const nextState = { ...state, selectionMode };
|
|
479
|
-
if (selectionMode === 'multiple') {
|
|
480
|
-
return nextState;
|
|
481
|
-
}
|
|
482
|
-
else {
|
|
483
|
-
const currentSelectionRange = computeCalendarScheduleSelectionDateCellRange(nextState);
|
|
484
|
-
return currentSelectionRange ? updateStateWithChangedDates(nextState, { set: [currentSelectionRange.i], invertSetBehavior: true }) : nextState;
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
else {
|
|
488
|
-
return state;
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
export function finalizeUpdateStateWithChangedScheduleDays(previousState, nextState) {
|
|
492
|
-
const previousScheduleDays = previousState.effectiveScheduleDays;
|
|
493
|
-
const nextScheduleDays = nextState.scheduleDays ?? nextState.defaultScheduleDays;
|
|
494
|
-
if (dateCellScheduleDayCodesAreSetsEquivalent(nextScheduleDays, previousScheduleDays)) {
|
|
495
|
-
return nextState; // the default or input schedule changed but the schedule is still the same, so no need for an update.
|
|
496
|
-
}
|
|
497
|
-
else {
|
|
498
|
-
const effectiveScheduleDays = new Set(simplifyDateCellScheduleDayCodes(nextScheduleDays));
|
|
499
|
-
const allowedDaysOfWeek = expandDateCellScheduleDayCodesToDayOfWeekSet(nextScheduleDays);
|
|
500
|
-
return finalizeNewCalendarScheduleSelectionState({
|
|
501
|
-
...nextState,
|
|
502
|
-
// update the effective schedule days and allowed days of week
|
|
503
|
-
effectiveScheduleDays,
|
|
504
|
-
allowedDaysOfWeek
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
export function updateStateWithChangedDates(state, change) {
|
|
509
|
-
const { selectionMode, allowedDaysOfWeek, indexFactory, indexDayOfWeek, inputStart: currentInputStart, inputEnd: currentInputEnd, minMaxDateRange, filter } = state;
|
|
510
|
-
const { start: minDateFromFilter, end: maxDateFromFilter } = calendarScheduleMinAndMaxDateRangeRelativeToFilter(state);
|
|
511
|
-
let inputStart = currentInputStart;
|
|
512
|
-
let inputEnd = currentInputEnd;
|
|
513
|
-
/**
|
|
514
|
-
* This is a set of indexes that are internally "selected" so that they are excluded from the inputStart/inputEnd date range.
|
|
515
|
-
*
|
|
516
|
-
* Do not confuse this with the actual indexes that are selected.
|
|
517
|
-
*/
|
|
518
|
-
let toggledIndexes;
|
|
519
|
-
function asIndexes(indexes) {
|
|
520
|
-
return iterableToArray(indexes).map(indexFactory);
|
|
521
|
-
}
|
|
522
|
-
// When using selection mode "single" we update the change to reflect the single selection.
|
|
523
|
-
if (selectionMode === 'single') {
|
|
524
|
-
function setFromFirstValue(input) {
|
|
525
|
-
const firstValue = isIterable(input) ? firstValueFromIterable(input) : input;
|
|
526
|
-
const set = new Set();
|
|
527
|
-
if (firstValue != null) {
|
|
528
|
-
set.add(firstValue);
|
|
529
|
-
}
|
|
530
|
-
return set;
|
|
531
|
-
}
|
|
532
|
-
if (change.set) {
|
|
533
|
-
change = { set: setFromFirstValue(change.set), invertSetBehavior: true };
|
|
534
|
-
}
|
|
535
|
-
else if (change.toggle) {
|
|
536
|
-
const nextSet = setFromFirstValue(change.toggle);
|
|
537
|
-
if (nextSet.size) {
|
|
538
|
-
const firstSetValueIndex = indexFactory(firstValueFromIterable(nextSet));
|
|
539
|
-
if (state.toggledIndexes.has(firstSetValueIndex) || (inputStart && indexFactory(inputStart) === firstSetValueIndex)) {
|
|
540
|
-
nextSet.clear(); // clear with the next set
|
|
541
|
-
}
|
|
542
|
-
change = { set: nextSet, invertSetBehavior: true };
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
// set, selectAll, add, and remove are treated as they normally are.
|
|
546
|
-
}
|
|
547
|
-
if (change.reset || change.selectAll != null || change.set != null) {
|
|
548
|
-
let set = change.set ?? [];
|
|
549
|
-
const selectAll = change.reset === true ? state.initialSelectionState : change.selectAll;
|
|
550
|
-
switch (selectAll) {
|
|
551
|
-
case 'all':
|
|
552
|
-
if (minDateFromFilter != null && maxDateFromFilter != null) {
|
|
553
|
-
inputStart = minDateFromFilter;
|
|
554
|
-
inputEnd = maxDateFromFilter;
|
|
555
|
-
set = [];
|
|
556
|
-
}
|
|
557
|
-
break;
|
|
558
|
-
case 'none':
|
|
559
|
-
inputStart = null;
|
|
560
|
-
inputEnd = null;
|
|
561
|
-
set = [];
|
|
562
|
-
break;
|
|
563
|
-
}
|
|
564
|
-
const inputSetIndexes = asIndexes(set);
|
|
565
|
-
toggledIndexes = new Set(inputSetIndexes);
|
|
566
|
-
if (change.invertSetBehavior && !selectAll) {
|
|
567
|
-
let minIndex;
|
|
568
|
-
let maxIndex;
|
|
569
|
-
if (minDateFromFilter != null && maxDateFromFilter != null) {
|
|
570
|
-
// only applicable when the filter is set.
|
|
571
|
-
minIndex = indexFactory(minDateFromFilter);
|
|
572
|
-
maxIndex = indexFactory(maxDateFromFilter);
|
|
573
|
-
inputStart = minDateFromFilter;
|
|
574
|
-
inputEnd = maxDateFromFilter;
|
|
575
|
-
}
|
|
576
|
-
else {
|
|
577
|
-
// when the filter is not set, use the least and greatest indexes from the input set.
|
|
578
|
-
const minAndMax = minAndMaxNumber(inputSetIndexes);
|
|
579
|
-
if (minAndMax != null) {
|
|
580
|
-
minIndex = minAndMax.min;
|
|
581
|
-
maxIndex = minAndMax.max;
|
|
582
|
-
const dateFactory = dateCellTimingStartDateFactory(indexFactory._timing);
|
|
583
|
-
inputStart = dateFactory(minAndMax.min);
|
|
584
|
-
inputEnd = minAndMax.min === minAndMax.max ? inputStart : dateFactory(minAndMax.max);
|
|
585
|
-
}
|
|
586
|
-
else {
|
|
587
|
-
// equivalent to an empty set / using "none" with selectAll.
|
|
588
|
-
inputStart = null;
|
|
589
|
-
inputEnd = null;
|
|
590
|
-
toggledIndexes = new Set();
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
// toggledIndexes should not include any indexes we want to include
|
|
594
|
-
if (minIndex != null && maxIndex != null) {
|
|
595
|
-
toggledIndexes = new Set(range(minIndex, maxIndex + 1).filter((x) => !toggledIndexes.has(x)));
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
else {
|
|
600
|
-
toggledIndexes = new Set(state.toggledIndexes); // copy the set
|
|
601
|
-
if (change.toggle) {
|
|
602
|
-
const allowedToToggle = asIndexes(change.toggle).filter((i) => allowedDaysOfWeek.has(indexDayOfWeek(i)));
|
|
603
|
-
toggleInSet(toggledIndexes, allowedToToggle);
|
|
604
|
-
}
|
|
605
|
-
let addToExclusion;
|
|
606
|
-
let removeFromExclusion;
|
|
607
|
-
if (change.add) {
|
|
608
|
-
if (change.invertSetBehavior) {
|
|
609
|
-
addToExclusion = change.add;
|
|
610
|
-
}
|
|
611
|
-
else {
|
|
612
|
-
removeFromExclusion = change.add;
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
if (change.remove) {
|
|
616
|
-
if (change.invertSetBehavior) {
|
|
617
|
-
removeFromExclusion = change.remove;
|
|
618
|
-
}
|
|
619
|
-
else {
|
|
620
|
-
addToExclusion = change.remove;
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
if (addToExclusion) {
|
|
624
|
-
removeFromSet(toggledIndexes, asIndexes(addToExclusion));
|
|
625
|
-
}
|
|
626
|
-
if (removeFromExclusion) {
|
|
627
|
-
addToSet(toggledIndexes, asIndexes(removeFromExclusion));
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
const nextState = { ...state, inputStart, inputEnd, toggledIndexes };
|
|
631
|
-
nextState.isEnabledDay = isEnabledDayInCalendarScheduleSelectionState(nextState);
|
|
632
|
-
// Recalculate the range and simplified to exclusions
|
|
633
|
-
const rangeAndExclusion = computeScheduleSelectionRangeAndExclusion(nextState);
|
|
634
|
-
if (rangeAndExclusion) {
|
|
635
|
-
return finalizeNewCalendarScheduleSelectionState({ ...nextState, toggledIndexes: new Set(rangeAndExclusion.excluded), inputStart: rangeAndExclusion.start, inputEnd: rangeAndExclusion.end });
|
|
636
|
-
}
|
|
637
|
-
else {
|
|
638
|
-
// no selected days
|
|
639
|
-
return noSelectionCalendarScheduleSelectionState(nextState);
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
export function noSelectionCalendarScheduleSelectionState(state) {
|
|
643
|
-
return finalizeNewCalendarScheduleSelectionState({ ...state, toggledIndexes: new Set(), inputStart: null, inputEnd: null });
|
|
644
|
-
}
|
|
645
|
-
export function updateStateWithChangedRange(state, change) {
|
|
646
|
-
const { inputStart: currentInputStart, inputEnd: currentInputEnd, indexFactory } = state;
|
|
647
|
-
const { start: minDate, end: maxDate } = calendarScheduleMinAndMaxDateRange(state);
|
|
648
|
-
const inputStart = startOfDay(change.inputStart);
|
|
649
|
-
const inputEnd = startOfDay(change.inputEnd); // midnight of the last day
|
|
650
|
-
const isValidRange = minDate != null || maxDate != null ? isDateInDateRangeFunction({ start: minDate ?? undefined, end: maxDate ?? undefined }) : () => true;
|
|
651
|
-
if (!isValidRange(inputStart) || !isValidRange(inputEnd) || (isSameDateDay(inputStart, currentInputStart) && isSameDateDay(inputEnd, currentInputEnd))) {
|
|
652
|
-
return state; // if no change, return the current state.
|
|
653
|
-
}
|
|
654
|
-
// retain all indexes that are within the new range
|
|
655
|
-
const minIndex = indexFactory(inputStart);
|
|
656
|
-
const maxIndex = indexFactory(inputEnd) + 1;
|
|
657
|
-
const currentIndexes = Array.from(state.toggledIndexes);
|
|
658
|
-
const isInCurrentRange = isIndexNumberInIndexRangeFunction({ minIndex, maxIndex });
|
|
659
|
-
const excludedIndexesInNewRange = currentIndexes.filter(isInCurrentRange);
|
|
660
|
-
const toggledIndexes = new Set(excludedIndexesInNewRange);
|
|
661
|
-
const nextState = { ...state, toggledIndexes, inputStart, inputEnd };
|
|
662
|
-
return finalizeNewCalendarScheduleSelectionState(nextState);
|
|
663
|
-
}
|
|
664
|
-
export function finalizeNewCalendarScheduleSelectionState(nextState) {
|
|
665
|
-
nextState.isEnabledDay = isEnabledDayInCalendarScheduleSelectionState(nextState);
|
|
666
|
-
nextState.currentSelectionValue = computeScheduleSelectionValue(nextState);
|
|
667
|
-
return nextState;
|
|
668
|
-
}
|
|
669
|
-
export function isEnabledDayInCalendarScheduleSelectionState(state) {
|
|
670
|
-
const { allowedDaysOfWeek, indexFactory, inputStart, inputEnd, indexDayOfWeek, systemTimezone } = state;
|
|
671
|
-
let isInStartAndEndRange;
|
|
672
|
-
if (inputStart && inputEnd) {
|
|
673
|
-
isInStartAndEndRange = isDateWithinDateCellRangeFunction({ startsAt: { startsAt: state.start, timezone: systemTimezone }, range: { start: inputStart, end: inputEnd } });
|
|
674
|
-
}
|
|
675
|
-
else {
|
|
676
|
-
isInStartAndEndRange = () => false;
|
|
677
|
-
}
|
|
678
|
-
return (input) => {
|
|
679
|
-
const index = indexFactory(input);
|
|
680
|
-
const dayOfWeek = indexDayOfWeek(index);
|
|
681
|
-
const isInSelectedRange = isInStartAndEndRange(index);
|
|
682
|
-
const isSelected = state.toggledIndexes.has(index);
|
|
683
|
-
const isAllowedDayOfWeek = allowedDaysOfWeek.has(dayOfWeek);
|
|
684
|
-
const result = isAllowedDayOfWeek && ((isInSelectedRange && !isSelected) || (isSelected && !isInSelectedRange));
|
|
685
|
-
return result;
|
|
686
|
-
};
|
|
687
|
-
}
|
|
688
|
-
export function computeScheduleSelectionValue(state) {
|
|
689
|
-
const { indexFactory: systemIndexFactory, allowedDaysOfWeek, effectiveScheduleDays, indexDayOfWeek, computeSelectionResultRelativeToFilter, filter, systemTimezone } = state;
|
|
690
|
-
let timezone = systemTimezone;
|
|
691
|
-
const rangeAndExclusion = computeScheduleSelectionRangeAndExclusion(state);
|
|
692
|
-
if (rangeAndExclusion == null) {
|
|
693
|
-
return null;
|
|
694
|
-
}
|
|
695
|
-
const { start: rangeStart, end: rangeEnd, excluded: allExcluded, dateCellRange } = rangeAndExclusion;
|
|
696
|
-
let filterOffsetExcludedRange = [];
|
|
697
|
-
let indexOffset = dateCellRange.i;
|
|
698
|
-
let start = rangeStart;
|
|
699
|
-
let end = rangeEnd;
|
|
700
|
-
// If computeSelectionResultRelativeToFilter is true, then we need to offset the values to be relative to that start.
|
|
701
|
-
if (computeSelectionResultRelativeToFilter && filter?.start) {
|
|
702
|
-
start = filter.start; // always start at the filter's start date
|
|
703
|
-
let startInSystemTimezone = start;
|
|
704
|
-
if (filter.timezone) {
|
|
705
|
-
timezone = filter.timezone;
|
|
706
|
-
const filterNormal = dateTimezoneUtcNormal(timezone);
|
|
707
|
-
end = filterNormal.startOfDayInTargetTimezone(end);
|
|
708
|
-
startInSystemTimezone = filterNormal.systemDateToTargetDate(start); // convert the start to the system timezone normal for deriving the index
|
|
709
|
-
}
|
|
710
|
-
const rangeStartIndex = systemIndexFactory(rangeStart);
|
|
711
|
-
const startIndex = systemIndexFactory(startInSystemTimezone);
|
|
712
|
-
const filterStartIndexOffset = rangeStartIndex - startIndex;
|
|
713
|
-
filterOffsetExcludedRange = range(0, filterStartIndexOffset);
|
|
714
|
-
indexOffset = indexOffset - filterStartIndexOffset;
|
|
715
|
-
}
|
|
716
|
-
const excluded = computeSelectionResultRelativeToFilter
|
|
717
|
-
? allExcluded.filter((x) => {
|
|
718
|
-
const isExcludedIndex = allowedDaysOfWeek.has(indexDayOfWeek(x)); // ???
|
|
719
|
-
return isExcludedIndex;
|
|
720
|
-
})
|
|
721
|
-
: allExcluded;
|
|
722
|
-
const offsetExcluded = excluded.map((x) => x - indexOffset); // set to the proper offset
|
|
723
|
-
const ex = [...filterOffsetExcludedRange, ...offsetExcluded];
|
|
724
|
-
const w = dateCellScheduleEncodedWeek(effectiveScheduleDays);
|
|
725
|
-
const d = []; // "included" blocks are never used/calculated.
|
|
726
|
-
// Always ensure the end is after or equal to the start.
|
|
727
|
-
if (isBefore(end, start)) {
|
|
728
|
-
end = start; // end is start
|
|
729
|
-
}
|
|
730
|
-
const dateScheduleRange = {
|
|
731
|
-
timezone,
|
|
732
|
-
start,
|
|
733
|
-
end,
|
|
734
|
-
w,
|
|
735
|
-
d,
|
|
736
|
-
ex
|
|
737
|
-
};
|
|
738
|
-
return {
|
|
739
|
-
dateScheduleRange,
|
|
740
|
-
minMaxRange: { start, end }
|
|
741
|
-
};
|
|
742
|
-
}
|
|
743
|
-
export function computeScheduleSelectionRangeAndExclusion(state) {
|
|
744
|
-
const { start: currentStart, isEnabledDay, isEnabledFilterDay, systemTimezone } = state;
|
|
745
|
-
const dateFactory = dateCellTimingStartDateFactory({ startsAt: currentStart, timezone: systemTimezone });
|
|
746
|
-
const dateCellRange = computeCalendarScheduleSelectionDateCellRange(state);
|
|
747
|
-
if (dateCellRange == null) {
|
|
748
|
-
return null; // returns null if no items are selected.
|
|
749
|
-
}
|
|
750
|
-
const start = dateFactory(dateCellRange.i);
|
|
751
|
-
const end = dateFactory(dateCellRange.to);
|
|
752
|
-
const excluded = range(dateCellRange.i, dateCellRange.to + 1).filter((x) => {
|
|
753
|
-
const isExcludedIndex = !isEnabledDay(x) || !isEnabledFilterDay(x);
|
|
754
|
-
return isExcludedIndex;
|
|
755
|
-
});
|
|
756
|
-
const result = {
|
|
757
|
-
dateCellRange,
|
|
758
|
-
start,
|
|
759
|
-
end,
|
|
760
|
-
excluded
|
|
761
|
-
};
|
|
762
|
-
return result;
|
|
763
|
-
}
|
|
764
|
-
export function computeCalendarScheduleSelectionRange(state) {
|
|
765
|
-
const dateFactory = dateCellTimingDateFactory({ startsAt: state.start, timezone: state.systemTimezone });
|
|
766
|
-
const dateCellRange = computeCalendarScheduleSelectionDateCellRange(state);
|
|
767
|
-
const dateRange = dateCellRange != null ? { start: dateFactory(dateCellRange.i), end: dateFactory(dateCellRange.to) } : undefined;
|
|
768
|
-
return dateRange;
|
|
769
|
-
}
|
|
770
|
-
export function computeCalendarScheduleSelectionDateCellRange(state) {
|
|
771
|
-
const { allowedDaysOfWeek, indexFactory, inputStart, inputEnd, indexDayOfWeek, isEnabledDay, isEnabledFilterDay } = state;
|
|
772
|
-
const enabledExclusionIndexes = Array.from(state.toggledIndexes).filter((i) => allowedDaysOfWeek.has(indexDayOfWeek(i)));
|
|
773
|
-
const minAndMaxSelectedValues = minAndMaxNumber(enabledExclusionIndexes);
|
|
774
|
-
let startRange;
|
|
775
|
-
let endRange;
|
|
776
|
-
if (minAndMaxSelectedValues) {
|
|
777
|
-
startRange = minAndMaxSelectedValues.min;
|
|
778
|
-
endRange = minAndMaxSelectedValues.max;
|
|
779
|
-
}
|
|
780
|
-
if (inputStart != null && inputEnd != null) {
|
|
781
|
-
const inputStartIndex = indexFactory(inputStart);
|
|
782
|
-
const inputEndIndex = indexFactory(inputEnd);
|
|
783
|
-
startRange = startRange != null ? Math.min(inputStartIndex, startRange) : inputStartIndex;
|
|
784
|
-
endRange = endRange != null ? Math.max(inputEndIndex, endRange) : inputEndIndex;
|
|
785
|
-
}
|
|
786
|
-
if (startRange != null && endRange != null) {
|
|
787
|
-
const scanStartIndex = startRange;
|
|
788
|
-
const scanEndIndex = endRange;
|
|
789
|
-
// clear start and end
|
|
790
|
-
startRange = undefined;
|
|
791
|
-
endRange = undefined;
|
|
792
|
-
// if the min is equal to the start index, then we are in the range and need to iterate dates until we find one that is not selected/excluded.
|
|
793
|
-
for (let i = scanStartIndex; i <= scanEndIndex; i += 1) {
|
|
794
|
-
if (isEnabledFilterDay(i) && isEnabledDay(i)) {
|
|
795
|
-
startRange = i;
|
|
796
|
-
break;
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
// same with the max
|
|
800
|
-
for (let i = scanEndIndex; i >= scanStartIndex; i -= 1) {
|
|
801
|
-
if (isEnabledFilterDay(i) && isEnabledDay(i)) {
|
|
802
|
-
endRange = i;
|
|
803
|
-
break;
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
if (startRange != null && endRange != null) {
|
|
808
|
-
return { i: startRange, to: endRange };
|
|
809
|
-
}
|
|
810
|
-
else {
|
|
811
|
-
return undefined;
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuc2NoZWR1bGUuc2VsZWN0aW9uLnN0b3JlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvZGJ4LWZvcm0vY2FsZW5kYXIvc3JjL2xpYi9jYWxlbmRhci5zY2hlZHVsZS5zZWxlY3Rpb24uc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBRUwsd0JBQXdCLEVBR3hCLHlCQUF5QixFQUV6QiwwQkFBMEIsRUFDMUIsb0NBQW9DLEVBRXBDLHVCQUF1QixFQUN2QiwyQkFBMkIsRUFHM0Isa0NBQWtDLEVBQ2xDLDhCQUE4QixFQUM5Qiw0Q0FBNEMsRUFDNUMsV0FBVyxFQUNYLFdBQVcsRUFDWCx5QkFBeUIsRUFFekIsaUNBQWlDLEVBQ2pDLFVBQVUsRUFDVixhQUFhLEVBQ2IsZUFBZSxFQUVmLHVDQUF1QyxFQUN2QyxtQkFBbUIsRUFFbkIscUJBQXFCLEVBRXJCLDJCQUEyQixFQUczQix3QkFBd0IsRUFFeEIseUNBQXlDLEVBQ3pDLGdDQUFnQyxFQUNoQyxnQ0FBZ0MsRUFDaEMsOEJBQThCLEVBRTlCLG1DQUFtQyxFQUNuQywrQkFBK0IsRUFFL0IseUJBQXlCLEVBQ3pCLG9DQUFvQyxFQUNwQyx5Q0FBeUMsRUFFekMsd0NBQXdDLEVBRXpDLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0UsT0FBTyxFQUE0RCxlQUFlLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxpQ0FBaUMsRUFBWSxlQUFlLEVBQWEsS0FBSyxFQUFzQixNQUFNLEVBQUUsV0FBVyxFQUFrQyxjQUFjLEVBQUUsd0JBQXdCLEVBQXdCLHNCQUFzQixFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN1ksT0FBTyxFQUFF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QUFLLElBQUksQ0FBQyxHQUFHLGNBQWMsRUFBRSxDQUFDLElBQUksWUFBWSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDdEQsSUFBSSxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQzVDLFVBQVUsR0FBRyxDQUFDLENBQUM7Z0JBQ2YsTUFBTTthQUNQO1NBQ0Y7UUFFRCxvQkFBb0I7UUFDcEIsS0FBSyxJQUFJLENBQUMsR0FBRyxZQUFZLEVBQUUsQ0FBQyxJQUFJLGNBQWMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3RELElBQUksa0JBQWtCLENBQUMsQ0FBQyxDQUFDLElBQUksWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUM1QyxRQUFRLEdBQUcsQ0FBQyxDQUFDO2dCQUNiLE1BQU07YUFDUDtTQUNGO0tBQ0Y7SUFFRCxJQUFJLFVBQVUsSUFBSSxJQUFJLElBQUksUUFBUSxJQUFJLElBQUksRUFBRTtRQUMxQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLENBQUM7S0FDeEM7U0FBTTtRQUNMLE9BQU8sU0FBUyxDQUFDO0tBQ2xCO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIERhdGVDZWxsRGF5T2ZXZWVrRmFjdG9yeSxcbiAgZGF0ZUNlbGxEYXlPZldlZWtGYWN0b3J5LFxuICBEYXRlQ2VsbEluZGV4LFxuICBEYXRlQ2VsbFJhbmdlV2l0aFJhbmdlLFxuICBkYXRlQ2VsbFRpbWluZ0RhdGVGYWN0b3J5LFxuICBEYXRlUmFuZ2UsXG4gIGRhdGVDZWxsU2NoZWR1bGVEYXRlRmlsdGVyLFxuICBjb3B5RGF0ZUNlbGxTY2hlZHVsZURhdGVGaWx0ZXJDb25maWcsXG4gIERhdGVDZWxsU2NoZWR1bGVEYXRlRmlsdGVyQ29uZmlnLFxuICBEYXRlQ2VsbFNjaGVkdWxlRGF5Q29kZSxcbiAgZGF0ZUNlbGxTY2hlZHVsZUVuY29kZWRXZWVrLFxuICBEYXRlQ2VsbFNjaGVkdWxlRW5jb2RlZFdlZWssXG4gIERhdGVDZWxsVGltaW5nUmVsYXRpdmVJbmRleEZhY3RvcnksXG4gIGRhdGVDZWxsVGltaW5nUmVsYXRpdmVJbmRleEZhY3RvcnksXG4gIGV4cGFuZERhdGVDZWxsU2NoZWR1bGVEYXlDb2RlcyxcbiAgZXhwYW5kRGF0ZUNlbGxTY2hlZHVsZURheUNvZGVzVG9EYXlPZldlZWtTZXQsXG4gIGZpbmRNYXhEYXRlLFxuICBmaW5kTWluRGF0ZSxcbiAgaXNEYXRlSW5EYXRlUmFuZ2VGdW5jdGlvbixcbiAgSXNEYXRlV2l0aGluRGF0ZUNlbGxSYW5nZUZ1bmN0aW9uLFxuICBpc0RhdGVXaXRoaW5EYXRlQ2VsbFJhbmdlRnVuY3Rpb24sXG4gIGlzU2FtZURhdGUsXG4gIGlzU2FtZURhdGVEYXksXG4gIGlzU2FtZURhdGVSYW5nZSxcbiAgRGF0ZU9yRGF0ZVJhbmdlT3JEYXRlQ2VsbEluZGV4T3JEYXRlQ2VsbFJhbmdlLFxuICBkYXRlQ2VsbFRpbWluZ1JlbGF0aXZlSW5kZXhBcnJheUZhY3RvcnksXG4gIGlzSW5maW5pdGVEYXRlUmFuZ2UsXG4gIGNvcHlIb3Vyc0FuZE1pbnV0ZXNGcm9tRGF0ZSxcbiAgZGF0ZVRpbWV6b25lVXRjTm9ybWFsLFxuICBEYXRlVGltZXpvbmVVdGNOb3JtYWxJbnN0YW5jZSxcbiAgZXhwYW5kRGF0ZUNlbGxTY2hlZHVsZVJhbmdlLFxuICBEYXRlQ2VsbCxcbiAgRGF0ZUNlbGxEdXJhdGlvblNwYW4sXG4gIGZvcm1hdFRvSVNPODYwMURheVN0cmluZyxcbiAgRGF0ZUNlbGxUaW1pbmdSZWxhdGl2ZUluZGV4RmFjdG9yeUlucHV0LFxuICBkYXRlQ2VsbFNjaGVkdWxlRGF5Q29kZXNBcmVTZXRzRXF1aXZhbGVudCxcbiAgc2ltcGxpZnlEYXRlQ2VsbFNjaGVkdWxlRGF5Q29kZXMsXG4gIGZ1bGxXZWVrRGF0ZUNlbGxTY2hlZHVsZURheUNvZGVzLFxuICBkYXRlQ2VsbFRpbWluZ1N0YXJ0RGF0ZUZhY3RvcnksXG4gIERhdGVDZWxsU2NoZWR1bGVEYXRlUmFuZ2UsXG4gIGRhdGVDZWxsVGltaW5nU3RhcnRzQXRGb3JTdGFydE9mRGF5LFxuICBpc1NhbWVEYXRlQ2VsbFNjaGVkdWxlRGF0ZVJhbmdlLFxuICBGdWxsRGF0ZUNlbGxTY2hlZHVsZVJhbmdlSW5wdXREYXRlUmFuZ2UsXG4gIGZ1bGxEYXRlQ2VsbFNjaGVkdWxlUmFuZ2UsXG4gIGRhdGVDZWxsVGltaW5nVGltZXpvbmVOb3JtYWxJbnN0YW5jZSxcbiAgY2hhbmdlRGF0ZUNlbGxTY2hlZHVsZURhdGVSYW5nZVRvVGltZXpvbmUsXG4gIHVwZGF0ZURhdGVDZWxsVGltaW5nVG9TeXN0ZW1UaW1lem9uZSxcbiAgU1lTVEVNX0RBVEVfVElNRVpPTkVfVVRDX05PUk1BTF9JTlNUQU5DRSxcbiAgZ2V0TGVhc3RBbmRHcmVhdGVzdERhdGVDZWxsSW5kZXhJbkRhdGVDZWxsUmFuZ2VzXG59IGZyb20gJ0BkZXJlZWtiL2RhdGUnO1xuaW1wb3J0IHsgZGlzdGluY3RVbnRpbEhhc0RpZmZlcmVudFZhbHVlcywgZmlsdGVyTWF5YmUgfSBmcm9tICdAZGVyZWVrYi9yeGpzJztcbmltcG9ydCB7IE1heWJlLCBUaW1lem9uZVN0cmluZywgRGVjaXNpb25GdW5jdGlvbiwgSXRlcmFibGVPclZhbHVlLCBpdGVyYWJsZVRvQXJyYXksIGFkZFRvU2V0LCB0b2dnbGVJblNldCwgaXNJbmRleE51bWJlckluSW5kZXhSYW5nZUZ1bmN0aW9uLCBNYXliZU1hcCwgbWluQW5kTWF4TnVtYmVyLCBEYXlPZldlZWssIHJhbmdlLCBBbGxPck5vbmVTZWxlY3Rpb24sIHVuaXF1ZSwgbWVyZ2VBcnJheXMsIEFycmF5T3JWYWx1ZSwgSVNPODYwMURheVN0cmluZywgbWFwVmFsdWVzVG9TZXQsIGlzSW5BbGxvd2VkRGF5c09mV2Vla1NldCwgQnVpbGRpbmcsIGZpcnN0VmFsdWUsIGZpcnN0VmFsdWVGcm9tSXRlcmFibGUsIGlzSXRlcmFibGUsIHJlbW92ZUZyb21TZXQgfSBmcm9tICdAZGVyZWVrYi91dGlsJztcbmltcG9ydCB7IENvbXBvbmVudFN0b3JlIH0gZnJvbSAnQG5ncngvY29tcG9uZW50LXN0b3JlJztcbmltcG9ydCB7IHN0YXJ0T2ZEYXksIGVuZE9mRGF5LCBpc0JlZm9yZSB9IGZyb20gJ2RhdGUtZm5zJztcbmltcG9ydCB7IE9ic2VydmFibGUsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBtYXAsIHNoYXJlUmVwbGF5LCBzd2l0Y2hNYXAsIHRhcCwgZmlyc3QsIGNvbWJpbmVMYXRlc3RXaXRoLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvbkNlbGxDb250ZW50RmFjdG9yeSwgQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblZhbHVlLCBkZWZhdWx0Q2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvbkNlbGxDb250ZW50RmFjdG9yeSB9IGZyb20gJy4vY2FsZW5kYXIuc2NoZWR1bGUuc2VsZWN0aW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uSW5wdXREYXRlUmFuZ2Uge1xuICAvKipcbiAgICogSW5wdXQgU3RhcnQgRGF0ZVxuICAgKi9cbiAgaW5wdXRTdGFydDogRGF0ZTtcbiAgLyoqXG4gICAqIElucHV0IEVuZCBEYXRlXG4gICAqL1xuICBpbnB1dEVuZDogRGF0ZTtcbn1cblxuZXhwb3J0IHR5cGUgUGFydGlhbENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25JbnB1dERhdGVSYW5nZSA9IFBhcnRpYWw8TWF5YmVNYXA8Q2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvbklucHV0RGF0ZVJhbmdlPj47XG5cbi8qKlxuICogRGJ4Q2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0b3JlIHNlbGVjdGlvbiBtb2RlLlxuICpcbiAqIFdoZW4gaW4gc2luZ2xlIG1vZGUgdGhlIHRvZ2dsZSBmdW5jdGlvbiBpcyB0cmVhdGVkIGFzIGEgc2V0IHRoYXQgY2xlYXJzIGFsbCB2YWx1ZXMgYW5kIG9ubHkgc2VsZWN0cyB0aGUgdG9nZ2xlJ2QgdmFsdWUuXG4gKi9cbmV4cG9ydCB0eXBlIERieENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdG9yZVNlbGVjdGlvbk1vZGUgPSAnbXVsdGlwbGUnIHwgJ3NpbmdsZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlIGV4dGVuZHMgUGFydGlhbENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25JbnB1dERhdGVSYW5nZSB7XG4gIC8qKlxuICAgKiBTZWxlY3Rpb24gbW9kZSBmb3IgdGhpcyBjYWxlbmRhci4gRGVmYXVsdHMgdG8gXCJtdWx0aXBsZVwiXG4gICAqL1xuICByZWFkb25seSBzZWxlY3Rpb25Nb2RlOiBEYnhDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RvcmVTZWxlY3Rpb25Nb2RlO1xuICAvKipcbiAgICogUmVhZG9ubHkgc3RhdGUgb2YgdGhlIHZpZXcuXG4gICAqXG4gICAqIERvZXMgbm90IGFmZmVjdCBzdGF0ZSBjaGFuZ2VzIGRpcmVjdGx5LCBidXQgaW5zdGVhZCBhY3RzIGFzIGEgZmxhZyBmb3IgdGhlIHBhcmVudCB2aWV3IHRvIHNldCBhbmQgdGhlIGNvbnN1bWluZyB2aWV3cyB0byB1cGRhdGUgb24uXG4gICAqL1xuICByZWFkb25seSBpc1ZpZXdSZWFkb25seT86IE1heWJlPGJvb2xlYW4+O1xuICAvKipcbiAgICogU2V0IG9mIHRoZSBkYXlzIG9mIHdlZWsgdGhhdCBhcmUgYWxsb3dlZCBieSBkZWZhdWx0LlxuICAgKi9cbiAgcmVhZG9ubHkgZGVmYXVsdFNjaGVkdWxlRGF5czogU2V0PERhdGVDZWxsU2NoZWR1bGVEYXlDb2RlPjtcbiAgLyoqXG4gICAqIEZpbHRlcnMgdGhlIGRheXMgb2YgdGhlIHNjaGVkdWxlIHRvIG9ubHkgYWxsb3cgc2VsZWN0aW5nIGRheXMgaW4gdGhlIHNjaGVkdWxlLlxuICAgKlxuICAgKiBUaGUgb3V0cHV0IHdpbGwgYmUgcmVsYXRpdmUgdG8gdGhpcyBmaWx0ZXIsIGFuZCBpbiBpdCdzIHRpbWV6b25lIHVubGVzcyBjb21wdXRlU2VsZWN0aW9uUmVzdWx0UmVsYXRpdmVUb0ZpbHRlciBpcyBmYWxzZS5cbiAgICpcbiAgICogVGhpcyBpcyBhIGNvcHkgb2YgYW55IHNldC9jb25maWd1cmVkIGlucHV0IGZpbHRlciBhbmQgd2lsbCBoYXZlIGEgc3RhcnQgZGF0ZSBzZXQgZnJvbSBzdGFydCBvciBzdGFydHNBdC5cbiAgICovXG4gIHJlYWRvbmx5IGZpbHRlcj86IE1heWJlPERhdGVDZWxsU2NoZWR1bGVEYXRlRmlsdGVyQ29uZmlnPjtcbiAgLyoqXG4gICAqIEFkZGl0aW9uYWwgZXhjbHVzaW9ucyB0aGF0IG1heSBub3QgYmUgZGVmaW5lZCB3aXRoaW4gdGhlIGZpbHRlci5cbiAgICovXG4gIHJlYWRvbmx5IGlucHV0RXhjbHVzaW9ucz86IE1heWJlPEFycmF5T3JWYWx1ZTxEYXRlT3JEYXRlUmFuZ2VPckRhdGVDZWxsSW5kZXhPckRhdGVDZWxsUmFuZ2U+PjtcbiAgLyoqXG4gICAqIFRoZSBjb21wdXRlZCBleGNsdXNpb25zIGdpdmVuIHRoZSBpbnB1dCBleGNsdXNpb25zLlxuICAgKi9cbiAgcmVhZG9ubHkgY29tcHV0ZWRFeGNsdXNpb25zPzogTWF5YmU8RGF0ZUNlbGxJbmRleFtdPjtcbiAgLyoqXG4gICAqIFRoZSBtaW4vbWF4IGRhdGUgcmFuZ2UuIFVzZWQgZm9yIHJlc3RyaWN0aW5nIHRoZSBtaW4vbWF4IHZhbHVlLiBXb3JrcyB3aXRoIHRoZSBmaWx0ZXIuIFRoZSBncmVhdGVyL2xlc3NlciBvZiB0aGUgc3RhcnQvZW5kIGRhdGVzIGFyZSB1c2VkIGlmIGJvdGggYXJlIHByb3ZpZGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgbWluTWF4RGF0ZVJhbmdlPzogTWF5YmU8UGFydGlhbDxEYXRlUmFuZ2U+PjtcbiAgLyoqXG4gICAqIFN0YXJ0IGRhdGUuIElzIHVwZGF0ZWQgYXMgdGhlIGlucHV0U3RhcnQgaXMgbW9kaWZpZWQgb3IgZmlsdGVyIGlzIHByb3ZpZGVkIHRoYXQgcHJvdmlkZXMgdGhlIHN0YXJ0IGRhdGUuXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIHRvZGF5IGFuZCB0aGUgY3VycmVudCB0aW1lem9uZS5cbiAgICovXG4gIHJlYWRvbmx5IHN0YXJ0OiBEYXRlQ2VsbFNjaGVkdWxlRGF0ZVJhbmdlWydzdGFydCddO1xuICAvKipcbiAgICogU3lzdGVtIFRpbWV6b25lLiBEb2VzIG5vdCBjaGFuZ2UuXG4gICAqL1xuICByZWFkb25seSBzeXN0ZW1UaW1lem9uZTogVGltZXpvbmVTdHJpbmc7XG4gIC8qKlxuICAgKiBUaW1lem9uZSB0byB1c2Ugd2hlbiBvdXRwdXR0aW5nIHRoZSB2YWx1ZS4gT25seSBpbmZsdWVuY2VzIHRoZSBvdXRwdXQgc3RhcnQgZGF0ZS5cbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dFRpbWV6b25lPzogTWF5YmU8VGltZXpvbmVTdHJpbmc+O1xuICAvKipcbiAgICogQ3VycmVudCB0aW1lem9uZSBub3JtYWwgd2l0aCB0aGUgY3VycmVudCB0aW1lem9uZS5cbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dFRpbWV6b25lTm9ybWFsPzogTWF5YmU8RGF0ZVRpbWV6b25lVXRjTm9ybWFsSW5zdGFuY2U+O1xuICAvKipcbiAgICogRGF0ZUNlbGxUaW1pbmdSZWxhdGl2ZUluZGV4RmFjdG9yeVxuICAgKi9cbiAgcmVhZG9ubHkgaW5kZXhGYWN0b3J5OiBEYXRlQ2VsbFRpbWluZ1JlbGF0aXZlSW5kZXhGYWN0b3J5O1xuICAvKipcbiAgICogQXJyYXkgb2YgbWFudWFsbHkgc2VsZWN0ZWQgZGF0ZXMgd2l0aGluIHRoZSBwaWNrZWQgcmFuZ2UuIFRoaXMgaXMgTk9UIHRoZSBzZXQgb2YgYWxsIHNlbGVjdGVkIGluZGV4ZXMgaW4gdGVybXMgb2Ygb3V0cHV0LlxuICAgKlxuICAgKiBWYWx1ZXMgdGhhdCBleGlzdCBvdXRzaWRlIG9mIHRoZSBcImlucHV0XCIgcmFuZ2UgYXJlIGNvbnNpZGVyZWQgdG9nZ2xlZCBvbiwgd2hpbGUgdGhvc2VcbiAgICogdGhhdCBhcmUgc2VsZWN0ZWQgd2l0aGluIHRoZSByYW5nZSBhcmUgY29uc2lkZXJlZCB0b2dnbGVkIG9mZi5cbiAgICpcbiAgICogSWYgZGF0ZXMgYXJlIHNlbGVjdGVkLCBhbmQgdGhlbiBhIHJhbmdlIGlzIHNlbGVjdGVkLCB0aGVuIHRob3NlIGRhdGVzIHdpdGhpbiB0aGUgcmFuZ2UgdGhhdCBmYWxsXG4gICAqIHdpdGhpbiB0aGUgcmFuZ2UgYXJlIGNsZWFyZWQgZnJvbSBzZWxlY3Rpb24uXG4gICAqXG4gICAqIFRoZXNlIGluZGV4ZXMgYXJlIHJlbGF0aXZlIHRvIHRoZSBzdGFydCBkYXRlLlxuICAgKi9cbiAgcmVhZG9ubHkgdG9nZ2xlZEluZGV4ZXM6IFNldDxEYXRlQ2VsbEluZGV4PjtcbiAgLyoqXG4gICAqIERheXMgb2YgdGhlIHNjaGVkdWxlIHRoYXQgYXJlIGFsbG93ZWQgdG8gYmUgcGlja2VkLiBJZiBub3QgZGVmaW5lZCwgZGVmYXVsdHMgdG8gZGVmYXVsdFNjaGVkdWxlRGF5cy5cbiAgICovXG4gIHJlYWRvbmx5IHNjaGVkdWxlRGF5cz86IE1heWJlPFNldDxEYXRlQ2VsbFNjaGVkdWxlRGF5Q29kZT4+O1xuICAvKipcbiAgICogVGhlIGN1cnJlbnQgRGF0ZUNlbGxTY2hlZHVsZURheUNvZGUgdmFsdWUuXG4gICAqL1xuICByZWFkb25seSBlZmZlY3RpdmVTY2hlZHVsZURheXM6IFNldDxEYXRlQ2VsbFNjaGVkdWxlRGF5Q29kZT47XG4gIC8qKlxuICAgKiBTZXQgb2YgdGhlIGRheXMgb2Ygd2VlayB0aGF0IGFyZSBhbGxvd2VkLiBEZXJpdmVkIGZyb20gdGhlIGN1cnJlbnQgc2NoZWR1bGUgZGF5cyB2YWx1ZS5cbiAgICovXG4gIHJlYWRvbmx5IGFsbG93ZWREYXlzT2ZXZWVrOiBTZXQ8RGF5T2ZXZWVrPjtcbiAgLyoqXG4gICAqXG4gICAqL1xuICByZWFkb25seSBpbmRleERheU9mV2VlazogRGF0ZUNlbGxEYXlPZldlZWtGYWN0b3J5O1xuICAvKipcbiAgICogRGVjaXNpb24gZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRydWUgaWYgYSB2YWx1ZSBpcyBlbmFibGVkIGdpdmVuIHRoZSBjdXJyZW50IGZpbHRlci5cbiAgICovXG4gIHJlYWRvbmx5IGlzRW5hYmxlZEZpbHRlckRheTogRGVjaXNpb25GdW5jdGlvbjxEYXRlQ2VsbFRpbWluZ1JlbGF0aXZlSW5kZXhGYWN0b3J5SW5wdXQ+O1xuICAvKipcbiAgICogRGVjaXNpb24gZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRydWUgaWYgYSB2YWx1ZSBpcyBlbmFibGVkLlxuICAgKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGRvZXMgbm90IHRha2UgdGhlIGN1cnJlbnQgZmlsdGVyIGludG8gYWNjb3VudC5cbiAgICovXG4gIHJlYWRvbmx5IGlzRW5hYmxlZERheTogRGVjaXNpb25GdW5jdGlvbjxEYXRlQ2VsbFRpbWluZ1JlbGF0aXZlSW5kZXhGYWN0b3J5SW5wdXQ+O1xuICAvKipcbiAgICogQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvbkNlbGxDb250ZW50RmFjdG9yeSBmb3IgdGhlIHZpZXcuXG4gICAqL1xuICByZWFkb25seSBjZWxsQ29udGVudEZhY3Rvcnk6IENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25DZWxsQ29udGVudEZhY3Rvcnk7XG4gIC8qKlxuICAgKiBDdXJyZW50IHNlbGVjdGlvbiB2YWx1ZS5cbiAgICovXG4gIHJlYWRvbmx5IGN1cnJlbnRTZWxlY3Rpb25WYWx1ZT86IE1heWJlPENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25WYWx1ZT47XG4gIC8qKlxuICAgKiBXaGV0aGVyIG9yIG5vdCB0byB1c2UgdGhlIGZpbHRlciBhcyB0aGUgc3RhcnQgYW5kIGVuZCByYW5nZSBpbnN0ZWFkIG9mIG9wdGltaXppbmcgZm9yIHRoZSBjdXJyZW50IGluZGV4LlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byB0cnVlLlxuICAgKi9cbiAgcmVhZG9ubHkgY29tcHV0ZVNlbGVjdGlvblJlc3VsdFJlbGF0aXZlVG9GaWx0ZXI/OiBNYXliZTxib29sZWFuPjtcbiAgLyoqXG4gICAqIFRoZSBpbml0aWFsIHNlbGVjdGlvbiBzdGF0ZSB3aGVuIHRoZSBjYWxlbmRhciBpcyByZXNldC5cbiAgICovXG4gIHJlYWRvbmx5IGluaXRpYWxTZWxlY3Rpb25TdGF0ZT86IE1heWJlPEFsbE9yTm9uZVNlbGVjdGlvbj47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpbml0aWFsQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlKCk6IENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSB7XG4gIGNvbnN0IGRlZmF1bHRTY2hlZHVsZURheXMgPSBuZXcgU2V0KFtEYXRlQ2VsbFNjaGVkdWxlRGF5Q29kZS5XRUVLREFZLCBEYXRlQ2VsbFNjaGVkdWxlRGF5Q29kZS5XRUVLRU5EXSk7XG4gIGNvbnN0IGFsbG93ZWREYXlzT2ZXZWVrID0gZXhwYW5kRGF0ZUNlbGxTY2hlZHVsZURheUNvZGVzVG9EYXlPZldlZWtTZXQoZGVmYXVsdFNjaGVkdWxlRGF5cyk7XG4gIGNvbnN0IGRlZmF1bHRTdGFydHNBdCA9IGRhdGVDZWxsVGltaW5nU3RhcnRzQXRGb3JTdGFydE9mRGF5KCk7IC8vIGdldCBtaWRuaWdodCBvZiB0aGUgY3VycmVudCB0aW1lem9uZVxuICBjb25zdCB7IHN0YXJ0c0F0LCB0aW1lem9uZTogc3lzdGVtVGltZXpvbmUgfSA9IGRlZmF1bHRTdGFydHNBdDtcbiAgY29uc3QgaW5kZXhGYWN0b3J5ID0gZGF0ZUNlbGxUaW1pbmdSZWxhdGl2ZUluZGV4RmFjdG9yeShkZWZhdWx0U3RhcnRzQXQpO1xuICBjb25zdCBpbmRleERheU9mV2VlayA9IGRhdGVDZWxsRGF5T2ZXZWVrRmFjdG9yeShzdGFydHNBdCk7XG5cbiAgcmV0dXJuIHtcbiAgICBzZWxlY3Rpb25Nb2RlOiAnbXVsdGlwbGUnLFxuICAgIHN0YXJ0OiBzdGFydHNBdCxcbiAgICBzeXN0ZW1UaW1lem9uZSxcbiAgICBpbmRleEZhY3RvcnksXG4gICAgdG9nZ2xlZEluZGV4ZXM6IG5ldyBTZXQoKSxcbiAgICBkZWZhdWx0U2NoZWR1bGVEYXlzLFxuICAgIGVmZmVjdGl2ZVNjaGVkdWxlRGF5czogZGVmYXVsdFNjaGVkdWxlRGF5cyxcbiAgICBhbGxvd2VkRGF5c09mV2VlayxcbiAgICBpbmRleERheU9mV2VlayxcbiAgICBpc0VuYWJsZWRGaWx0ZXJEYXk6ICgpID0+IHRydWUsXG4gICAgaXNFbmFibGVkRGF5OiAoKSA9PiBmYWxzZSxcbiAgICBjb21wdXRlU2VsZWN0aW9uUmVzdWx0UmVsYXRpdmVUb0ZpbHRlcjogdHJ1ZSxcbiAgICBjZWxsQ29udGVudEZhY3Rvcnk6IGRlZmF1bHRDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uQ2VsbENvbnRlbnRGYWN0b3J5XG4gIH07XG59XG5cbi8qKlxuICogVGhpcyBpcyB1c2VkIGluIGNhc2VzIHdoZXJlIHRoZSBkYXRlcyBpbiB0aGUgbWluL21heCBkYXRlIHJhbmdlIG5lZWQgdG8gYmUgc2hpZnRlZCB0byB0aGUgZmlsdGVyJ3MgdGltZXpvbmUuXG4gKlxuICogVGhpcyBpcyBiZWNhdXNlIHRoZSBpbmRleCBmYWN0b3J5IGlzIGFsd2F5cyBpbiBzeXN0ZW0gdGltZXpvbmUsIGJ1dCB3aGVuIHNlbGVjdGluZyBhbGwvbm9uZSB3aXRoIGEgZmlsdGVyIHdlIG5lZWQgdG8gdXNlIHRoZSBmaWx0ZXIncyB0aW1lem9uZS5cbiAqXG4gKiBAcGFyYW0geFxuICogQHJldHVybnNcbiAqL1xuZnVuY3Rpb24gY2FsZW5kYXJTY2hlZHVsZU1pbkFuZE1heERhdGVSYW5nZVJlbGF0aXZlVG9GaWx0ZXIoeDogUGljazxDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUsICdmaWx0ZXInIHwgJ21pbk1heERhdGVSYW5nZSc+KTogUGFydGlhbDxEYXRlUmFuZ2U+IHtcbiAgbGV0IGlucHV0OiBQaWNrPENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSwgJ2ZpbHRlcicgfCAnbWluTWF4RGF0ZVJhbmdlJz4gPSB4O1xuXG4gIGlmICh4LmZpbHRlcj8udGltZXpvbmUgJiYgeC5taW5NYXhEYXRlUmFuZ2UgIT0gbnVsbCkge1xuICAgIGNvbnN0IGZpbHRlck5vcm1hbCA9IGRhdGVUaW1lem9uZVV0Y05vcm1hbCh4LmZpbHRlci50aW1lem9uZSk7XG4gICAgY29uc3QgdHJhbnNmb3JtRm4gPSBmaWx0ZXJOb3JtYWwudHJhbnNmb3JtRnVuY3Rpb24oJ3N5c3RlbURhdGVUb1RhcmdldERhdGUnKTtcblxuICAgIGlucHV0ID0ge1xuICAgICAgZmlsdGVyOiB4LmZpbHRlcixcbiAgICAgIG1pbk1heERhdGVSYW5nZToge1xuICAgICAgICBzdGFydDogeC5taW5NYXhEYXRlUmFuZ2Uuc3RhcnQgPyB0cmFuc2Zvcm1Gbih4Lm1pbk1heERhdGVSYW5nZS5zdGFydCkgOiB1bmRlZmluZWQsXG4gICAgICAgIGVuZDogeC5taW5NYXhEYXRlUmFuZ2UuZW5kID8gdHJhbnNmb3JtRm4oeC5taW5NYXhEYXRlUmFuZ2UuZW5kKSA6IHVuZGVmaW5lZFxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICByZXR1cm4gY2FsZW5kYXJTY2hlZHVsZU1pbkFuZE1heERhdGVSYW5nZShpbnB1dCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYWxlbmRhclNjaGVkdWxlTWluQW5kTWF4RGF0ZVJhbmdlKHg6IFBpY2s8Q2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlLCAnZmlsdGVyJyB8ICdtaW5NYXhEYXRlUmFuZ2UnPik6IFBhcnRpYWw8RGF0ZVJhbmdlPiB7XG4gIHJldHVybiB7XG4gICAgc3RhcnQ6IGNhbGVuZGFyU2NoZWR1bGVNaW5EYXRlKHgpIHx8IHVuZGVmaW5lZCxcbiAgICBlbmQ6IGNhbGVuZGFyU2NoZWR1bGVNYXhEYXRlKHgpIHx8IHVuZGVmaW5lZFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FsZW5kYXJTY2hlZHVsZU1pbkRhdGUoeDogUGljazxDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUsICdmaWx0ZXInIHwgJ21pbk1heERhdGVSYW5nZSc+KTogTWF5YmU8RGF0ZT4ge1xuICByZXR1cm4gZmluZE1heERhdGUoW3guZmlsdGVyPy5zdGFydCwgeC5taW5NYXhEYXRlUmFuZ2U/LnN0YXJ0XSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYWxlbmRhclNjaGVkdWxlTWF4RGF0ZSh4OiBQaWNrPENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSwgJ2ZpbHRlcicgfCAnbWluTWF4RGF0ZVJhbmdlJz4pOiBNYXliZTxEYXRlPiB7XG4gIHJldHVybiBmaW5kTWluRGF0ZShbeC5maWx0ZXI/LmVuZCwgeC5taW5NYXhEYXRlUmFuZ2U/LmVuZF0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FsZW5kYXJTY2hlZHVsZVN0YXJ0QmVpbmdVc2VkRnJvbUZpbHRlcih4OiBQaWNrPENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSwgJ2ZpbHRlcicgfCAnY29tcHV0ZVNlbGVjdGlvblJlc3VsdFJlbGF0aXZlVG9GaWx0ZXInPikge1xuICByZXR1cm4geC5jb21wdXRlU2VsZWN0aW9uUmVzdWx0UmVsYXRpdmVUb0ZpbHRlciAmJiB4LmZpbHRlcj8uc3RhcnQgIT0gbnVsbDsgLy8gbWF5IGJlIHVzaW5nIGVpdGhlclxufVxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgRGJ4Q2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0b3JlIGV4dGVuZHMgQ29tcG9uZW50U3RvcmU8Q2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlPiB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKGluaXRpYWxDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUoKSk7XG4gIH1cblxuICAvLyBNQVJLOlxuICByZWFkb25seSB0b2dnbGVTZWxlY3Rpb24gPSB0aGlzLmVmZmVjdCgoaW5wdXQ6IE9ic2VydmFibGU8dm9pZD4pID0+IHtcbiAgICByZXR1cm4gaW5wdXQucGlwZShcbiAgICAgIHN3aXRjaE1hcCgoKSA9PlxuICAgICAgICB0aGlzLm5leHRUb2dnbGVTZWxlY3Rpb24kLnBpcGUoXG4gICAgICAgICAgZmlyc3QoKSxcbiAgICAgICAgICBmaWx0ZXJNYXliZSgpLFxuICAgICAgICAgIHRhcCgoeCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RBbGxEYXRlcyh4KTtcbiAgICAgICAgICB9KVxuICAgICAgICApXG4gICAgICApXG4gICAgKTtcbiAgfSk7XG5cbiAgLy8gTUFSSzogQWNjZXNzb3JzXG4gIHJlYWRvbmx5IHNlbGVjdGlvbk1vZGUkID0gdGhpcy5zdGF0ZSQucGlwZShcbiAgICBtYXAoKHgpID0+IHguc2VsZWN0aW9uTW9kZSksXG4gICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICBzaGFyZVJlcGxheSgxKVxuICApO1xuXG4gIHJlYWRvbmx5IGZpbHRlciQgPSB0aGlzLnN0YXRlJC5waXBlKFxuICAgIG1hcCgoeCkgPT4geC5maWx0ZXIpLFxuICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICByZWFkb25seSBtaW5NYXhEYXRlUmFuZ2UkID0gdGhpcy5zdGF0ZSQucGlwZShtYXAoY2FsZW5kYXJTY2hlZHVsZU1pbkFuZE1heERhdGVSYW5nZSksIGRpc3RpbmN0VW50aWxDaGFuZ2VkKGlzU2FtZURhdGVSYW5nZSksIHNoYXJlUmVwbGF5KDEpKTtcblxuICByZWFkb25seSBtaW5EYXRlJCA9IHRoaXMubWluTWF4RGF0ZVJhbmdlJC5waXBlKFxuICAgIG1hcCgoeCkgPT4geD8uc3RhcnQpLFxuICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKGlzU2FtZURhdGVEYXkpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG4gIHJlYWRvbmx5IG1heERhdGUkID0gdGhpcy5taW5NYXhEYXRlUmFuZ2UkLnBpcGUoXG4gICAgbWFwKCh4KSA9PiB4Py5lbmQpLFxuICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKGlzU2FtZURhdGVEYXkpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgcmVhZG9ubHkgaGFzQ29uZmlndXJlZE1pbk1heFJhbmdlJCA9IHRoaXMubWluTWF4RGF0ZVJhbmdlJC5waXBlKFxuICAgIG1hcCgoeCkgPT4geCAhPSBudWxsICYmIHguc3RhcnQgIT0gbnVsbCAmJiB4LmVuZCAhPSBudWxsKSxcbiAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgcmVhZG9ubHkgaW5wdXRTdGFydCQgPSB0aGlzLnN0YXRlJC5waXBlKFxuICAgIG1hcCgoeCkgPT4geC5pbnB1dFN0YXJ0KSxcbiAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZChpc1NhbWVEYXRlKSxcbiAgICBzaGFyZVJlcGxheSgxKVxuICApO1xuXG4gIHJlYWRvbmx5IGlucHV0RW5kJCA9IHRoaXMuc3RhdGUkLnBpcGUoXG4gICAgbWFwKCh4KSA9PiB4LmlucHV0RW5kKSxcbiAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZChpc1NhbWVEYXRlKSxcbiAgICBzaGFyZVJlcGxheSgxKVxuICApO1xuXG4gIHJlYWRvbmx5IGN1cnJlbnRJbnB1dFJhbmdlJDogT2JzZXJ2YWJsZTxNYXliZTxDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uSW5wdXREYXRlUmFuZ2U+PiA9IHRoaXMuc3RhdGUkLnBpcGUoXG4gICAgbWFwKCh7IGlucHV0U3RhcnQsIGlucHV0RW5kIH0pID0+ICh7IHN0YXJ0OiBpbnB1dFN0YXJ0LCBlbmQ6IGlucHV0RW5kIH0pKSxcbiAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgoYSwgYikgPT4gaXNTYW1lRGF0ZVJhbmdlKGEgYXMgRGF0ZVJhbmdlLCBiIGFzIERhdGVSYW5nZSkpLFxuICAgIG1hcCgoeCkgPT4gKHsgaW5wdXRTdGFydDogeC5zdGFydCwgaW5wdXRFbmQ6IHguZW5kIH0pKSxcbiAgICBtYXAoKHgpID0+IHtcbiAgICAgIGlmICh4LmlucHV0U3RhcnQgJiYgeC5pbnB1dEVuZCkge1xuICAgICAgICByZXR1cm4geCBhcyBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uSW5wdXREYXRlUmFuZ2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH0pLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgcmVhZG9ubHkgaW5wdXRSYW5nZSQ6IE9ic2VydmFibGU8Q2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvbklucHV0RGF0ZVJhbmdlPiA9IHRoaXMuY3VycmVudElucHV0UmFuZ2UkLnBpcGUoZmlsdGVyTWF5YmUoKSwgc2hhcmVSZXBsYXkoMSkpO1xuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBUaGlzIGlzIG5vdCB0aGUgc2FtZSBhcyB0aGUgY3VycmVudCBzZWxlY3Rpb24gdmFsdWUuIFRoaXMgaXMgdGhlIHNldCBvZiBtYW51YWxseSB0b2dnZWQgb2ZmIGRhdGVzLiBJdCB3aWxsIGJlIHJlbW92ZWQgaW4gYSBmdXR1cmUgdXBkYXRlLlxuICAgKi9cbiAgcmVhZG9ubHkgc2VsZWN0ZWREYXRlcyQ6IE9ic2VydmFibGU8U2V0PERhdGVDZWxsSW5kZXg+PiA9IHRoaXMuc3RhdGUkLnBpcGUoXG4gICAgbWFwKCh4KSA9PiB4LnRvZ2dsZWRJbmRleGVzKSxcbiAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgcmVhZG9ubHkgaXNFbmFibGVkRmlsdGVyRGF5RnVuY3Rpb24kOiBPYnNlcnZhYmxlPERlY2lzaW9uRnVuY3Rpb248RGF0ZUNlbGxUaW1pbmdSZWxhdGl2ZUluZGV4RmFjdG9yeUlucHV0Pj4gPSB0aGlzLnN0YXRlJC5waXBlKFxuICAgIG1hcCgoeCkgPT4geC5pc0VuYWJsZWRGaWx0ZXJEYXkpLFxuICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICByZWFkb25seSBpc0VuYWJsZWREYXlGdW5jdGlvbiQ6IE9ic2VydmFibGU8RGVjaXNpb25GdW5jdGlvbjxEYXRlQ2VsbFRpbWluZ1JlbGF0aXZlSW5kZXhGYWN0b3J5SW5wdXQ+PiA9IHRoaXMuc3RhdGUkLnBpcGUoXG4gICAgbWFwKCh4KSA9PiB4LmlzRW5hYmxlZERheSksXG4gICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICBzaGFyZVJlcGxheSgxKVxuICApO1xuXG4gIHJlYWRvbmx5IGN1cnJlbnREYXRlUmFuZ2UkOiBPYnNlcnZhYmxlPE1heWJlPERhdGVSYW5nZT4+ID0gdGhpcy5zdGF0ZSQucGlwZShcbiAgICBtYXAoY29tcHV0ZUNhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25SYW5nZSksXG4gICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKGEsIGIpID0+IGlzU2FtZURhdGVSYW5nZShhLCBiKSksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICByZWFkb25seSBjb21wdXRlU2VsZWN0aW9uUmVzdWx0UmVsYXRpdmVUb0ZpbHRlciQ6IE9ic2VydmFibGU8TWF5YmU8Ym9vbGVhbj4+ID0gdGhpcy5zdGF0ZSQucGlwZShcbiAgICBtYXAoKHgpID0+IHguY29tcHV0ZVNlbGVjdGlvblJlc3VsdFJlbGF0aXZlVG9GaWx0ZXIpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgcmVhZG9ubHkgc3RhcnRCZWluZ1VzZWRGcm9tRmlsdGVyJDogT2JzZXJ2YWJsZTxNYXliZTxib29sZWFuPj4gPSB0aGlzLnN0YXRlJC5waXBlKFxuICAgIC8vXG4gICAgbWFwKGNhbGVuZGFyU2NoZWR1bGVTdGFydEJlaW5nVXNlZEZyb21GaWx0ZXIpLFxuICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICByZWFkb25seSBkYXRlUmFuZ2UkOiBPYnNlcnZhYmxlPERhdGVSYW5nZT4gPSB0aGlzLmN1cnJlbnREYXRlUmFuZ2UkLnBpcGUoZmlsdGVyTWF5YmUoKSwgc2hhcmVSZXBsYXkoMSkpO1xuXG4gIHJlYWRvbmx5IGFsbG93ZWREYXlzT2ZXZWVrJDogT2JzZXJ2YWJsZTxTZXQ8RGF5T2ZXZWVrPj4gPSB0aGlzLnN0YXRlJC5waXBlKFxuICAgIG1hcCgoeCkgPT4geC5hbGxvd2VkRGF5c09mV2VlayksXG4gICAgZGlzdGluY3RVbnRpbEhhc0RpZmZlcmVudFZhbHVlcygpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgcmVhZG9ubHkgaXNJbkFsbG93ZWREYXlzT2ZXZWVrRnVuY3Rpb24kID0gdGhpcy5hbGxvd2VkRGF5c09mV2VlayQucGlwZShcbiAgICBtYXAoKHgpID0+IGlzSW5BbGxvd2VkRGF5c09mV2Vla1NldCh4KSksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICByZWFkb25seSBzY2hlZHVsZURheXMkOiBPYnNlcnZhYmxlPFNldDxEYXRlQ2VsbFNjaGVkdWxlRGF5Q29kZT4+ID0gdGhpcy5zdGF0ZSQucGlwZShcbiAgICBtYXAoKHgpID0+IHguZWZmZWN0aXZlU2NoZWR1bGVEYXlzKSxcbiAgICBkaXN0aW5jdFVudGlsSGFzRGlmZmVyZW50VmFsdWVzKCksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICByZWFkb25seSBvdXRwdXRUaW1lem9uZSQ6IE9ic2VydmFibGU8TWF5YmU8VGltZXpvbmVTdHJpbmc+PiA9IHRoaXMuc3RhdGUkLnBpcGUoXG4gICAgbWFwKCh4KSA9PiB4Lm91dHB1dFRpbWV6b25lKSxcbiAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgLyoqXG4gICAqIFRoZSB0aW1lem9uZSBvZiB0aGUgb3V0cHV0IHZhbHVlcy5cbiAgICpcbiAgICogSWYgYW4gb3V0cHV0VGltZXpvbmUgaXMgbm90IHNwZWNpZmllZCwgdGhpcyBkZWZhdWx0cyB0byB0aGUgc3lzdGVtIHRpbWV6b25lLlxuICAgKi9cbiAgcmVhZG9ubHkgZWZmZWN0aXZlT3V0cHV0VGltZXpvbmUkOiBPYnNlcnZhYmxlPFRpbWV6b25lU3RyaW5nPiA9IHRoaXMuc3RhdGUkLnBpcGUoXG4gICAgbWFwKCh4KSA9PiB4Lm91dHB1dFRpbWV6b25lIHx8IHguc3lzdGVtVGltZXpvbmUpLFxuICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICAvKipcbiAgICogQW4gb3V0cHV0VGltZXpvbmVOb3JtYWwgdG8gdXNlLlxuICAgKlxuICAgKiBJZiBhbiBvdXRwdXRUaW1lem9uZSBpcyBub3Qgc3BlY2lmaWVkLCB0aGlzIGlzIHVuZGVmaW5lZC5cbiAgICovXG4gIHJlYWRvbmx5IGVmZmVjdGl2ZU91dHB1dFRpbWV6b25lTm9ybWFsJDogT2JzZXJ2YWJsZTxNYXliZTxEYXRlVGltZXpvbmVVdGNOb3JtYWxJbnN0YW5jZT4+ID0gdGhpcy5zdGF0ZSQucGlwZShcbiAgICBtYXAoKHgpID0+ICh4Lm91dHB1dFRpbWV6b25lTm9ybWFsID8geC5vdXRwdXRUaW1lem9uZU5vcm1hbCA6IHVuZGVmaW5lZCkpLFxuICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICByZWFkb25seSBjdXJyZW50U2VsZWN0aW9uVmFsdWUkID0gdGhpcy5zdGF0ZSQucGlwZShcbiAgICBtYXAoKHgpID0+IHguY3VycmVudFNlbGVjdGlvblZhbHVlKSxcbiAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgcmVhZG9ubHkgY3VycmVudFNlbGVjdGlvblZhbHVlU3RhcnQkID0gdGhpcy5jdXJyZW50U2VsZWN0aW9uVmFsdWUkLnBpcGUoXG4gICAgbWFwKCh4KSA9PiB4Py5kYXRlU2NoZWR1bGVSYW5nZS5zdGFydCksXG4gICAgZGlzdGluY3RVbnRpbENoYW5nZWQoaXNTYW1lRGF0ZSksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICByZWFkb25seSBjdXJyZW50U2VsZWN0aW9uVmFsdWVEYXRlQ2VsbFRpbWluZ0RhdGVGYWN0b3J5JCA9IHRoaXMuY3VycmVudFNlbGVjdGlvblZhbHVlJC5waXBlKFxuICAgIG1hcCgoeCkgPT4gKHggPyBkYXRlQ2VsbFRpbWluZ0RhdGVGYWN0b3J5KHsgc3RhcnRzQXQ6IHguZGF0ZVNjaGVkdWxlUmFuZ2Uuc3RhcnQsIHRpbWV6b25lOiB4LmRhdGVTY2hlZHVsZVJhbmdlLnRpbWV6b25lIH0pIDogdW5kZWZpbmVkKSksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICByZWFkb25seSBjdXJyZW50U2VsZWN0aW9uVmFsdWVEYXRlQ2VsbER1cmF0aW9uU3BhbkV4cGFuc2lvbiQ6IE9ic2VydmFibGU8RGF0ZUNlbGxEdXJhdGlvblNwYW48RGF0ZUNlbGw+W10+ID0gdGhpcy5jdXJyZW50U2VsZWN0aW9uVmFsdWUkLnBpcGUoXG4gICAgbWFwKCh4KSA9PiAoeCA/IGV4cGFuZERhdGVDZWxsU2NoZWR1bGVSYW5nZSh7IGRhdGVDZWxsU2NoZWR1bGVSYW5nZTogeC5kYXRlU2NoZWR1bGVSYW5nZSB9KSA6IFtdKSksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICByZWFkb25seSBzZWxlY3Rpb25WYWx1ZVNlbGVjdGVkSW5kZXhlcyQ6IE9ic2VydmFibGU8U2V0PERhdGVDZWxsSW5kZXg+PiA9IHRoaXMuY3VycmVudFNlbGVjdGlvblZhbHVlRGF0ZUNlbGxEdXJhdGlvblNwYW5FeHBhbnNpb24kLnBpcGUoXG4gICAgbWFwKCh4KSA9PiBuZXcgU2V0KHgubWFwKCh5KSA9PiB5LmkpKSksXG4gICAgZGlzdGluY3RVbnRpbEhhc0RpZmZlcmVudFZhbHVlcygpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgcmVhZG9ubHkgc2VsZWN0aW9uVmFsdWVTZWxlY3RlZERhdGVzJDogT2JzZXJ2YWJsZTxTZXQ8SVNPODYwMURheVN0cmluZz4+ID0gdGhpcy5jdXJyZW50U2VsZWN0aW9uVmFsdWVEYXRlQ2VsbFRpbWluZ0RhdGVGYWN0b3J5JC5waXBlKFxuICAgIHN3aXRjaE1hcCgoZGF0ZUZhY3RvcnkpID0+IHtcbiAgICAgIHJldHVybiBkYXRlRmFjdG9yeSA/IHRoaXMuc2VsZWN0aW9uVmFsdWVTZWxlY3RlZEluZGV4ZXMkLnBpcGUobWFwKCh4KSA9PiBtYXBWYWx1ZXNUb1NldCh4LCAoeSkgPT4gZm9ybWF0VG9JU084NjAxRGF5U3RyaW5nKGRhdGVGYWN0b3J5KHkpKSkpKSA6IG9mKG5ldyBTZXQ8SVNPODYwMURheVN0cmluZz4oKSk7XG4gICAgfSksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICByZWFkb25seSBzZWxlY3Rpb25WYWx1ZSQgPSB0aGlzLmN1cnJlbnRTZWxlY3Rpb25WYWx1ZSQucGlwZShmaWx0ZXJNYXliZSgpLCBzaGFyZVJlcGxheSgxKSk7XG5cbiAgcmVhZG9ubHkgY3VycmVudFNlbGVjdGlvblZhbHVlV2l0aFRpbWV6b25lJCA9IHRoaXMuY3VycmVudFNlbGVjdGlvblZhbHVlJC5waXBlKFxuICAgIGNvbWJpbmVMYXRlc3RXaXRoKHRoaXMuZWZmZWN0aXZlT3V0cHV0VGltZXpvbmVOb3JtYWwkKSxcbiAgICBtYXAoKFt4LCB0aW1lem9uZU5vcm1hbF0pID0+IHtcbiAgICAgIGxldCBjdXJyZW50VmFsdWVXaXRoVGltZXpvbmUgPSB4O1xuXG4gICAgICBpZiAoeCAmJiB0aW1lem9uZU5vcm1hbCkge1xuICAgICAgICBjdXJyZW50VmFsdWVXaXRoVGltZXpvbmUgPSB7XG4gICAgICAgICAgZGF0ZVNjaGVkdWxlUmFuZ2U6IGNoYW5nZURhdGVDZWxsU2NoZWR1bGVEYXRlUmFuZ2VUb1RpbWV6b25lKHguZGF0ZVNjaGVkdWxlUmFuZ2UsIHRpbWV6b25lTm9ybWFsKSxcbiAgICAgICAgICBtaW5NYXhSYW5nZTogeC5taW5NYXhSYW5nZVxuICAgICAgICB9IGFzIENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25WYWx1ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGN1cnJlbnRWYWx1ZVdpdGhUaW1lem9uZTtcbiAgICB9KSxcbiAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgcmVhZG9ubHkgc2VsZWN0aW9uVmFsdWVXaXRoVGltZXpvbmUkID0gdGhpcy5jdXJyZW50U2VsZWN0aW9uVmFsdWVXaXRoVGltZXpvbmUkLnBpcGUoZmlsdGVyTWF5YmUoKSwgc2hhcmVSZXBsYXkoMSkpO1xuXG4gIHJlYWRvbmx5IHNlbGVjdGlvblZhbHVlV2l0aFRpbWV6b25lRGF0ZUNlbGxEdXJhdGlvblNwYW5FeHBhbnNpb24kOiBPYnNlcnZhYmxlPERhdGVDZWxsRHVyYXRpb25TcGFuPERhdGVDZWxsPltdPiA9IHRoaXMuc2VsZWN0aW9uVmFsdWVXaXRoVGltZXpvbmUkLnBpcGUoXG4gICAgbWFwKCh4KSA9PiBleHBhbmREYXRlQ2VsbFNjaGVkdWxlUmFuZ2UoeyBkYXRlQ2VsbFNjaGVkdWxlUmFuZ2U6IHguZGF0ZVNjaGVkdWxlUmFuZ2UgfSkpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgcmVhZG9ubHkgbmV4dFRvZ2dsZVNlbGVjdGlvbiQ6IE9ic2VydmFibGU8TWF5YmU8QWxsT3JOb25lU2VsZWN0aW9uPj4gPSB0aGlzLmhhc0NvbmZpZ3VyZWRNaW5NYXhSYW5nZSQucGlwZShcbiAgICBzd2l0Y2hNYXAoKGhhc0NvbmZpZ3VyZWRNaW5NYXhSYW5nZSkgPT4ge1xuICAgICAgbGV0IG9iczogT2JzZXJ2YWJsZTxNYXliZTxBbGxPck5vbmVTZWxlY3Rpb24+PjtcblxuICAgICAgaWYgKGhhc0NvbmZpZ3VyZWRNaW5NYXhSYW5nZSkge1xuICAgICAgICBvYnMgPSB0aGlzLmN1cnJlbnRTZWxlY3Rpb25WYWx1ZSQucGlwZShtYXAoKHgpID0+ICh4ID8gJ25vbmUnIDogJ2FsbCcpKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvYnMgPSB0aGlzLmN1cnJlbnRTZWxlY3Rpb25WYWx1ZSQucGlwZShtYXAoKHgpID0+ICh4ID8gJ25vbmUnIDogdW5kZWZpbmVkKSkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gb2JzO1xuICAgIH0pLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgcmVhZG9ubHkgY3VycmVudERhdGVDZWxsU2NoZWR1bGVSYW5nZVZhbHVlJCA9IHRoaXMuY3VycmVudFNlbGVjdGlvblZhbHVlV2l0aFRpbWV6b25lJC5waXBlKFxuICAgIG1hcCgoeCkgPT4geD8uZGF0ZVNjaGVkdWxlUmFuZ2UpLFxuICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKGlzU2FtZURhdGVDZWxsU2NoZWR1bGVEYXRlUmFuZ2UpLFxuICAgIHNoYXJlUmVwbGF5KDEpXG4gICk7XG5cbiAgcmVhZG9ubHkgZGF0ZUNlbGxTY2hlZHVsZVJhbmdlVmFsdWUkID0gdGhpcy5jdXJyZW50RGF0ZUNlbGxTY2hlZHVsZVJhbmdlVmFsdWUkLnBpcGUoZmlsdGVyTWF5YmUoKSwgc2hhcmVSZXBsYXkoMSkpO1xuXG4gIHJlYWRvbmx5IGNlbGxDb250ZW50RmFjdG9yeSQgPSB0aGlzLnN0YXRlJC5waXBlKFxuICAgIG1hcCgoeCkgPT4geC5jZWxsQ29udGVudEZhY3RvcnkpLFxuICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICByZWFkb25seSBpc0N1c3RvbWl6ZWQkID0gdGhpcy5zdGF0ZSQucGlwZShcbiAgICBtYXAoKHgpID0+IHgudG9nZ2xlZEluZGV4ZXMuc2l6ZSA+IDApLFxuICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgc2hhcmVSZXBsYXkoMSlcbiAgKTtcblxuICByZWFkb25seSBpc1ZpZXdSZWFkb25seSQgPSB0aGlzLnN0YXRlJC5waXBlKFxuICAgIG1hcCgoeCkgPT4geC5pc1ZpZXdSZWFkb25seSksXG4gICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICBzaGFyZVJlcGxheSgxKVxuICApO1xuXG4gIC8vIE1BUks6IFN0YXRlIENoYW5nZXNcbiAgcmVhZG9ubHkgc2V0TWluTWF4RGF0ZVJhbmdlID0gdGhpcy51cGRhdGVyKHVwZGF0ZVN0YXRlV2l0aE1pbk1heERhdGVSYW5nZSk7XG4gIHJlYWRvbmx5IHNldERlZmF1bHRXZWVrID0gdGhpcy51cGRhdGVyKHVwZGF0ZVN0YXRlV2l0aE1pbk1heERhdGVSYW5nZSk7XG4gIHJlYWRvbmx5IHNldEZpbHRlciA9IHRoaXMudXBkYXRlcih1cGRhdGVTdGF0ZVdpdGhGaWx0ZXIpO1xuICByZWFkb25seSBzZXRFeGNsdXNpb25zID0gdGhpcy51cGRhdGVyKHVwZGF0ZVN0YXRlV2l0aEV4Y2x1c2lvbnMpO1xuICByZWFkb25seSBzZXRDb21wdXRlU2VsZWN0aW9uUmVzdWx0UmVsYXRpdmVUb0ZpbHRlciA9IHRoaXMudXBkYXRlcih1cGRhdGVTdGF0ZVdpdGhDb21wdXRlU2VsZWN0aW9uUmVzdWx0UmVsYXRpdmVUb0ZpbHRlcik7XG4gIHJlYWRvbmx5IGNsZWFyRmlsdGVyID0gdGhpcy51cGRhdGVyKChzdGF0ZSkgPT4gdXBkYXRlU3RhdGVXaXRoRmlsdGVyKHN0YXRlLCB1bmRlZmluZWQpKTtcblxuICByZWFkb25seSBzZXRPdXRwdXRUaW1lem9uZSA9IHRoaXMudXBkYXRlcih1cGRhdGVTdGF0ZVdpdGhUaW1lem9uZVZhbHVlKTtcbiAgLyoqXG4gICAqIFNldHMgdGhlIFwiaW5wdXRcIiBkYXRlIHJhbmdlLiBUaGlzIGlzIHRoZSByYW5nZSB0aGF0IGdldHMgZGlzcGxheWVkIG9uIHRoZSBkYXRlIHJhbmdlIHBpY2tlci5cbiAgICovXG4gIHJlYWRvbmx5IHNldElucHV0UmFuZ2UgPSB0aGlzLnVwZGF0ZXIodXBkYXRlU3RhdGVXaXRoQ2hhbmdlZFJhbmdlKTtcblxuICAvLyBOT1RFOiBTZWxlY3RlZCBkYXRlcyBhcmUgTk9UIHNlbGVjdGVkIGluZGV4ZXMuIFRoZXkgYXJlIHRoZSBpbnRlcm5hbCBzZWxlY3RlZCBkYXRlcyB0aGF0IGFyZSBleGNsdWRlZCBmcm9tIHRoZSBzZWxlY3Rpb24uXG4gIHJlYWRvbmx5IHRvZ2dsZVNlbGVjdGVkRGF0ZXMgPSB0aGlzLnVwZGF0ZXIoKHN0YXRlLCB0b2dnbGU6IEl0ZXJhYmxlT3JWYWx1ZTxEYXRlQ2VsbFRpbWluZ1JlbGF0aXZlSW5kZXhGYWN0b3J5SW5wdXQ+KSA9PiB1cGRhdGVTdGF0ZVdpdGhDaGFuZ2VkRGF0ZXMoc3RhdGUsIHsgdG9nZ2xlIH0pKTtcbiAgcmVhZG9ubHkgYWRkU2VsZWN0ZWREYXRlcyA9IHRoaXMudXBkYXRlcigoc3RhdGUsIGFkZDogSXRlcmFibGVPclZhbHVlPERhdGVDZWxsVGltaW5nUmVsYXRpdmVJbmRleEZhY3RvcnlJbnB1dD4pID0+IHVwZGF0ZVN0YXRlV2l0aENoYW5nZWREYXRlcyhzdGF0ZSwgeyBhZGQgfSkpO1xuICByZWFkb25seSByZW1vdmVTZWxlY3RlZERhdGVzID0gdGhpcy51cGRhdGVyKChzdGF0ZSwgcmVtb3ZlOiBJdGVyYWJsZU9yVmFsdWU8RGF0ZUNlbGxUaW1pbmdSZWxhdGl2ZUluZGV4RmFjdG9yeUlucHV0PikgPT4gdXBkYXRlU3RhdGVXaXRoQ2hhbmdlZERhdGVzKHN0YXRlLCB7IHJlbW92ZSB9KSk7XG4gIHJlYWRvbmx5IHNldFNlbGVjdGVkRGF0ZXMgPSB0aGlzLnVwZGF0ZXIoKHN0YXRlLCBzZXQ6IEl0ZXJhYmxlT3JWYWx1ZTxEYXRlQ2VsbFRpbWluZ1JlbGF0aXZlSW5kZXhGYWN0b3J5SW5wdXQ+KSA9PiB1cGRhdGVTdGF0ZVdpdGhDaGFuZ2VkRGF0ZXMoc3RhdGUsIHsgc2V0IH0pKTtcbiAgcmVhZG9ubHkgc2VsZWN0QWxsRGF0ZXMgPSB0aGlzLnVwZGF0ZXIoKHN0YXRlLCBzZWxlY3RBbGw6IEFsbE9yTm9uZVNlbGVjdGlvbiA9ICdhbGwnKSA9PiB1cGRhdGVTdGF0ZVdpdGhDaGFuZ2VkRGF0ZXMoc3RhdGUsIHsgc2VsZWN0QWxsIH0pKTtcblxuICAvLyBOT1RFOiBTZWxlY3RlZCBpbmRleGVzIGFyZSB0aGUgdHlwaWNhbC9leHBlY3RlZCBpbmRleGVzIHRoYXQgYXJlIHNlbGVjdGVkIG9yIG5vdC5cbiAgcmVhZG9ubHkgc2V0U2VsZWN0ZWRJbmRleGVzID0gdGhpcy51cGRhdGVyKChzdGF0ZSwgc2V0OiBJdGVyYWJsZU9yVmFsdWU8RGF0ZUNlbGxUaW1pbmdSZWxhdGl2ZUluZGV4RmFjdG9yeUlucHV0PikgPT4gdXBkYXRlU3RhdGVXaXRoQ2hhbmdlZERhdGVzKHN0YXRlLCB7IHNldCwgaW52ZXJ0U2V0QmVoYXZpb3I6IHRydWUgfSkpO1xuICByZWFkb25seSBzZXRJbml0aWFsU2VsZWN0aW9uU3RhdGUgPSB0aGlzLnVwZGF0ZXIodXBkYXRlU3RhdGVXaXRoSW5pdGlhbFNlbGVjdGlvblN0YXRlKTtcblxuICByZWFkb25seSBzZXREZWZhdWx0U2NoZWR1bGVEYXlzID0gdGhpcy51cGRhdGVyKHVwZGF0ZVN0YXRlV2l0aENoYW5nZWREZWZhdWx0U2NoZWR1bGVEYXlzKTtcbiAgcmVhZG9ubHkgc2V0U2NoZWR1bGVEYXlzID0gdGhpcy51cGRhdGVyKHVwZGF0ZVN0YXRlV2l0aENoYW5nZWRTY2hlZHVsZURheXMpO1xuICByZWFkb25seSBzZXRBbGxvd0FsbFNjaGVkdWxlRGF5cyA9IHRoaXMudXBkYXRlcigoc3RhdGUpID0+IHVwZGF0ZVN0YXRlV2l0aENoYW5nZWRTY2hlZHVsZURheXMoc3RhdGUsIFtEYXRlQ2VsbFNjaGVkdWxlRGF5Q29kZS5XRUVLREFZLCBEYXRlQ2VsbFNjaGVkdWxlRGF5Q29kZS5XRUVLRU5EXSkpO1xuXG4gIHJlYWRvbmx5IHNldERhdGVTY2hlZHVsZVJhbmdlVmFsdWUgPSB0aGlzLnVwZGF0ZXIoKHN0YXRlLCB2YWx1ZTogTWF5YmU8RnVsbERhdGVDZWxsU2NoZWR1bGVSYW5nZUlucHV0RGF0ZVJhbmdlPikgPT4gdXBkYXRlU3RhdGVXaXRoRGF0ZUNlbGxTY2hlZHVsZVJhbmdlVmFsdWUoc3RhdGUsIHZhbHVlKSk7XG4gIHJlYWRvbmx5IHNldENlbGxDb250ZW50RmFjdG9yeSA9IHRoaXMudXBkYXRlcigoc3RhdGUsIGNlbGxDb250ZW50RmFjdG9yeTogQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvbkNlbGxDb250ZW50RmFjdG9yeSkgPT4gKHsgLi4uc3RhdGUsIGNlbGxDb250ZW50RmFjdG9yeSB9KSk7XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIHNlbGVjdGlvbiBtb2RlLlxuICAgKi9cbiAgcmVhZG9ubHkgc2V0U2VsZWN0aW9uTW9kZSA9IHRoaXMudXBkYXRlcih1cGRhdGVTdGF0ZVdpdGhTZWxlY3Rpb25Nb2RlKTtcblxuICAvKipcbiAgICogVXNlZCBieSB0aGUgcGFyZW50IHZpZXcgdG8gcHJvcG9nYXRlIGEgcmVhZG9ubHkgc3RhdGUuXG4gICAqXG4gICAqIFNob3VsZCB0eXBpY2FsbHkgbm90IGJlIHVzZWQgYnkgdGhlIHVzZXIgZGlyZWN0bHkgd2l0aCB0aGUgaW50ZW50aW9uIG9mIHRoZSBwYXJlbnQgc3luY2hyb25pemluZyB0byB0aGlzIHN0YXRlLlxuICAgKi9cbiAgcmVhZG9ubHkgc2V0Vmlld1JlYWRvbmx5U3RhdGUgPSB0aGlzLnVwZGF0ZXIoKHN0YXRlLCBpc1ZpZXdSZWFkb25seTogYm9vbGVhbikgPT4gKHsgLi4uc3RhdGUsIGlzVmlld1JlYWRvbmx5IH0pKTtcblxuICAvLyBNQVJLOiBDb21wYXRcbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIHVzZSBzZXRPdXRwdXRUaW1lem9uZSBpbnN0ZWFkLlxuICAgKi9cbiAgcmVhZG9ubHkgc2V0VGltZXpvbmUgPSB0aGlzLnNldE91dHB1dFRpbWV6b25lO1xuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCB1c2Ugb3VwdXRUaW1lem9uZSRcbiAgICovXG4gIHJlYWRvbmx5IGN1cnJlbnRUaW1lem9uZSQ6IE9ic2VydmFibGU8TWF5YmU8VGltZXpvbmVTdHJpbmc+PiA9IHRoaXMub3V0cHV0VGltZXpvbmUkO1xuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCB1c2UgZWZmZWN0aXZlT3VwdXRUaW1lem9uZSRcbiAgICovXG4gIHJlYWRvbmx5IGVmZmVjdGl2ZVRpbWV6b25lJDogT2JzZXJ2YWJsZTxNYXliZTxUaW1lem9uZVN0cmluZz4+ID0gdGhpcy5lZmZlY3RpdmVPdXRwdXRUaW1lem9uZSQ7XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIHVzZSBlZmZlY3RpdmVPdXB1dFRpbWV6b25lTm9ybWFsJFxuICAgKi9cbiAgcmVhZG9ubHkgZWZmZWN0aXZlVGltZXpvbmVOb3JtYWwkID0gdGhpcy5lZmZlY3RpdmVPdXRwdXRUaW1lem9uZU5vcm1hbCQ7XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIHVzZSBjdXJyZW50U2VsZWN0aW9uVmFsdWVEYXRlQ2VsbER1cmF0aW9uU3BhbkV4cGFuc2lvbiRcbiAgICovXG4gIHJlYWRvbmx5IGN1cnJlbnRTZWxlY3Rpb25WYWx1ZURhdGVCbG9ja0R1cmF0aW9uU3BhbiQgPSB0aGlzLmN1cnJlbnRTZWxlY3Rpb25WYWx1ZURhdGVDZWxsRHVyYXRpb25TcGFuRXhwYW5zaW9uJDtcblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgdXNlIHNlbGVjdGlvblZhbHVlV2l0aFRpbWV6b25lRGF0ZUNlbGxEdXJhdGlvblNwYW5FeHBhbnNpb24kXG4gICAqL1xuICByZWFkb25seSBzZWxlY3Rpb25WYWx1ZVdpdGhUaW1lem9uZURhdGVCbG9ja0R1cmF0aW9uU3BhbiQgPSB0aGlzLnNlbGVjdGlvblZhbHVlV2l0aFRpbWV6b25lRGF0ZUNlbGxEdXJhdGlvblNwYW5FeHBhbnNpb24kO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlU3RhdGVXaXRoSW5pdGlhbFNlbGVjdGlvblN0YXRlKHN0YXRlOiBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUsIGluaXRpYWxTZWxlY3Rpb25TdGF0ZTogTWF5YmU8QWxsT3JOb25lU2VsZWN0aW9uPik6IENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSB7XG4gIGNvbnN0IHsgdG9nZ2xlZEluZGV4ZXMgfSA9IHN0YXRlO1xuXG4gIGlmICh0b2dnbGVkSW5kZXhlcy5zaXplID09PSAwICYmIGluaXRpYWxTZWxlY3Rpb25TdGF0ZSA9PT0gJ2FsbCcpIHtcbiAgICBzdGF0ZSA9IHVwZGF0ZVN0YXRlV2l0aENoYW5nZWREYXRlcyhzdGF0ZSwgeyBzZWxlY3RBbGw6IGluaXRpYWxTZWxlY3Rpb25TdGF0ZSB9KTtcbiAgfVxuXG4gIHJldHVybiB7IC4uLnN0YXRlLCBpbml0aWFsU2VsZWN0aW9uU3RhdGUgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVN0YXRlV2l0aENvbXB1dGVTZWxlY3Rpb25SZXN1bHRSZWxhdGl2ZVRvRmlsdGVyKGN1cnJlbnRTdGF0ZTogQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlLCBjb21wdXRlU2VsZWN0aW9uUmVzdWx0UmVsYXRpdmVUb0ZpbHRlcjogTWF5YmU8Ym9vbGVhbj4pOiBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUge1xuICBsZXQgc3RhdGU6IENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSA9IHsgLi4uY3VycmVudFN0YXRlLCBjb21wdXRlU2VsZWN0aW9uUmVzdWx0UmVsYXRpdmVUb0ZpbHRlciB9O1xuXG4gIGlmIChCb29sZWFuKGN1cnJlbnRTdGF0ZS5jb21wdXRlU2VsZWN0aW9uUmVzdWx0UmVsYXRpdmVUb0ZpbHRlcikgIT09IEJvb2xlYW4oY29tcHV0ZVNlbGVjdGlvblJlc3VsdFJlbGF0aXZlVG9GaWx0ZXIpKSB7XG4gICAgc3RhdGUgPSB1cGRhdGVTdGF0ZVdpdGhDaGFuZ2VkRGF0ZXMoc3RhdGUsIHt9KTsgLy8gcmVjYWxjdWxhdGUgaWYgY2hhbmdlIG9jY3VycyBhcyBpdCB3aWxsIGFmZmVjdCB0aGUgb3V0cHV0IHZhbHVlXG4gIH1cblxuICByZXR1cm4gc3RhdGU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVTdGF0ZVdpdGhFeGNsdXNpb25zKHN0YXRlOiBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUsIGlucHV0RXhjbHVzaW9uczogTWF5YmU8QXJyYXlPclZhbHVlPERhdGVPckRhdGVSYW5nZU9yRGF0ZUNlbGxJbmRleE9yRGF0ZUNlbGxSYW5nZT4+KTogQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlIHtcbiAgbGV0IGNvbXB1dGVkRXhjbHVzaW9uczogTWF5YmU8RGF0ZUNlbGxJbmRleFtdPjtcblxuICBpZiAoaW5wdXRFeGNsdXNpb25zKSB7XG4gICAgY29uc3QgeyBpbmRleEZhY3RvcnkgfSA9IHN0YXRlO1xuICAgIGNvbnN0IGluZGV4QXJyYXlGYWN0b3J5ID0gZGF0ZUNlbGxUaW1pbmdSZWxhdGl2ZUluZGV4QXJyYXlGYWN0b3J5KGluZGV4RmFjdG9yeSk7XG4gICAgY29tcHV0ZWRFeGNsdXNpb25zID0gaW5kZXhBcnJheUZhY3RvcnkoaW5wdXRFeGNsdXNpb25zKTtcbiAgfVxuXG4gIHN0YXRlID0geyAuLi5zdGF0ZSwgaW5wdXRFeGNsdXNpb25zLCBjb21wdXRlZEV4Y2x1c2lvbnMgfTtcbiAgcmV0dXJuIHVwZGF0ZVN0YXRlV2l0aEZpbHRlcihzdGF0ZSwgc3RhdGUuZmlsdGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVN0YXRlV2l0aE1pbk1heERhdGVSYW5nZShzdGF0ZTogQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlLCBtaW5NYXhEYXRlUmFuZ2U6IE1heWJlPFBhcnRpYWw8RGF0ZVJhbmdlPj4pOiBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUge1xuICBpZiAobWluTWF4RGF0ZVJhbmdlICE9IG51bGwgJiYgIWlzSW5maW5pdGVEYXRlUmFuZ2UobWluTWF4RGF0ZVJhbmdlKSkge1xuICAgIHN0YXRlID0ge1xuICAgICAgLi4uc3RhdGUsXG4gICAgICBtaW5NYXhEYXRlUmFuZ2U6IHtcbiAgICAgICAgc3RhcnQ6IG1pbk1heERhdGVSYW5nZS5zdGFydCAhPSBudWxsID8gc3RhcnRPZkRheShtaW5NYXhEYXRlUmFuZ2Uuc3RhcnQpIDogdW5kZWZpbmVkLFxuICAgICAgICBlbmQ6IG1pbk1heERhdGVSYW5nZS5lbmQgIT0gbnVsbCA/IGVuZE9mRGF5KG1pbk1heERhdGVSYW5nZS5lbmQpIDogdW5kZWZpbmVkXG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBzdGF0ZSA9IHsgLi4uc3RhdGUsIG1pbk1heERhdGVSYW5nZTogdW5kZWZpbmVkIH07XG4gIH1cblxuICByZXR1cm4gdXBkYXRlU3RhdGVXaXRoRmlsdGVyKHN0YXRlLCBzdGF0ZS5maWx0ZXIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlU3RhdGVXaXRoRmlsdGVyKGN1cnJlbnRTdGF0ZTogQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlLCBpbnB1dEZpbHRlcjogTWF5YmU8RGF0ZUNlbGxTY2hlZHVsZURhdGVGaWx0ZXJDb25maWc+KTogQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlIHtcbiAgY29uc3QgeyBjb21wdXRlZEV4Y2x1c2lvbnM6IGV4Y2x1c2lvbnMsIG1pbk1heERhdGVSYW5nZSwgc3lzdGVtVGltZXpvbmUgfSA9IGN1cnJlbnRTdGF0ZTtcblxuICBsZXQgaXNFbmFibGVkRmlsdGVyRGF5OiBNYXliZTxEZWNpc2lvbkZ1bmN0aW9uPERhdGVDZWxsVGltaW5nUmVsYXRpdmVJbmRleEZhY3RvcnlJbnB1dD4+ID0gKCkgPT4gdHJ1ZTtcbiAgbGV0IGZpbHRlcjogTWF5YmU8RGF0ZUNlbGxTY2hlZHVsZURhdGVGaWx0ZXJDb25maWc+ID0gbnVsbDtcblxuICAvLyBjcmVhdGUgdGhlIGZpbHRlciB1c2luZyBpbnB1dEZpbHRlciwgZXhjbHVzaW9ucywgYW5kIG1pbk1heERhdGVSYW5nZVxuICBpZiAoaW5wdXRGaWx0ZXIgfHwgZXhjbHVzaW9ucz8ubGVuZ3RoIHx8IG1pbk1heERhdGVSYW5nZSkge1xuICAgIGxldCBlbmFibGVkRmlsdGVyOiBEYXRlQ2VsbFNjaGVkdWxlRGF0ZUZpbHRlckNvbmZpZztcbiAgICBsZXQgZmlsdGVyU3RhcnQ6IE1heWJlPERhdGU+ID0gbnVsbDsgLy8gdGhlIHN0YXJ0IGRhdGUgdGhhdCB3aWxsIGJlIHVzZWQvc2V0IG9uIHRoZSBmaWx0ZXIuXG5cbiAgICBpZiAoaW5wdXRGaWx0ZXIpIHtcbiAgICAgIGZpbHRlciA9IGNvcHlEYXRlQ2VsbFNjaGVkdWxlRGF0ZUZpbHRlckNvbmZpZyhpbnB1dEZpbHRlcik7IC8vIGNvcHkgZmlsdGVyXG5cbiAgICAgIGxldCBuZXh0RmlsdGVyVGltZXpvbmU6IFRpbWV6b25lU3RyaW5nIHwgdW5kZWZpbmVkOyAvLyBvbmx5IHNldCBpZiBpbnB1dEZpbHRlci5zdGFydCBvciBpbnB1dEZpbHRlci5zdGFydHNBdFxuXG4gICAgICAvLyBjb25maWd1cmUgZmlsdGVyIHN0YXJ0XG4gICAgICBpZiAoaW5wdXRGaWx0ZXIuc3RhcnQpIHtcbiAgICAgICAgZmlsdGVyU3RhcnQgPSBpbnB1dEZpbHRlci5zdGFydDtcblxuICAgICAgICAvLyBpZiBubyB0aW1lem9uZSBpcyBzcGVjaWZpZWQsIHRoZW4gdXNlIHRoZSBzeXN0ZW0gdGltZXpvbmUgYW5kIGFsaWduIGZpbHRlclN0YXJ0IHRvIHRoZSBzdGFydCBvZiB0aGUgZGF5LlxuICAgICAgICBpZiAoIWlucHV0RmlsdGVyLnRpbWV6b25lKSB7XG4gICAgICAgICAgZmlsdGVyU3RhcnQgPSBTWVNURU1fREFURV9USU1FWk9ORV9VVENfTk9STUFMX0lOU1RBTkNFLnN0YXJ0T2ZEYXlJblRhcmdldFRpbWV6b25lKGlucHV0RmlsdGVyLnN0YXJ0c0F0KTtcbiAgICAgICAgICBuZXh0RmlsdGVyVGltZXpvbmUgPSBzeXN0ZW1UaW1lem9uZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXh0RmlsdGVyVGltZXpvbmUgPSBpbnB1dEZpbHRlci50aW1lem9uZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChpbnB1dEZpbHRlci5zdGFydHNBdCkge1xuICAgICAgICBpZiAoaW5wdXRGaWx0ZXIudGltZXpvbmUpIHtcbiAgICAgICAgICAvLyBpZiBubyB0aW1lem9uZSBpcyBwcm92aWRlZCwgdXNlIHN0YXJ0c0F0IGFzLWlzXG4gICAgICAgICAgY29uc3QgdGltZXpvbmVOb3JtYWwgPSBkYXRlVGltZXpvbmVVdGNOb3JtYWwoaW5wdXRGaWx0ZXIudGltZXpvbmUpO1xuICAgICAgICAgIGZpbHRlclN0YXJ0ID0gdGltZXpvbmVOb3JtYWwuc3RhcnRPZkRheUluVGFyZ2V0VGltZXpvbmUoaW5wdXRGaWx0ZXIuc3RhcnRzQXQpO1xuICAgICAgICAgIG5leHRGaWx0ZXJUaW1lem9uZSA9IGlucHV0RmlsdGVyLnRpbWV6b25lO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIHNldCB0byB0aGUgc3RhcnQgb2YgdG9kYXkgaW4gdGhlIHN5c3RlbSB0aW1lem9uZS5cbiAgICAgICAgICBmaWx0ZXJTdGFydCA9IFNZU1RFTV9EQVRFX1RJTUVaT05FX1VUQ19OT1JNQUxfSU5TVEFOQ0Uuc3RhcnRPZkRheUluVGFyZ2V0VGltZXpvbmUoaW5wdXRGaWx0ZXIuc3RhcnRzQXQpO1xuICAgICAgICAgIG5leHRGaWx0ZXJUaW1lem9uZSA9IHN5c3RlbVRpbWV6b25lO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZpbHRlci5zdGFydCA9IGZpbHRlclN0YXJ0ID8/IHVuZGVmaW5lZDtcbiAgICAgIGZpbHRlci50aW1lem9uZSA9IG5leHRGaWx0ZXJUaW1lem9uZTtcblxuICAgICAgLy8gY29uZmlndXJlIGV4Y2x1c2lvbnNcbiAgICAgIGlmIChleGNsdXNpb25zPy5sZW5ndGgpIHtcbiAgICAgICAgZW5hYmxlZEZpbHRlciA9IHtcbiAgICAgICAgICAuLi5maWx0ZXIsXG4gICAgICAgICAgZXg6IHVuaXF1ZShtZXJnZUFycmF5cyhbZmlsdGVyLmV4LCBleGNsdXNpb25zXSkpXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbmFibGVkRmlsdGVyID0gZmlsdGVyO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBlbmFibGVkRmlsdGVyID0ge1xuICAgICAgICB3OiAnODknLFxuICAgICAgICBleDogZXhjbHVzaW9ucyBhcyBudW1iZXJbXVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAobWluTWF4RGF0ZVJhbmdlKSB7XG4gICAgICBlbmFibGVkRmlsdGVyLm1pbk1heERhdGVSYW5nZSA9IG1pbk1heERhdGVSYW5nZTtcbiAgICAgIGVuYWJsZWRGaWx0ZXIuc2V0U3RhcnRBc01pbkRhdGUgPSBmaWx0ZXJTdGFydCA/IHRydWUgOiBmYWxzZTsgLy8gSWYgYSBzdGFydCBkYXRlIGlzIHNldCwgdGhlbiBpdCBiZWNvbWVzIHRoZSBmbG9vci5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgaW5wdXQgZmlsdGVyIGhhcyBhIHN0YXJ0IGRhdGUsIHVzZSB0aGF0IGFzIHRoZSByZWxhdGl2ZSBzdGFydCB0byBlbnN1cmUgaW5kZXhlcyBhcmUgY29tcGFyZWQgdGhlIHNhbWUsXG4gICAgICogb3RoZXJ3aXNlIHVzZSB0aGUgc3RhdGUncyBzdGFydC4gVGhpcyBpcyBpbXBvcnRhbnQgZm9yIHRoZSBpbmRleCBjYWxjdWxhdGlvbnMuXG4gICAgICovXG4gICAgbGV0IGZpbmFsRW5hYmxlZFN0YXJ0OiBEYXRlO1xuICAgIGxldCBmaW5hbEVuYWJsZWRUaW1lem9uZTogVGltZXpvbmVTdHJpbmc7XG4gICAgLy8gIGZpbHRlcj8uc3RhcnQgPz8gc3RhdGUuc3RhcnQ7XG5cbiAgICBpZiAoIWVuYWJsZWRGaWx0ZXIuc3RhcnQpIHtcbiAgICAgIC8vIHVzZSB0aGUgY3VycmVudCBzdGF0ZSdzIHN0YXJ0LCBidXQgbWFrZSBzdXJlIGl0IGlzIGluIHRoZSBwcm9wZXIgdGltZXpvbmUuXG4gICAgICBpZiAoZW5hYmxlZEZpbHRlci50aW1lem9uZSkge1xuICAgICAgICBjb25zdCB0aW1lem9uZU5vcm1hbCA9IGRhdGVUaW1lem9uZVV0Y05vcm1hbChlbmFibGVkRmlsdGVyLnRpbWV6b25lKTtcbiAgICAgICAgZmluYWxFbmFibGVkU3RhcnQgPSB0aW1lem9uZU5vcm1hbC5zdGFydE9mRGF5SW5UYXJnZXRUaW1lem9uZShjdXJyZW50U3RhdGUuc3RhcnQpOyAvLyBnZXQgdGhlIHN0YXJ0IG9mIHRoZSBkYXkgZm9yIHRoZSBjdXJyZW50IHN0YXJ0XG4gICAgICAgIGZpbmFsRW5hYmxlZFRpbWV6b25lID0gZW5hYmxlZEZpbHRlci50aW1lem9uZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZpbmFsRW5hYmxlZFN0YXJ0ID0gY3VycmVudFN0YXRlLnN0YXJ0O1xuICAgICAgICBmaW5hbEVuYWJsZWRUaW1lem9uZSA9IHN5c3RlbVRpbWV6b25lO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIWVuYWJsZWRGaWx0ZXIudGltZXpvbmUpIHtcbiAgICAgIGZpbmFsRW5hYmxlZFRpbWV6b25lID0gc3lzdGVtVGltZXpvbmU7XG5cbiAgICAgIGNvbnN0IHRpbWV6b25lTm9ybWFsID0gZGF0ZVRpbWV6b25lVXRjTm9ybWFsKGZpbmFsRW5hYmxlZFRpbWV6b25lKTtcbiAgICAgIGZpbmFsRW5hYmxlZFN0YXJ0ID0gdGltZXpvbmVOb3JtYWwuc3RhcnRPZkRheUluVGFyZ2V0VGltZXpvbmUoZW5hYmxlZEZpbHRlci5zdGFydCk7IC8vIGdldCB0aGUgc3RhcnQgb2YgdGhlIGRheSBmb3IgdGhlIHRhcmdldCB0aW1lem9uZVxuICAgIH0gZWxzZSB7XG4gICAgICBmaW5hbEVuYWJsZWRTdGFydCA9IGVuYWJsZWRGaWx0ZXIuc3RhcnQ7XG4gICAgICBmaW5hbEVuYWJsZWRUaW1lem9uZSA9IGVuYWJsZWRGaWx0ZXIudGltZXpvbmU7XG4gICAgfVxuXG4gICAgZW5hYmxlZEZpbHRlci5zdGFydCA9IGZpbmFsRW5hYmxlZFN0YXJ0O1xuICAgIGVuYWJsZWRGaWx0ZXIudGltZXpvbmUgPSBmaW5hbEVuYWJsZWRUaW1lem9uZTtcblxuICAgIC8vIGNyZWF0ZSB0aGUgZmlsdGVyXG4gICAgaXNFbmFibGVkRmlsdGVyRGF5ID0gZGF0ZUNlbGxTY2hlZHVsZURhdGVGaWx0ZXIoZW5hYmxlZEZpbHRlcik7XG4gIH1cblxuICBsZXQgbmV4dFN0YXRlOiBCdWlsZGluZzxDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGU+ID0geyAuLi5jdXJyZW50U3RhdGUsIGZpbHRlciwgaXNFbmFibGVkRmlsdGVyRGF5IH07XG5cbiAgLy8gRm9yIHRoZSBzYW1lIHJlYXNvbiBhcyBhYm92ZSwgdXNlIHRoZSBmaWx0ZXIncyBzdGFydCBkYXRlIGFzIHRoZSByZWxhdGl2ZSBzdGFydCBpZiBhcHBsaWNhYmxlLlxuICBpZiAoZmlsdGVyICYmIGZpbHRlci5zdGFydCkge1xuICAgIGxldCBzdGFydEZvclN5c3RlbVRpbWV6b25lOiBEYXRlID0gZmlsdGVyLnN0YXJ0O1xuXG4gICAgaWYgKGZpbHRlci50aW1lem9uZSkge1xuICAgICAgY29uc3QgdGltZXpvbmVOb3JtYWwgPSBkYXRlVGltZXpvbmVVdGNOb3JtYWwoZmlsdGVyLnRpbWV6b25lKTtcbiAgICAgIHN0YXJ0Rm9yU3lzdGVtVGltZXpvbmUgPSB0aW1lem9uZU5vcm1hbC5zeXN0ZW1EYXRlVG9UYXJnZXREYXRlKGZpbHRlci5zdGFydCk7IC8vIGdldCB0aGUgc3RhcnQgb2YgdGhlIGRheSBmb3IgdGhlIHN5c3RlbSB0aW1lem9uZVxuICAgIH1cblxuICAgIG5leHRTdGF0ZS5zdGFydCA9IHN0YXJ0Rm9yU3lzdGVtVGltZXpvbmU7XG4gICAgbmV4dFN0YXRlLmluZGV4RmFjdG9yeSA9IGRhdGVDZWxsVGltaW5nUmVsYXRpdmVJbmRleEZhY3RvcnkoeyBzdGFydHNBdDogc3RhcnRGb3JTeXN0ZW1UaW1lem9uZSwgdGltZXpvbmU6IHN5c3RlbVRpbWV6b25lIH0pO1xuICAgIG5leHRTdGF0ZS5pbmRleERheU9mV2VlayA9IGRhdGVDZWxsRGF5T2ZXZWVrRmFjdG9yeShzdGFydEZvclN5c3RlbVRpbWV6b25lKTtcbiAgfVxuXG4gIC8vIGF0dGVtcHQgdG8gcmUtYXBwbHkgdGhlIGluaXRpYWwgc2VsZWN0aW9uIHN0YXRlIG9uY2UgZmlsdGVyIGlzIGFwcGxpZWRcbiAgaWYgKG5leHRTdGF0ZS5pbml0aWFsU2VsZWN0aW9uU3RhdGUpIHtcbiAgICBuZXh0U3RhdGUgPSB1cGRhdGVTdGF0ZVdpdGhJbml0aWFsU2VsZWN0aW9uU3RhdGUobmV4dFN0YXRlIGFzIENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSwgbmV4dFN0YXRlLmluaXRpYWxTZWxlY3Rpb25TdGF0ZSk7XG4gIH1cblxuICAvLyByZS1jYWxjdWxhdGUgdGhlIHNlbGVjdGlvbiBnaXZlbiB0aGUgZmlsdGVyXG4gIGNvbnN0IHsgaW5wdXRTdGFydCwgaW5wdXRFbmQgfSA9IG5leHRTdGF0ZTtcblxuICBpZiAoaW5wdXRTdGFydCAmJiBpbnB1dEVuZCkge1xuICAgIG5leHRTdGF0ZSA9IHVwZGF0ZVN0YXRlV2l0aENoYW5nZWRSYW5nZShuZXh0U3RhdGUgYXMgQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlLCB7IGlucHV0U3RhcnQsIGlucHV0RW5kIH0pO1xuICB9XG5cbiAgcmV0dXJuIG5leHRTdGF0ZSBhcyBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVTdGF0ZVdpdGhUaW1lem9uZVZhbHVlKHN0YXRlOiBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUsIHRpbWV6b25lOiBNYXliZTxUaW1lem9uZVN0cmluZz4pOiBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUge1xuICBjb25zdCB7IGN1cnJlbnRTZWxlY3Rpb25WYWx1ZSB9ID0gc3RhdGU7XG4gIGNvbnN0IHRpbWV6b25lTm9ybWFsID0gdGltZXpvbmUgPyBkYXRlVGltZXpvbmVVdGNOb3JtYWwoeyB0aW1lem9uZSB9KSA6IHVuZGVmaW5lZDtcblxuICBpZiAodGltZXpvbmVOb3JtYWwgJiYgY3VycmVudFNlbGVjdGlvblZhbHVlKSB7XG4gICAgLy8gdXBkYXRlIHRoZSBzZWxlY3Rpb24gdmFsdWUgdG8gcmVmbGVjdCB0aGUgdGltZXpvbmUgY2hhbmdlcy5cbiAgICBjb25zdCB7IGRhdGVTY2hlZHVsZVJhbmdlOiBjdXJyZW50RGF0ZUNlbGxTY2hlZHVsZVJhbmdlIH0gPSBjdXJyZW50U2VsZWN0aW9uVmFsdWU7XG4gICAgY29uc3Qgc3RhcnQgPSB0aW1lem9uZU5vcm1hbC50YXJnZXREYXRlVG9TeXN0ZW1EYXRlKGN1cnJlbnREYXRlQ2VsbFNjaGVkdWxlUmFuZ2Uuc3RhcnQpO1xuICAgIGNvbnN0IGVuZCA9IHRpbWV6b25lTm9ybWFsLnRhcmdldERhdGVUb1N5c3RlbURhdGUoY3VycmVudERhdGVDZWxsU2NoZWR1bGVSYW5nZS5lbmQpO1xuXG4gICAgY29uc3QgbmV3UmFuZ2U6IERhdGVDZWxsU2NoZWR1bGVEYXRlUmFuZ2UgPSB7XG4gICAgICAuLi5jdXJyZW50U2VsZWN0aW9uVmFsdWUuZGF0ZVNjaGVkdWxlUmFuZ2UsXG4gICAgICBzdGFydCxcbiAgICAgIGVuZFxuICAgIH07XG5cbiAgICByZXR1cm4gdXBkYXRlU3RhdGVXaXRoRGF0ZUNlbGxTY2hlZHVsZVJhbmdlVmFsdWUoeyAuLi5zdGF0ZSwgb3V0cHV0VGltZXpvbmU6IHRpbWV6b25lLCBvdXRwdXRUaW1lem9uZU5vcm1hbDogdGltZXpvbmVOb3JtYWwgfSwgbmV3UmFuZ2UpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB7IC4uLnN0YXRlLCBvdXRwdXRUaW1lem9uZTogdGltZXpvbmUsIG91dHB1dFRpbWV6b25lTm9ybWFsOiB0aW1lem9uZU5vcm1hbCB9OyAvLyBubyBjaGFuZ2UgaW4gdmFsdWVcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlU3RhdGVXaXRoRGF0ZUNlbGxTY2hlZHVsZVJhbmdlVmFsdWUoc3RhdGU6IENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSwgaW5wdXRDaGFuZ2U6IE1heWJlPEZ1bGxEYXRlQ2VsbFNjaGVkdWxlUmFuZ2VJbnB1dERhdGVSYW5nZT4pOiBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUge1xuICBjb25zdCB7IGN1cnJlbnRTZWxlY3Rpb25WYWx1ZSwgc3lzdGVtVGltZXpvbmUgfSA9IHN0YXRlO1xuICBjb25zdCBjdXJyZW50RGF0ZUNlbGxTY2hlZHVsZVJhbmdlID0gY3VycmVudFNlbGVjdGlvblZhbHVlPy5kYXRlU2NoZWR1bGVSYW5nZTsgLy8gY3VycmVudCByYW5nZSBpcyBhbHdheXMgaW4gc3lzdGVtIHRpbWVcbiAgbGV0IGNoYW5nZTogTWF5YmU8UGljazxEYXRlQ2VsbFNjaGVkdWxlRGF0ZVJhbmdlLCAnc3RhcnQnIHwgJ2VuZCcgfCAnZXgnIHwgJ3cnIHwgJ3RpbWV6b25lJz4+O1xuXG4gIC8vIFdoZW4gdXNpbmcgdGltZXpvbmVzLCBhbHdheXMgcmV0dXJuIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBkYXkuIElucHV0cyBhcmUgY29udmVydGVkIHRvIHRoZSBzeXN0ZW0gdGltZSBhbmQgdXNlZCBhcyB0aGUgc3RhcnQgb2YgdGhlIGRheS5cbiAgLy8gT3V0cHV0cyByZW1haW4gYWNjdXJhdGUuXG5cbiAgaWYgKGlucHV0Q2hhbmdlKSB7XG4gICAgLy8gbWFrZSBzdXJlIGEgdGltZXpvbmUgaXMgc2V0LiBJbnB1dCBtYXkgbm90IGhhdmUgYSB0aW1lem9uZSBhdHRhY2hlZC4gRGVmYXVsdCB0byBzeXN0ZW0gdGltZS5cbiAgICBjb25zdCBpbnB1dENoYW5nZVdpdGhUaW1lem9uZVNldCA9IHtcbiAgICAgIC4uLmlucHV0Q2hhbmdlLFxuICAgICAgdGltZXpvbmU6IGlucHV0Q2hhbmdlLnRpbWV6b25lID8/IHN5c3RlbVRpbWV6b25lXG4gICAgfTtcblxuICAgIC8vIGNhbGN1bGF0ZSB0aGUgc2NoZWR1bGUgcmFuZ2VcbiAgICBjb25zdCBmdWxsQ2hhbmdlID0gZnVsbERhdGVDZWxsU2NoZWR1bGVSYW5nZSh7IGRhdGVDZWxsU2NoZWR1bGVSYW5nZTogaW5wdXRDaGFuZ2VXaXRoVGltZXpvbmVTZXQgfSk7XG4gICAgY29uc3QgaW5wdXROb3JtYWwgPSBkYXRlQ2VsbFRpbWluZ1RpbWV6b25lTm9ybWFsSW5zdGFuY2UoZnVsbENoYW5nZSk7XG5cbiAgICBjb25zdCBzdGFydEluU3lzdGVtVHogPSBpbnB1dE5vcm1hbC5zeXN0ZW1EYXRlVG9UYXJnZXREYXRlKGZ1bGxDaGFuZ2Uuc3RhcnQpO1xuICAgIGNvbnN0IGVuZEluU3lzdGVtVHogPSBzdGFydE9mRGF5KGlucHV0Tm9ybWFsLnN5c3RlbURhdGVUb1RhcmdldERhdGUoZnVsbENoYW5nZS5lbmQpKTtcblxuICAgIC8vIGNvbnZlcnQgdGhlIHN0YXJ0L2VuZCB0byBzeXN0ZW0gdGltZVxuICAgIGNoYW5nZSA9IHtcbiAgICAgIHN0YXJ0OiBzdGFydEluU3lzdGVtVHosXG4gICAgICBlbmQ6IGVuZEluU3lzdGVtVHosXG4gICAgICB3OiBmdWxsQ2hhbmdlLncsXG4gICAgICBleDogZnVsbENoYW5nZS5leCxcbiAgICAgIHRpbWV6b25lOiBmdWxsQ2hhbmdlLnRpbWV6b25lXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IGlzU2FtZVZhbHVlID0gaXNTYW1lRGF0ZUNlbGxTY2hlZHVsZURhdGVSYW5nZShjdXJyZW50RGF0ZUNlbGxTY2hlZHVsZVJhbmdlLCBjaGFuZ2UpO1xuXG4gIGlmIChpc1NhbWVWYWx1ZSkge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfSBlbHNlIHtcbiAgICBpZiAoY2hhbmdlICE9IG51bGwpIHtcbiAgICAgIGNvbnN0IG5leHRTdGF0ZTogQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlID0geyAuLi5zdGF0ZSwgaW5wdXRTdGFydDogY2hhbmdlLnN0YXJ0LCBpbnB1dEVuZDogY2hhbmdlLmVuZCwgdG9nZ2xlZEluZGV4ZXM6IG5ldyBTZXQoY2hhbmdlLmV4KSB9O1xuICAgICAgcmV0dXJuIHVwZGF0ZVN0YXRlV2l0aENoYW5nZWRTY2hlZHVsZURheXMoZmluYWxpemVOZXdDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUobmV4dFN0YXRlKSwgZXhwYW5kRGF0ZUNlbGxTY2hlZHVsZURheUNvZGVzKGNoYW5nZS53IHx8ICc4OScpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG5vU2VsZWN0aW9uQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlKHN0YXRlKTsgLy8gY2xlYXIgc2VsZWN0aW9uLCByZXRhaW4gZGlzYWJsZWQgZGF5c1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlU3RhdGVXaXRoQ2hhbmdlZERlZmF1bHRTY2hlZHVsZURheXMoc3RhdGU6IENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSwgY2hhbmdlOiBNYXliZTxJdGVyYWJsZTxEYXRlQ2VsbFNjaGVkdWxlRGF5Q29kZT4+KTogQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlIHtcbiAgY29uc3QgeyBkZWZhdWx0U2NoZWR1bGVEYXlzOiBjdXJyZW50RGVmYXVsdFNjaGVkdWxlRGF5cyB9ID0gc3RhdGU7XG4gIGNvbnN0IGRlZmF1bHRTY2hlZHVsZURheXMgPSBuZXcgU2V0KGNoYW5nZSA/PyBmdWxsV2Vla0RhdGVDZWxsU2NoZWR1bGVEYXlDb2RlcygpKTtcblxuICBpZiAoZGF0ZUNlbGxTY2hlZHVsZURheUNvZGVzQXJlU2V0c0VxdWl2YWxlbnQoZGVmYXVsdFNjaGVkdWxlRGF5cywgY3VycmVudERlZmF1bHRTY2hlZHVsZURheXMpKSB7XG4gICAgcmV0dXJuIHN0YXRlOyAvLyBubyBjaGFuZ2VcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZmluYWxpemVVcGRhdGVTdGF0ZVdpdGhDaGFuZ2VkU2NoZWR1bGVEYXlzKHN0YXRlLCB7IC4uLnN0YXRlLCBkZWZhdWx0U2NoZWR1bGVEYXlzIH0pO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVTdGF0ZVdpdGhDaGFuZ2VkU2NoZWR1bGVEYXlzKHN0YXRlOiBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUsIGNoYW5nZTogTWF5YmU8SXRlcmFibGU8RGF0ZUNlbGxTY2hlZHVsZURheUNvZGU+Pik6IENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSB7XG4gIGNvbnN0IHsgc2NoZWR1bGVEYXlzOiBjdXJyZW50U2NoZWR1bGVEYXlzIH0gPSBzdGF0ZTtcbiAgY29uc3Qgc2NoZWR1bGVEYXlzID0gbmV3IFNldChjaGFuZ2UgPz8gW10pO1xuXG4gIGxldCBuZXdTY2hlZHVsZURheXM6IFNldDxEYXRlQ2VsbFNjaGVkdWxlRGF5Q29kZT4gfCBudWxsIHwgdW5kZWZpbmVkO1xuXG4gIGlmIChjdXJyZW50U2NoZWR1bGVEYXlzICE9IG51bGwgJiYgY2hhbmdlICE9IG51bGwpIHtcbiAgICBpZiAoZGF0ZUNlbGxTY2hlZHVsZURheUNvZGVzQXJlU2V0c0VxdWl2YWxlbnQoc2NoZWR1bGVEYXlzLCBjdXJyZW50U2NoZWR1bGVEYXlzKSkge1xuICAgICAgbmV3U2NoZWR1bGVEYXlzID0gdW5kZWZpbmVkOyAvL25vIGNoYW5nZVxuICAgIH0gZWxzZSB7XG4gICAgICBuZXdTY2hlZHVsZURheXMgPSBzY2hlZHVsZURheXM7XG4gICAgfVxuICB9IGVsc2UgaWYgKGN1cnJlbnRTY2hlZHVsZURheXMgIT09IGNoYW5nZSkge1xuICAgIG5ld1NjaGVkdWxlRGF5cyA9IGNoYW5nZSA/IHNjaGVkdWxlRGF5cyA6IG51bGw7IC8vIHNldCB0aGUgbmV3IG9uZSwgb3IgY2xlYXIgaXRcbiAgfVxuXG4gIGlmIChuZXdTY2hlZHVsZURheXMgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZmluYWxpemVVcGRhdGVTdGF0ZVdpdGhDaGFuZ2VkU2NoZWR1bGVEYXlzKHN0YXRlLCB7IC4uLnN0YXRlLCBzY2hlZHVsZURheXM6IG5ld1NjaGVkdWxlRGF5cyA/PyB1bmRlZmluZWQgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVN0YXRlV2l0aFNlbGVjdGlvbk1vZGUoc3RhdGU6IENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSwgc2VsZWN0aW9uTW9kZTogRGJ4Q2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0b3JlU2VsZWN0aW9uTW9kZSk6IENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSB7XG4gIGNvbnN0IHsgc2VsZWN0aW9uTW9kZTogY3VycmVudFNlbGVjdGlvbk1vZGUgfSA9IHN0YXRlO1xuXG4gIGlmIChjdXJyZW50U2VsZWN0aW9uTW9kZSAhPT0gc2VsZWN0aW9uTW9kZSkge1xuICAgIGNvbnN0IG5leHRTdGF0ZSA9IHsgLi4uc3RhdGUsIHNlbGVjdGlvbk1vZGUgfTtcblxuICAgIGlmIChzZWxlY3Rpb25Nb2RlID09PSAnbXVsdGlwbGUnKSB7XG4gICAgICByZXR1cm4gbmV4dFN0YXRlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBjdXJyZW50U2VsZWN0aW9uUmFuZ2UgPSBjb21wdXRlQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvbkRhdGVDZWxsUmFuZ2UobmV4dFN0YXRlKTtcbiAgICAgIHJldHVybiBjdXJyZW50U2VsZWN0aW9uUmFuZ2UgPyB1cGRhdGVTdGF0ZVdpdGhDaGFuZ2VkRGF0ZXMobmV4dFN0YXRlLCB7IHNldDogW2N1cnJlbnRTZWxlY3Rpb25SYW5nZS5pXSwgaW52ZXJ0U2V0QmVoYXZpb3I6IHRydWUgfSkgOiBuZXh0U3RhdGU7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZmluYWxpemVVcGRhdGVTdGF0ZVdpdGhDaGFuZ2VkU2NoZWR1bGVEYXlzKHByZXZpb3VzU3RhdGU6IENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSwgbmV4dFN0YXRlOiBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUpOiBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUge1xuICBjb25zdCBwcmV2aW91c1NjaGVkdWxlRGF5cyA9IHByZXZpb3VzU3RhdGUuZWZmZWN0aXZlU2NoZWR1bGVEYXlzO1xuICBjb25zdCBuZXh0U2NoZWR1bGVEYXlzID0gbmV4dFN0YXRlLnNjaGVkdWxlRGF5cyA/PyBuZXh0U3RhdGUuZGVmYXVsdFNjaGVkdWxlRGF5cztcblxuICBpZiAoZGF0ZUNlbGxTY2hlZHVsZURheUNvZGVzQXJlU2V0c0VxdWl2YWxlbnQobmV4dFNjaGVkdWxlRGF5cywgcHJldmlvdXNTY2hlZHVsZURheXMpKSB7XG4gICAgcmV0dXJuIG5leHRTdGF0ZTsgLy8gdGhlIGRlZmF1bHQgb3IgaW5wdXQgc2NoZWR1bGUgY2hhbmdlZCBidXQgdGhlIHNjaGVkdWxlIGlzIHN0aWxsIHRoZSBzYW1lLCBzbyBubyBuZWVkIGZvciBhbiB1cGRhdGUuXG4gIH0gZWxzZSB7XG4gICAgY29uc3QgZWZmZWN0aXZlU2NoZWR1bGVEYXlzID0gbmV3IFNldChzaW1wbGlmeURhdGVDZWxsU2NoZWR1bGVEYXlDb2RlcyhuZXh0U2NoZWR1bGVEYXlzKSk7XG4gICAgY29uc3QgYWxsb3dlZERheXNPZldlZWsgPSBleHBhbmREYXRlQ2VsbFNjaGVkdWxlRGF5Q29kZXNUb0RheU9mV2Vla1NldChuZXh0U2NoZWR1bGVEYXlzKTtcblxuICAgIHJldHVybiBmaW5hbGl6ZU5ld0NhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSh7XG4gICAgICAuLi5uZXh0U3RhdGUsXG4gICAgICAvLyB1cGRhdGUgdGhlIGVmZmVjdGl2ZSBzY2hlZHVsZSBkYXlzIGFuZCBhbGxvd2VkIGRheXMgb2Ygd2Vla1xuICAgICAgZWZmZWN0aXZlU2NoZWR1bGVEYXlzLFxuICAgICAgYWxsb3dlZERheXNPZldlZWtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZURhdGVzQ2hhbmdlIHtcbiAgcmVzZXQ/OiB0cnVlO1xuICB0b2dnbGU/OiBJdGVyYWJsZU9yVmFsdWU8RGF0ZUNlbGxUaW1pbmdSZWxhdGl2ZUluZGV4RmFjdG9yeUlucHV0PjtcbiAgYWRkPzogSXRlcmFibGVPclZhbHVlPERhdGVDZWxsVGltaW5nUmVsYXRpdmVJbmRleEZhY3RvcnlJbnB1dD47XG4gIHJlbW92ZT86IEl0ZXJhYmxlT3JWYWx1ZTxEYXRlQ2VsbFRpbWluZ1JlbGF0aXZlSW5kZXhGYWN0b3J5SW5wdXQ+O1xuICBzZXQ/OiBJdGVyYWJsZU9yVmFsdWU8RGF0ZUNlbGxUaW1pbmdSZWxhdGl2ZUluZGV4RmFjdG9yeUlucHV0PjtcbiAgc2VsZWN0QWxsPzogQWxsT3JOb25lU2VsZWN0aW9uO1xuICAvKipcbiAgICogSW52ZXJ0cyB0aGUgc2V0IGRhdGUgY2hhbmdpbmcgYmVoYXZpb3Igc28gdGhhdCB0aGUgc2V0IGlucHV0IGlzIHRyZWF0ZWQgYXMgaXRlbXMgdGhhdCBzaG91bGQgYmUgcmV0YWluZWQgaW5zdGVhZCBvZiBleGNsdWRlZC5cbiAgICpcbiAgICogSWdub3JlZCB3aGVuIHNldCBpcyBub3QgdXNlZC4gSWdub3JlZCBmb3Igc2VsZWN0QWxsLlxuICAgKi9cbiAgaW52ZXJ0U2V0QmVoYXZpb3I/OiBib29sZWFuO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlU3RhdGVXaXRoQ2hhbmdlZERhdGVzKHN0YXRlOiBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUsIGNoYW5nZTogQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlRGF0ZXNDaGFuZ2UpOiBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUge1xuICBjb25zdCB7IHNlbGVjdGlvbk1vZGUsIGFsbG93ZWREYXlzT2ZXZWVrLCBpbmRleEZhY3RvcnksIGluZGV4RGF5T2ZXZWVrLCBpbnB1dFN0YXJ0OiBjdXJyZW50SW5wdXRTdGFydCwgaW5wdXRFbmQ6IGN1cnJlbnRJbnB1dEVuZCwgbWluTWF4RGF0ZVJhbmdlLCBmaWx0ZXIgfSA9IHN0YXRlO1xuICBjb25zdCB7IHN0YXJ0OiBtaW5EYXRlRnJvbUZpbHRlciwgZW5kOiBtYXhEYXRlRnJvbUZpbHRlciB9ID0gY2FsZW5kYXJTY2hlZHVsZU1pbkFuZE1heERhdGVSYW5nZVJlbGF0aXZlVG9GaWx0ZXIoc3RhdGUpO1xuICBsZXQgaW5wdXRTdGFydCA9IGN1cnJlbnRJbnB1dFN0YXJ0O1xuICBsZXQgaW5wdXRFbmQgPSBjdXJyZW50SW5wdXRFbmQ7XG5cbiAgLyoqXG4gICAqIFRoaXMgaXMgYSBzZXQgb2YgaW5kZXhlcyB0aGF0IGFyZSBpbnRlcm5hbGx5IFwic2VsZWN0ZWRcIiBzbyB0aGF0IHRoZXkgYXJlIGV4Y2x1ZGVkIGZyb20gdGhlIGlucHV0U3RhcnQvaW5wdXRFbmQgZGF0ZSByYW5nZS5cbiAgICpcbiAgICogRG8gbm90IGNvbmZ1c2UgdGhpcyB3aXRoIHRoZSBhY3R1YWwgaW5kZXhlcyB0aGF0IGFyZSBzZWxlY3RlZC5cbiAgICovXG4gIGxldCB0b2dnbGVkSW5kZXhlczogU2V0PERhdGVDZWxsSW5kZXg+O1xuXG4gIGZ1bmN0aW9uIGFzSW5kZXhlcyhpbmRleGVzOiBJdGVyYWJsZU9yVmFsdWU8RGF0ZUNlbGxUaW1pbmdSZWxhdGl2ZUluZGV4RmFjdG9yeUlucHV0Pik6IERhdGVDZWxsSW5kZXhbXSB7XG4gICAgcmV0dXJuIGl0ZXJhYmxlVG9BcnJheShpbmRleGVzKS5tYXAoaW5kZXhGYWN0b3J5KTtcbiAgfVxuXG4gIC8vIFdoZW4gdXNpbmcgc2VsZWN0aW9uIG1vZGUgXCJzaW5nbGVcIiB3ZSB1cGRhdGUgdGhlIGNoYW5nZSB0byByZWZsZWN0IHRoZSBzaW5nbGUgc2VsZWN0aW9uLlxuICBpZiAoc2VsZWN0aW9uTW9kZSA9PT0gJ3NpbmdsZScpIHtcbiAgICBmdW5jdGlvbiBzZXRGcm9tRmlyc3RWYWx1ZShpbnB1dDogSXRlcmFibGVPclZhbHVlPERhdGVDZWxsVGltaW5nUmVsYXRpdmVJbmRleEZhY3RvcnlJbnB1dD4pOiBTZXQ8RGF0ZUNlbGxUaW1pbmdSZWxhdGl2ZUluZGV4RmFjdG9yeUlucHV0PiB7XG4gICAgICBjb25zdCBmaXJzdFZhbHVlID0gaXNJdGVyYWJsZShpbnB1dCkgPyBmaXJzdFZhbHVlRnJvbUl0ZXJhYmxlKGlucHV0KSA6IGlucHV0O1xuICAgICAgY29uc3Qgc2V0ID0gbmV3IFNldDxEYXRlQ2VsbFRpbWluZ1JlbGF0aXZlSW5kZXhGYWN0b3J5SW5wdXQ+KCk7XG5cbiAgICAgIGlmIChmaXJzdFZhbHVlICE9IG51bGwpIHtcbiAgICAgICAgc2V0LmFkZChmaXJzdFZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNldDtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlLnNldCkge1xuICAgICAgY2hhbmdlID0geyBzZXQ6IHNldEZyb21GaXJzdFZhbHVlKGNoYW5nZS5zZXQpLCBpbnZlcnRTZXRCZWhhdmlvcjogdHJ1ZSB9O1xuICAgIH0gZWxzZSBpZiAoY2hhbmdlLnRvZ2dsZSkge1xuICAgICAgY29uc3QgbmV4dFNldCA9IHNldEZyb21GaXJzdFZhbHVlKGNoYW5nZS50b2dnbGUpO1xuXG4gICAgICBpZiAobmV4dFNldC5zaXplKSB7XG4gICAgICAgIGNvbnN0IGZpcnN0U2V0VmFsdWVJbmRleCA9IGluZGV4RmFjdG9yeShmaXJzdFZhbHVlRnJvbUl0ZXJhYmxlKG5leHRTZXQpIGFzIERhdGVDZWxsVGltaW5nUmVsYXRpdmVJbmRleEZhY3RvcnlJbnB1dCk7XG5cbiAgICAgICAgaWYgKHN0YXRlLnRvZ2dsZWRJbmRleGVzLmhhcyhmaXJzdFNldFZhbHVlSW5kZXgpIHx8IChpbnB1dFN0YXJ0ICYmIGluZGV4RmFjdG9yeShpbnB1dFN0YXJ0KSA9PT0gZmlyc3RTZXRWYWx1ZUluZGV4KSkge1xuICAgICAgICAgIG5leHRTZXQuY2xlYXIoKTsgLy8gY2xlYXIgd2l0aCB0aGUgbmV4dCBzZXRcbiAgICAgICAgfVxuXG4gICAgICAgIGNoYW5nZSA9IHsgc2V0OiBuZXh0U2V0LCBpbnZlcnRTZXRCZWhhdmlvcjogdHJ1ZSB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNldCwgc2VsZWN0QWxsLCBhZGQsIGFuZCByZW1vdmUgYXJlIHRyZWF0ZWQgYXMgdGhleSBub3JtYWxseSBhcmUuXG4gIH1cblxuICBpZiAoY2hhbmdlLnJlc2V0IHx8IGNoYW5nZS5zZWxlY3RBbGwgIT0gbnVsbCB8fCBjaGFuZ2Uuc2V0ICE9IG51bGwpIHtcbiAgICBsZXQgc2V0OiBNYXliZTxJdGVyYWJsZU9yVmFsdWU8RGF0ZUNlbGxUaW1pbmdSZWxhdGl2ZUluZGV4RmFjdG9yeUlucHV0Pj4gPSBjaGFuZ2Uuc2V0ID8/IFtdO1xuICAgIGNvbnN0IHNlbGVjdEFsbDogTWF5YmU8QWxsT3JOb25lU2VsZWN0aW9uPiA9IGNoYW5nZS5yZXNldCA9PT0gdHJ1ZSA/IHN0YXRlLmluaXRpYWxTZWxlY3Rpb25TdGF0ZSA6IGNoYW5nZS5zZWxlY3RBbGw7XG5cbiAgICBzd2l0Y2ggKHNlbGVjdEFsbCkge1xuICAgICAgY2FzZSAnYWxsJzpcbiAgICAgICAgaWYgKG1pbkRhdGVGcm9tRmlsdGVyICE9IG51bGwgJiYgbWF4RGF0ZUZyb21GaWx0ZXIgIT0gbnVsbCkge1xuICAgICAgICAgIGlucHV0U3RhcnQgPSBtaW5EYXRlRnJvbUZpbHRlcjtcbiAgICAgICAgICBpbnB1dEVuZCA9IG1heERhdGVGcm9tRmlsdGVyO1xuICAgICAgICAgIHNldCA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbm9uZSc6XG4gICAgICAgIGlucHV0U3RhcnQgPSBudWxsO1xuICAgICAgICBpbnB1dEVuZCA9IG51bGw7XG4gICAgICAgIHNldCA9IFtdO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBjb25zdCBpbnB1dFNldEluZGV4ZXMgPSBhc0luZGV4ZXMoc2V0KTtcbiAgICB0b2dnbGVkSW5kZXhlcyA9IG5ldyBTZXQoaW5wdXRTZXRJbmRleGVzKTtcblxuICAgIGlmIChjaGFuZ2UuaW52ZXJ0U2V0QmVoYXZpb3IgJiYgIXNlbGVjdEFsbCkge1xuICAgICAgbGV0IG1pbkluZGV4OiBNYXliZTxudW1iZXI+O1xuICAgICAgbGV0IG1heEluZGV4OiBNYXliZTxudW1iZXI+O1xuXG4gICAgICBpZiAobWluRGF0ZUZyb21GaWx0ZXIgIT0gbnVsbCAmJiBtYXhEYXRlRnJvbUZpbHRlciAhPSBudWxsKSB7XG4gICAgICAgIC8vIG9ubHkgYXBwbGljYWJsZSB3aGVuIHRoZSBmaWx0ZXIgaXMgc2V0LlxuICAgICAgICBtaW5JbmRleCA9IGluZGV4RmFjdG9yeShtaW5EYXRlRnJvbUZpbHRlcik7XG4gICAgICAgIG1heEluZGV4ID0gaW5kZXhGYWN0b3J5KG1heERhdGVGcm9tRmlsdGVyKTtcblxuICAgICAgICBpbnB1dFN0YXJ0ID0gbWluRGF0ZUZyb21GaWx0ZXI7XG4gICAgICAgIGlucHV0RW5kID0gbWF4RGF0ZUZyb21GaWx0ZXI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyB3aGVuIHRoZSBmaWx0ZXIgaXMgbm90IHNldCwgdXNlIHRoZSBsZWFzdCBhbmQgZ3JlYXRlc3QgaW5kZXhlcyBmcm9tIHRoZSBpbnB1dCBzZXQuXG4gICAgICAgIGNvbnN0IG1pbkFuZE1heCA9IG1pbkFuZE1heE51bWJlcihpbnB1dFNldEluZGV4ZXMpO1xuXG4gICAgICAgIGlmIChtaW5BbmRNYXggIT0gbnVsbCkge1xuICAgICAgICAgIG1pbkluZGV4ID0gbWluQW5kTWF4Lm1pbjtcbiAgICAgICAgICBtYXhJbmRleCA9IG1pbkFuZE1heC5tYXg7XG4gICAgICAgICAgY29uc3QgZGF0ZUZhY3RvcnkgPSBkYXRlQ2VsbFRpbWluZ1N0YXJ0RGF0ZUZhY3RvcnkoaW5kZXhGYWN0b3J5Ll90aW1pbmcpO1xuXG4gICAgICAgICAgaW5wdXRTdGFydCA9IGRhdGVGYWN0b3J5KG1pbkFuZE1heC5taW4pO1xuICAgICAgICAgIGlucHV0RW5kID0gbWluQW5kTWF4Lm1pbiA9PT0gbWluQW5kTWF4Lm1heCA/IGlucHV0U3RhcnQgOiBkYXRlRmFjdG9yeShtaW5BbmRNYXgubWF4KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBlcXVpdmFsZW50IHRvIGFuIGVtcHR5IHNldCAvIHVzaW5nIFwibm9uZVwiIHdpdGggc2VsZWN0QWxsLlxuICAgICAgICAgIGlucHV0U3RhcnQgPSBudWxsO1xuICAgICAgICAgIGlucHV0RW5kID0gbnVsbDtcbiAgICAgICAgICB0b2dnbGVkSW5kZXhlcyA9IG5ldyBTZXQoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyB0b2dnbGVkSW5kZXhlcyBzaG91bGQgbm90IGluY2x1ZGUgYW55IGluZGV4ZXMgd2Ugd2FudCB0byBpbmNsdWRlXG4gICAgICBpZiAobWluSW5kZXggIT0gbnVsbCAmJiBtYXhJbmRleCAhPSBudWxsKSB7XG4gICAgICAgIHRvZ2dsZWRJbmRleGVzID0gbmV3IFNldChyYW5nZShtaW5JbmRleCwgbWF4SW5kZXggKyAxKS5maWx0ZXIoKHgpID0+ICF0b2dnbGVkSW5kZXhlcy5oYXMoeCkpKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdG9nZ2xlZEluZGV4ZXMgPSBuZXcgU2V0KHN0YXRlLnRvZ2dsZWRJbmRleGVzKTsgLy8gY29weSB0aGUgc2V0XG5cbiAgICBpZiAoY2hhbmdlLnRvZ2dsZSkge1xuICAgICAgY29uc3QgYWxsb3dlZFRvVG9nZ2xlID0gYXNJbmRleGVzKGNoYW5nZS50b2dnbGUpLmZpbHRlcigoaSkgPT4gYWxsb3dlZERheXNPZldlZWsuaGFzKGluZGV4RGF5T2ZXZWVrKGkpKSk7XG4gICAgICB0b2dnbGVJblNldCh0b2dnbGVkSW5kZXhlcywgYWxsb3dlZFRvVG9nZ2xlKTtcbiAgICB9XG5cbiAgICBsZXQgYWRkVG9FeGNsdXNpb246IE1heWJlPEl0ZXJhYmxlT3JWYWx1ZTxEYXRlQ2VsbFRpbWluZ1JlbGF0aXZlSW5kZXhGYWN0b3J5SW5wdXQ+PjtcbiAgICBsZXQgcmVtb3ZlRnJvbUV4Y2x1c2lvbjogTWF5YmU8SXRlcmFibGVPclZhbHVlPERhdGVDZWxsVGltaW5nUmVsYXRpdmVJbmRleEZhY3RvcnlJbnB1dD4+O1xuXG4gICAgaWYgKGNoYW5nZS5hZGQpIHtcbiAgICAgIGlmIChjaGFuZ2UuaW52ZXJ0U2V0QmVoYXZpb3IpIHtcbiAgICAgICAgYWRkVG9FeGNsdXNpb24gPSBjaGFuZ2UuYWRkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVtb3ZlRnJvbUV4Y2x1c2lvbiA9IGNoYW5nZS5hZGQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZS5yZW1vdmUpIHtcbiAgICAgIGlmIChjaGFuZ2UuaW52ZXJ0U2V0QmVoYXZpb3IpIHtcbiAgICAgICAgcmVtb3ZlRnJvbUV4Y2x1c2lvbiA9IGNoYW5nZS5yZW1vdmU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhZGRUb0V4Y2x1c2lvbiA9IGNoYW5nZS5yZW1vdmU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGFkZFRvRXhjbHVzaW9uKSB7XG4gICAgICByZW1vdmVGcm9tU2V0KHRvZ2dsZWRJbmRleGVzLCBhc0luZGV4ZXMoYWRkVG9FeGNsdXNpb24pKTtcbiAgICB9XG5cbiAgICBpZiAocmVtb3ZlRnJvbUV4Y2x1c2lvbikge1xuICAgICAgYWRkVG9TZXQodG9nZ2xlZEluZGV4ZXMsIGFzSW5kZXhlcyhyZW1vdmVGcm9tRXhjbHVzaW9uKSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgbmV4dFN0YXRlID0geyAuLi5zdGF0ZSwgaW5wdXRTdGFydCwgaW5wdXRFbmQsIHRvZ2dsZWRJbmRleGVzIH07XG4gIG5leHRTdGF0ZS5pc0VuYWJsZWREYXkgPSBpc0VuYWJsZWREYXlJbkNhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZShuZXh0U3RhdGUpO1xuXG4gIC8vIFJlY2FsY3VsYXRlIHRoZSByYW5nZSBhbmQgc2ltcGxpZmllZCB0byBleGNsdXNpb25zXG4gIGNvbnN0IHJhbmdlQW5kRXhjbHVzaW9uID0gY29tcHV0ZVNjaGVkdWxlU2VsZWN0aW9uUmFuZ2VBbmRFeGNsdXNpb24obmV4dFN0YXRlKTtcblxuICBpZiAocmFuZ2VBbmRFeGNsdXNpb24pIHtcbiAgICByZXR1cm4gZmluYWxpemVOZXdDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUoeyAuLi5uZXh0U3RhdGUsIHRvZ2dsZWRJbmRleGVzOiBuZXcgU2V0KHJhbmdlQW5kRXhjbHVzaW9uLmV4Y2x1ZGVkKSwgaW5wdXRTdGFydDogcmFuZ2VBbmRFeGNsdXNpb24uc3RhcnQsIGlucHV0RW5kOiByYW5nZUFuZEV4Y2x1c2lvbi5lbmQgfSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gbm8gc2VsZWN0ZWQgZGF5c1xuICAgIHJldHVybiBub1NlbGVjdGlvbkNhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZShuZXh0U3RhdGUpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBub1NlbGVjdGlvbkNhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZShzdGF0ZTogQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlKTogQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlIHtcbiAgcmV0dXJuIGZpbmFsaXplTmV3Q2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlKHsgLi4uc3RhdGUsIHRvZ2dsZWRJbmRleGVzOiBuZXcgU2V0KCksIGlucHV0U3RhcnQ6IG51bGwsIGlucHV0RW5kOiBudWxsIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlU3RhdGVXaXRoQ2hhbmdlZFJhbmdlKHN0YXRlOiBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUsIGNoYW5nZTogQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvbklucHV0RGF0ZVJhbmdlKTogQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlIHtcbiAgY29uc3QgeyBpbnB1dFN0YXJ0OiBjdXJyZW50SW5wdXRTdGFydCwgaW5wdXRFbmQ6IGN1cnJlbnRJbnB1dEVuZCwgaW5kZXhGYWN0b3J5IH0gPSBzdGF0ZTtcbiAgY29uc3QgeyBzdGFydDogbWluRGF0ZSwgZW5kOiBtYXhEYXRlIH0gPSBjYWxlbmRhclNjaGVkdWxlTWluQW5kTWF4RGF0ZVJhbmdlKHN0YXRlKTtcblxuICBjb25zdCBpbnB1dFN0YXJ0OiBEYXRlID0gc3RhcnRPZkRheShjaGFuZ2UuaW5wdXRTdGFydCk7XG4gIGNvbnN0IGlucHV0RW5kOiBEYXRlID0gc3RhcnRPZkRheShjaGFuZ2UuaW5wdXRFbmQpOyAvLyBtaWRuaWdodCBvZiB0aGUgbGFzdCBkYXlcblxuICBjb25zdCBpc1ZhbGlkUmFuZ2UgPSBtaW5EYXRlICE9IG51bGwgfHwgbWF4RGF0ZSAhPSBudWxsID8gaXNEYXRlSW5EYXRlUmFuZ2VGdW5jdGlvbih7IHN0YXJ0OiBtaW5EYXRlID8/IHVuZGVmaW5lZCwgZW5kOiBtYXhEYXRlID8/IHVuZGVmaW5lZCB9KSA6ICgpID0+IHRydWU7XG5cbiAgaWYgKCFpc1ZhbGlkUmFuZ2UoaW5wdXRTdGFydCkgfHwgIWlzVmFsaWRSYW5nZShpbnB1dEVuZCkgfHwgKGlzU2FtZURhdGVEYXkoaW5wdXRTdGFydCwgY3VycmVudElucHV0U3RhcnQpICYmIGlzU2FtZURhdGVEYXkoaW5wdXRFbmQsIGN1cnJlbnRJbnB1dEVuZCkpKSB7XG4gICAgcmV0dXJuIHN0YXRlOyAvLyBpZiBubyBjaGFuZ2UsIHJldHVybiB0aGUgY3VycmVudCBzdGF0ZS5cbiAgfVxuXG4gIC8vIHJldGFpbiBhbGwgaW5kZXhlcyB0aGF0IGFyZSB3aXRoaW4gdGhlIG5ldyByYW5nZVxuICBjb25zdCBtaW5JbmRleCA9IGluZGV4RmFjdG9yeShpbnB1dFN0YXJ0KTtcbiAgY29uc3QgbWF4SW5kZXggPSBpbmRleEZhY3RvcnkoaW5wdXRFbmQpICsgMTtcblxuICBjb25zdCBjdXJyZW50SW5kZXhlczogRGF0ZUNlbGxJbmRleFtdID0gQXJyYXkuZnJvbShzdGF0ZS50b2dnbGVkSW5kZXhlcyk7XG4gIGNvbnN0IGlzSW5DdXJyZW50UmFuZ2UgPSBpc0luZGV4TnVtYmVySW5JbmRleFJhbmdlRnVuY3Rpb24oeyBtaW5JbmRleCwgbWF4SW5kZXggfSk7XG4gIGNvbnN0IGV4Y2x1ZGVkSW5kZXhlc0luTmV3UmFuZ2UgPSBjdXJyZW50SW5kZXhlcy5maWx0ZXIoaXNJbkN1cnJlbnRSYW5nZSk7XG4gIGNvbnN0IHRvZ2dsZWRJbmRleGVzID0gbmV3IFNldChleGNsdWRlZEluZGV4ZXNJbk5ld1JhbmdlKTtcblxuICBjb25zdCBuZXh0U3RhdGUgPSB7IC4uLnN0YXRlLCB0b2dnbGVkSW5kZXhlcywgaW5wdXRTdGFydCwgaW5wdXRFbmQgfTtcbiAgcmV0dXJuIGZpbmFsaXplTmV3Q2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlKG5leHRTdGF0ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmaW5hbGl6ZU5ld0NhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZShuZXh0U3RhdGU6IEJ1aWxkaW5nPENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZT4pOiBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUge1xuICBuZXh0U3RhdGUuaXNFbmFibGVkRGF5ID0gaXNFbmFibGVkRGF5SW5DYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUobmV4dFN0YXRlIGFzIENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSk7XG4gIG5leHRTdGF0ZS5jdXJyZW50U2VsZWN0aW9uVmFsdWUgPSBjb21wdXRlU2NoZWR1bGVTZWxlY3Rpb25WYWx1ZShuZXh0U3RhdGUgYXMgQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlKTtcbiAgcmV0dXJuIG5leHRTdGF0ZSBhcyBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0VuYWJsZWREYXlJbkNhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZShzdGF0ZTogQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblN0YXRlKTogRGVjaXNpb25GdW5jdGlvbjxEYXRlQ2VsbFRpbWluZ1JlbGF0aXZlSW5kZXhGYWN0b3J5SW5wdXQ+IHtcbiAgY29uc3QgeyBhbGxvd2VkRGF5c09mV2VlaywgaW5kZXhGYWN0b3J5LCBpbnB1dFN0YXJ0LCBpbnB1dEVuZCwgaW5kZXhEYXlPZldlZWssIHN5c3RlbVRpbWV6b25lIH0gPSBzdGF0ZTtcbiAgbGV0IGlzSW5TdGFydEFuZEVuZFJhbmdlOiBJc0RhdGVXaXRoaW5EYXRlQ2VsbFJhbmdlRnVuY3Rpb247XG5cbiAgaWYgKGlucHV0U3RhcnQgJiYgaW5wdXRFbmQpIHtcbiAgICBpc0luU3RhcnRBbmRFbmRSYW5nZSA9IGlzRGF0ZVdpdGhpbkRhdGVDZWxsUmFuZ2VGdW5jdGlvbih7IHN0YXJ0c0F0OiB7IHN0YXJ0c0F0OiBzdGF0ZS5zdGFydCwgdGltZXpvbmU6IHN5c3RlbVRpbWV6b25lIH0sIHJhbmdlOiB7IHN0YXJ0OiBpbnB1dFN0YXJ0LCBlbmQ6IGlucHV0RW5kIH0gfSk7XG4gIH0gZWxzZSB7XG4gICAgaXNJblN0YXJ0QW5kRW5kUmFuZ2UgPSAoKSA9PiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiAoaW5wdXQ6IERhdGVDZWxsVGltaW5nUmVsYXRpdmVJbmRleEZhY3RvcnlJbnB1dCkgPT4ge1xuICAgIGNvbnN0IGluZGV4ID0gaW5kZXhGYWN0b3J5KGlucHV0KTtcbiAgICBjb25zdCBkYXlPZldlZWsgPSBpbmRleERheU9mV2VlayhpbmRleCk7XG5cbiAgICBjb25zdCBpc0luU2VsZWN0ZWRSYW5nZSA9IGlzSW5TdGFydEFuZEVuZFJhbmdlKGluZGV4KTtcbiAgICBjb25zdCBpc1NlbGVjdGVkID0gc3RhdGUudG9nZ2xlZEluZGV4ZXMuaGFzKGluZGV4KTtcbiAgICBjb25zdCBpc0FsbG93ZWREYXlPZldlZWsgPSBhbGxvd2VkRGF5c09mV2Vlay5oYXMoZGF5T2ZXZWVrKTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGlzQWxsb3dlZERheU9mV2VlayAmJiAoKGlzSW5TZWxlY3RlZFJhbmdlICYmICFpc1NlbGVjdGVkKSB8fCAoaXNTZWxlY3RlZCAmJiAhaXNJblNlbGVjdGVkUmFuZ2UpKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29tcHV0ZVNjaGVkdWxlU2VsZWN0aW9uVmFsdWUoc3RhdGU6IENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSk6IE1heWJlPENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25WYWx1ZT4ge1xuICBjb25zdCB7IGluZGV4RmFjdG9yeTogc3lzdGVtSW5kZXhGYWN0b3J5LCBhbGxvd2VkRGF5c09mV2VlaywgZWZmZWN0aXZlU2NoZWR1bGVEYXlzLCBpbmRleERheU9mV2VlaywgY29tcHV0ZVNlbGVjdGlvblJlc3VsdFJlbGF0aXZlVG9GaWx0ZXIsIGZpbHRlciwgc3lzdGVtVGltZXpvbmUgfSA9IHN0YXRlO1xuICBsZXQgdGltZXpvbmUgPSBzeXN0ZW1UaW1lem9uZTtcbiAgY29uc3QgcmFuZ2VBbmRFeGNsdXNpb24gPSBjb21wdXRlU2NoZWR1bGVTZWxlY3Rpb25SYW5nZUFuZEV4Y2x1c2lvbihzdGF0ZSk7XG5cbiAgaWYgKHJhbmdlQW5kRXhjbHVzaW9uID09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHsgc3RhcnQ6IHJhbmdlU3RhcnQsIGVuZDogcmFuZ2VFbmQsIGV4Y2x1ZGVkOiBhbGxFeGNsdWRlZCwgZGF0ZUNlbGxSYW5nZSB9ID0gcmFuZ2VBbmRFeGNsdXNpb247XG4gIGxldCBmaWx0ZXJPZmZzZXRFeGNsdWRlZFJhbmdlOiBEYXRlQ2VsbEluZGV4W10gPSBbXTtcbiAgbGV0IGluZGV4T2Zmc2V0ID0gZGF0ZUNlbGxSYW5nZS5pO1xuXG4gIGxldCBzdGFydCA9IHJhbmdlU3RhcnQ7XG4gIGxldCBlbmQgPSByYW5nZUVuZDtcblxuICAvLyBJZiBjb21wdXRlU2VsZWN0aW9uUmVzdWx0UmVsYXRpdmVUb0ZpbHRlciBpcyB0cnVlLCB0aGVuIHdlIG5lZWQgdG8gb2Zmc2V0IHRoZSB2YWx1ZXMgdG8gYmUgcmVsYXRpdmUgdG8gdGhhdCBzdGFydC5cbiAgaWYgKGNvbXB1dGVTZWxlY3Rpb25SZXN1bHRSZWxhdGl2ZVRvRmlsdGVyICYmIGZpbHRlcj8uc3RhcnQpIHtcbiAgICBzdGFydCA9IGZpbHRlci5zdGFydDsgLy8gYWx3YXlzIHN0YXJ0IGF0IHRoZSBmaWx0ZXIncyBzdGFydCBkYXRlXG4gICAgbGV0IHN0YXJ0SW5TeXN0ZW1UaW1lem9uZSA9IHN0YXJ0O1xuXG4gICAgaWYgKGZpbHRlci50aW1lem9uZSkge1xuICAgICAgdGltZXpvbmUgPSBmaWx0ZXIudGltZXpvbmU7XG4gICAgICBjb25zdCBmaWx0ZXJOb3JtYWwgPSBkYXRlVGltZXpvbmVVdGNOb3JtYWwodGltZXpvbmUpO1xuICAgICAgZW5kID0gZmlsdGVyTm9ybWFsLnN0YXJ0T2ZEYXlJblRhcmdldFRpbWV6b25lKGVuZCk7XG4gICAgICBzdGFydEluU3lzdGVtVGltZXpvbmUgPSBmaWx0ZXJOb3JtYWwuc3lzdGVtRGF0ZVRvVGFyZ2V0RGF0ZShzdGFydCk7IC8vIGNvbnZlcnQgdGhlIHN0YXJ0IHRvIHRoZSBzeXN0ZW0gdGltZXpvbmUgbm9ybWFsIGZvciBkZXJpdmluZyB0aGUgaW5kZXhcbiAgICB9XG5cbiAgICBjb25zdCByYW5nZVN0YXJ0SW5kZXggPSBzeXN0ZW1JbmRleEZhY3RvcnkocmFuZ2VTdGFydCk7XG4gICAgY29uc3Qgc3RhcnRJbmRleCA9IHN5c3RlbUluZGV4RmFjdG9yeShzdGFydEluU3lzdGVtVGltZXpvbmUpO1xuICAgIGNvbnN0IGZpbHRlclN0YXJ0SW5kZXhPZmZzZXQgPSByYW5nZVN0YXJ0SW5kZXggLSBzdGFydEluZGV4O1xuICAgIGZpbHRlck9mZnNldEV4Y2x1ZGVkUmFuZ2UgPSByYW5nZSgwLCBmaWx0ZXJTdGFydEluZGV4T2Zmc2V0KTtcbiAgICBpbmRleE9mZnNldCA9IGluZGV4T2Zmc2V0IC0gZmlsdGVyU3RhcnRJbmRleE9mZnNldDtcbiAgfVxuXG4gIGNvbnN0IGV4Y2x1ZGVkID0gY29tcHV0ZVNlbGVjdGlvblJlc3VsdFJlbGF0aXZlVG9GaWx0ZXJcbiAgICA/IGFsbEV4Y2x1ZGVkLmZpbHRlcigoeCkgPT4ge1xuICAgICAgICBjb25zdCBpc0V4Y2x1ZGVkSW5kZXggPSBhbGxvd2VkRGF5c09mV2Vlay5oYXMoaW5kZXhEYXlPZldlZWsoeCkpOyAvLyA/Pz9cbiAgICAgICAgcmV0dXJuIGlzRXhjbHVkZWRJbmRleDtcbiAgICAgIH0pXG4gICAgOiBhbGxFeGNsdWRlZDtcblxuICBjb25zdCBvZmZzZXRFeGNsdWRlZDogRGF0ZUNlbGxJbmRleFtdID0gZXhjbHVkZWQubWFwKCh4KSA9PiB4IC0gaW5kZXhPZmZzZXQpOyAvLyBzZXQgdG8gdGhlIHByb3BlciBvZmZzZXRcblxuICBjb25zdCBleCA9IFsuLi5maWx0ZXJPZmZzZXRFeGNsdWRlZFJhbmdlLCAuLi5vZmZzZXRFeGNsdWRlZF07XG5cbiAgY29uc3QgdzogRGF0ZUNlbGxTY2hlZHVsZUVuY29kZWRXZWVrID0gZGF0ZUNlbGxTY2hlZHVsZUVuY29kZWRXZWVrKGVmZmVjdGl2ZVNjaGVkdWxlRGF5cyk7XG4gIGNvbnN0IGQ6IERhdGVDZWxsSW5kZXhbXSA9IFtdOyAvLyBcImluY2x1ZGVkXCIgYmxvY2tzIGFyZSBuZXZlciB1c2VkL2NhbGN1bGF0ZWQuXG5cbiAgLy8gQWx3YXlzIGVuc3VyZSB0aGUgZW5kIGlzIGFmdGVyIG9yIGVxdWFsIHRvIHRoZSBzdGFydC5cbiAgaWYgKGlzQmVmb3JlKGVuZCwgc3RhcnQpKSB7XG4gICAgZW5kID0gc3RhcnQ7IC8vIGVuZCBpcyBzdGFydFxuICB9XG5cbiAgY29uc3QgZGF0ZVNjaGVkdWxlUmFuZ2U6IERhdGVDZWxsU2NoZWR1bGVEYXRlUmFuZ2UgPSB7XG4gICAgdGltZXpvbmUsXG4gICAgc3RhcnQsXG4gICAgZW5kLFxuICAgIHcsXG4gICAgZCxcbiAgICBleFxuICB9O1xuXG4gIHJldHVybiB7XG4gICAgZGF0ZVNjaGVkdWxlUmFuZ2UsXG4gICAgbWluTWF4UmFuZ2U6IHsgc3RhcnQsIGVuZCB9XG4gIH07XG59XG5cbi8qKlxuICogVGhlIHNlbGVjdGVkIGRhdGUgcmFuZ2UgYW5kIHRoZSBjb3JyZXNwb25kaW5nIGNlbGwgcmFuZ2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblJhbmdlQW5kRXhjbHVzaW9uIGV4dGVuZHMgRGF0ZVJhbmdlIHtcbiAgLyoqXG4gICAqIENvcnJlc3BvbmRzIHRvIHRoZSBzdGFydCBhbmQgZW5kIGluZGV4ZXMgaW4gdGhlIGRhdGUgcmFuZ2UuXG4gICAqL1xuICBkYXRlQ2VsbFJhbmdlOiBEYXRlQ2VsbFJhbmdlV2l0aFJhbmdlO1xuICAvKipcbiAgICogQWxsIGV4Y2x1ZGVkIGluZGV4ZXMuXG4gICAqL1xuICBleGNsdWRlZDogRGF0ZUNlbGxJbmRleFtdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29tcHV0ZVNjaGVkdWxlU2VsZWN0aW9uUmFuZ2VBbmRFeGNsdXNpb24oc3RhdGU6IENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25TdGF0ZSk6IE1heWJlPENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25SYW5nZUFuZEV4Y2x1c2lvbj4ge1xuICBjb25zdCB7IHN0YXJ0OiBjdXJyZW50U3RhcnQsIGlzRW5hYmxlZERheSwgaXNFbmFibGVkRmlsdGVyRGF5LCBzeXN0ZW1UaW1lem9uZSB9ID0gc3RhdGU7XG5cbiAgY29uc3QgZGF0ZUZhY3RvcnkgPSBkYXRlQ2VsbFRpbWluZ1N0YXJ0RGF0ZUZhY3RvcnkoeyBzdGFydHNBdDogY3VycmVudFN0YXJ0LCB0aW1lem9uZTogc3lzdGVtVGltZXpvbmUgfSk7XG4gIGNvbnN0IGRhdGVDZWxsUmFuZ2UgPSBjb21wdXRlQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvbkRhdGVDZWxsUmFuZ2Uoc3RhdGUpO1xuXG4gIGlmIChkYXRlQ2VsbFJhbmdlID09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbDsgLy8gcmV0dXJucyBudWxsIGlmIG5vIGl0ZW1zIGFyZSBzZWxlY3RlZC5cbiAgfVxuXG4gIGNvbnN0IHN0YXJ0ID0gZGF0ZUZhY3RvcnkoZGF0ZUNlbGxSYW5nZS5pKTtcbiAgY29uc3QgZW5kID0gZGF0ZUZhY3RvcnkoZGF0ZUNlbGxSYW5nZS50byk7XG5cbiAgY29uc3QgZXhjbHVkZWQ6IERhdGVDZWxsSW5kZXhbXSA9IHJhbmdlKGRhdGVDZWxsUmFuZ2UuaSwgZGF0ZUNlbGxSYW5nZS50byArIDEpLmZpbHRlcigoeCkgPT4ge1xuICAgIGNvbnN0IGlzRXhjbHVkZWRJbmRleCA9ICFpc0VuYWJsZWREYXkoeCkgfHwgIWlzRW5hYmxlZEZpbHRlckRheSh4KTtcbiAgICByZXR1cm4gaXNFeGNsdWRlZEluZGV4O1xuICB9KTtcblxuICBjb25zdCByZXN1bHQ6IENhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25SYW5nZUFuZEV4Y2x1c2lvbiA9IHtcbiAgICBkYXRlQ2VsbFJhbmdlLFxuICAgIHN0YXJ0LFxuICAgIGVuZCxcbiAgICBleGNsdWRlZFxuICB9O1xuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvblJhbmdlKHN0YXRlOiBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUpOiBNYXliZTxEYXRlUmFuZ2U+IHtcbiAgY29uc3QgZGF0ZUZhY3RvcnkgPSBkYXRlQ2VsbFRpbWluZ0RhdGVGYWN0b3J5KHsgc3RhcnRzQXQ6IHN0YXRlLnN0YXJ0LCB0aW1lem9uZTogc3RhdGUuc3lzdGVtVGltZXpvbmUgfSk7XG4gIGNvbnN0IGRhdGVDZWxsUmFuZ2UgPSBjb21wdXRlQ2FsZW5kYXJTY2hlZHVsZVNlbGVjdGlvbkRhdGVDZWxsUmFuZ2Uoc3RhdGUpO1xuICBjb25zdCBkYXRlUmFuZ2U6IE1heWJlPERhdGVSYW5nZT4gPSBkYXRlQ2VsbFJhbmdlICE9IG51bGwgPyB7IHN0YXJ0OiBkYXRlRmFjdG9yeShkYXRlQ2VsbFJhbmdlLmkpLCBlbmQ6IGRhdGVGYWN0b3J5KGRhdGVDZWxsUmFuZ2UudG8gYXMgbnVtYmVyKSB9IDogdW5kZWZpbmVkO1xuICByZXR1cm4gZGF0ZVJhbmdlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29tcHV0ZUNhbGVuZGFyU2NoZWR1bGVTZWxlY3Rpb25EYXRlQ2VsbFJhbmdlKHN0YXRlOiBDYWxlbmRhclNjaGVkdWxlU2VsZWN0aW9uU3RhdGUpOiBNYXliZTxEYXRlQ2VsbFJhbmdlV2l0aFJhbmdlPiB7XG4gIGNvbnN0IHsgYWxsb3dlZERheXNPZldlZWssIGluZGV4RmFjdG9yeSwgaW5wdXRTdGFydCwgaW5wdXRFbmQsIGluZGV4RGF5T2ZXZWVrLCBpc0VuYWJsZWREYXksIGlzRW5hYmxlZEZpbHRlckRheSB9ID0gc3RhdGU7XG4gIGNvbnN0IGVuYWJsZWRFeGNsdXNpb25JbmRleGVzID0gQXJyYXkuZnJvbShzdGF0ZS50b2dnbGVkSW5kZXhlcykuZmlsdGVyKChpKSA9PiBhbGxvd2VkRGF5c09mV2Vlay5oYXMoaW5kZXhEYXlPZldlZWsoaSkpKTtcbiAgY29uc3QgbWluQW5kTWF4U2VsZWN0ZWRWYWx1ZXMgPSBtaW5BbmRNYXhOdW1iZXIoZW5hYmxlZEV4Y2x1c2lvbkluZGV4ZXMpO1xuXG4gIGxldCBzdGFydFJhbmdlOiBNYXliZTxEYXRlQ2VsbEluZGV4PjtcbiAgbGV0IGVuZFJhbmdlOiBNYXliZTxEYXRlQ2VsbEluZGV4PjtcblxuICBpZiAobWluQW5kTWF4U2VsZWN0ZWRWYWx1ZXMpIHtcbiAgICBzdGFydFJhbmdlID0gbWluQW5kTWF4U2VsZWN0ZWRWYWx1ZXMubWluO1xuICAgIGVuZFJhbmdlID0gbWluQW5kTWF4U2VsZWN0ZWRWYWx1ZXMubWF4O1xuICB9XG5cbiAgaWYgKGlucHV0U3RhcnQgIT0gbnVsbCAmJiBpbnB1dEVuZCAhPSBudWxsKSB7XG4gICAgY29uc3QgaW5wdXRTdGFydEluZGV4ID0gaW5kZXhGYWN0b3J5KGlucHV0U3RhcnQpO1xuICAgIGNvbnN0IGlucHV0RW5kSW5kZXggPSBpbmRleEZhY3RvcnkoaW5wdXRFbmQpO1xuXG4gICAgc3RhcnRSYW5nZSA9IHN0YXJ0UmFuZ2UgIT0gbnVsbCA/IE1hdGgubWluKGlucHV0U3RhcnRJbmRleCwgc3RhcnRSYW5nZSkgOiBpbnB1dFN0YXJ0SW5kZXg7XG4gICAgZW5kUmFuZ2UgPSBlbmRSYW5nZSAhPSBudWxsID8gTWF0aC5tYXgoaW5wdXRFbmRJbmRleCwgZW5kUmFuZ2UpIDogaW5wdXRFbmRJbmRleDtcbiAgfVxuXG4gIGlmIChzdGFydFJhbmdlICE9IG51bGwgJiYgZW5kUmFuZ2UgIT0gbnVsbCkge1xuICAgIGNvbnN0IHNjYW5TdGFydEluZGV4ID0gc3RhcnRSYW5nZTtcbiAgICBjb25zdCBzY2FuRW5kSW5kZXggPSBlbmRSYW5nZTtcblxuICAgIC8vIGNsZWFyIHN0YXJ0IGFuZCBlbmRcbiAgICBzdGFydFJhbmdlID0gdW5kZWZpbmVkO1xuICAgIGVuZFJhbmdlID0gdW5kZWZpbmVkO1xuXG4gICAgLy8gaWYgdGhlIG1pbiBpcyBlcXVhbCB0byB0aGUgc3RhcnQgaW5kZXgsIHRoZW4gd2UgYXJlIGluIHRoZSByYW5nZSBhbmQgbmVlZCB0byBpdGVyYXRlIGRhdGVzIHVudGlsIHdlIGZpbmQgb25lIHRoYXQgaXMgbm90IHNlbGVjdGVkL2V4Y2x1ZGVkLlxuICAgIGZvciAobGV0IGkgPSBzY2FuU3RhcnRJbmRleDsgaSA8PSBzY2FuRW5kSW5kZXg7IGkgKz0gMSkge1xuICAgICAgaWYgKGlzRW5hYmxlZEZpbHRlckRheShpKSAmJiBpc0VuYWJsZWREYXkoaSkpIHtcbiAgICAgICAgc3RhcnRSYW5nZSA9IGk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNhbWUgd2l0aCB0aGUgbWF4XG4gICAgZm9yIChsZXQgaSA9IHNjYW5FbmRJbmRleDsgaSA+PSBzY2FuU3RhcnRJbmRleDsgaSAtPSAxKSB7XG4gICAgICBpZiAoaXNFbmFibGVkRmlsdGVyRGF5KGkpICYmIGlzRW5hYmxlZERheShpKSkge1xuICAgICAgICBlbmRSYW5nZSA9IGk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChzdGFydFJhbmdlICE9IG51bGwgJiYgZW5kUmFuZ2UgIT0gbnVsbCkge1xuICAgIHJldHVybiB7IGk6IHN0YXJ0UmFuZ2UsIHRvOiBlbmRSYW5nZSB9O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cbiJdfQ==
|