UNPKG

@taiga-ui/addon-mobile

Version:

Extension package for Taiga UI that adds support for mobile specific behaviors such as custom data pickers, dropdowns, etc.

126 lines • 20.5 kB
import { __decorate } from "tslib"; import { MONTHS_IN_YEAR } from '@taiga-ui/cdk/date-time'; import { tuiPure } from '@taiga-ui/cdk/utils/miscellaneous'; import { distinctUntilChanged, Subject, takeUntil } from 'rxjs'; import { ANDROID_CYCLE, BUFFER, IOS_CYCLE, RANGE, YEARLY_CYCLE, } from './mobile-calendar.const'; const ANDROID_CYCLE_HEIGHT = reduceCycle(ANDROID_CYCLE); const IOS_CYCLE_HEIGHT = reduceCycle(IOS_CYCLE); function reduceCycle(cycle, lastYear = 28, lastMonth = 12) { return cycle.reduce((total, year, yearIndex) => yearIndex <= lastYear ? total + year.reduce((sum, month, monthIndex) => yearIndex < lastYear || (yearIndex === lastYear && monthIndex < lastMonth) ? sum + month : sum, 0) : total, 0); } /** * This scroll strategy is hard wired with styles for iOS and Android. * It is dependent on month height on those platforms and is designed to * work for {@link TuiMobileCalendar} with years 1906 to 2102 */ export class TuiMobileCalendarStrategy { constructor(isIOS, scrollService) { this.isIOS = isIOS; this.scrollService = scrollService; this.index$ = new Subject(); this.viewport = null; this.destroy$ = new Subject(); } get scrolledIndexChange() { return this.index$.pipe(distinctUntilChanged()); } attach(viewport) { const cycle = this.isIOS ? IOS_CYCLE_HEIGHT : ANDROID_CYCLE_HEIGHT; this.viewport = viewport; this.viewport.setTotalContentSize(cycle * 7); this.updateRenderedRange(this.viewport); } detach() { this.index$.complete(); this.viewport = null; this.destroy$.next(); this.destroy$.complete(); } onContentScrolled() { if (this.viewport) { this.updateRenderedRange(this.viewport); } } /** These do not matter for this case */ onDataLengthChanged() { } onContentRendered() { } onRenderedOffsetChanged() { } scrollToIndex(index, behavior) { if (!this.viewport) { return; } const scrollTop = this.getOffsetForIndex(index); if (behavior !== 'smooth') { this.viewport.scrollToOffset(scrollTop, behavior); return; } this.scrollService .scroll$(this.viewport.elementRef.nativeElement, scrollTop) .pipe(takeUntil(this.destroy$)) .subscribe(); } getOffsetForIndex(index) { const month = index % MONTHS_IN_YEAR; const year = (index - month) / MONTHS_IN_YEAR; return this.computeHeight(year, month); } getIndexForOffset(offset) { const cycle = this.isIOS ? IOS_CYCLE : ANDROID_CYCLE; const cycleHeight = this.isIOS ? IOS_CYCLE_HEIGHT : ANDROID_CYCLE_HEIGHT; const remainder = offset % cycleHeight; const years = ((offset - remainder) / cycleHeight) * YEARLY_CYCLE; let accumulator = 0; for (let year = 0; year < cycle.length; year++) { for (let month = 0; month < (cycle[year]?.length ?? 0); month++) { accumulator += cycle[year]?.[month] ?? 0; if (accumulator - (cycle[year]?.[month] ?? 0) / 2 > remainder) { return Math.max((years + year) * MONTHS_IN_YEAR + month, 0); } } } return RANGE; } computeHeight(year, month) { const cycle = this.isIOS ? IOS_CYCLE : ANDROID_CYCLE; const remainder = year % YEARLY_CYCLE; const remainderHeight = reduceCycle(cycle, remainder, month); const fullCycles = (year - remainder) / YEARLY_CYCLE; const fullCyclesHeight = this.isIOS ? fullCycles * IOS_CYCLE_HEIGHT : fullCycles * ANDROID_CYCLE_HEIGHT; return fullCyclesHeight + remainderHeight; } updateRenderedRange(viewport) { const offset = viewport.measureScrollOffset(); const { start, end } = viewport.getRenderedRange(); const viewportSize = viewport.getViewportSize(); const dataLength = viewport.getDataLength(); const newRange = { start, end }; const firstVisibleIndex = this.getIndexForOffset(offset); const startBuffer = offset - this.getOffsetForIndex(start); if (startBuffer < BUFFER && start !== 0) { newRange.start = Math.max(0, this.getIndexForOffset(offset - BUFFER * 2)); newRange.end = Math.min(dataLength, this.getIndexForOffset(offset + viewportSize + BUFFER)); } else { const endBuffer = this.getOffsetForIndex(end) - offset - viewportSize; if (endBuffer < BUFFER && end !== dataLength) { newRange.start = Math.max(0, this.getIndexForOffset(offset - BUFFER)); newRange.end = Math.min(dataLength, this.getIndexForOffset(offset + viewportSize + BUFFER * 2)); } } viewport.setRenderedRange(newRange); viewport.setRenderedContentOffset(this.getOffsetForIndex(newRange.start)); this.index$.next(firstVisibleIndex); } } __decorate([ tuiPure ], TuiMobileCalendarStrategy.prototype, "scrolledIndexChange", null); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9iaWxlLWNhbGVuZGFyLnN0cmF0ZWd5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYWRkb24tbW9iaWxlL2NvbXBvbmVudHMvbW9iaWxlLWNhbGVuZGFyL21vYmlsZS1jYWxlbmRhci5zdHJhdGVneS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBSUEsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLHlCQUF5QixDQUFDO0FBRXZELE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSxtQ0FBbUMsQ0FBQztBQUMxRCxPQUFPLEVBQUMsb0JBQW9CLEVBQW1CLE9BQU8sRUFBRSxTQUFTLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFFL0UsT0FBTyxFQUNILGFBQWEsRUFDYixNQUFNLEVBQ04sU0FBUyxFQUNULEtBQUssRUFDTCxZQUFZLEdBQ2YsTUFBTSx5QkFBeUIsQ0FBQztBQUVqQyxNQUFNLG9CQUFvQixHQUFHLFdBQVcsQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUN4RCxNQUFNLGdCQUFnQixHQUFHLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUVoRCxTQUFTLFdBQVcsQ0FDaEIsS0FBdUMsRUFDdkMsUUFBUSxHQUFHLEVBQUUsRUFDYixTQUFTLEdBQUcsRUFBRTtJQUVkLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FDZixDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEVBQUUsQ0FDdkIsU0FBUyxJQUFJLFFBQVE7UUFDakIsQ0FBQyxDQUFDLEtBQUs7WUFDTCxJQUFJLENBQUMsTUFBTSxDQUNQLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsRUFBRSxDQUN2QixTQUFTLEdBQUcsUUFBUTtnQkFDcEIsQ0FBQyxTQUFTLEtBQUssUUFBUSxJQUFJLFVBQVUsR0FBRyxTQUFTLENBQUM7Z0JBQzlDLENBQUMsQ0FBQyxHQUFHLEdBQUcsS0FBSztnQkFDYixDQUFDLENBQUMsR0FBRyxFQUNi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QU0sQ0FBQyxDQUN6RCxDQUFDO1NBQ0w7YUFBTTtZQUNILE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLEdBQUcsWUFBWSxDQUFDO1lBRXRFLElBQUksU0FBUyxHQUFHLE1BQU0sSUFBSSxHQUFHLEtBQUssVUFBVSxFQUFFO2dCQUMxQyxRQUFRLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFDdEUsUUFBUSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUNuQixVQUFVLEVBQ1YsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sR0FBRyxZQUFZLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUM3RCxDQUFDO2FBQ0w7U0FDSjtRQUVELFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNwQyxRQUFRLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDeEMsQ0FBQztDQUNKO0FBeEhHO0lBREMsT0FBTztvRUFHUCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgdHlwZSBDZGtWaXJ0dWFsU2Nyb2xsVmlld3BvcnQsXG4gICAgdHlwZSBWaXJ0dWFsU2Nyb2xsU3RyYXRlZ3ksXG59IGZyb20gJ0Bhbmd1bGFyL2Nkay9zY3JvbGxpbmcnO1xuaW1wb3J0IHtNT05USFNfSU5fWUVBUn0gZnJvbSAnQHRhaWdhLXVpL2Nkay9kYXRlLXRpbWUnO1xuaW1wb3J0IHt0eXBlIFR1aVNjcm9sbFNlcnZpY2V9IGZyb20gJ0B0YWlnYS11aS9jZGsvc2VydmljZXMnO1xuaW1wb3J0IHt0dWlQdXJlfSBmcm9tICdAdGFpZ2EtdWkvY2RrL3V0aWxzL21pc2NlbGxhbmVvdXMnO1xuaW1wb3J0IHtkaXN0aW5jdFVudGlsQ2hhbmdlZCwgdHlwZSBPYnNlcnZhYmxlLCBTdWJqZWN0LCB0YWtlVW50aWx9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQge1xuICAgIEFORFJPSURfQ1lDTEUsXG4gICAgQlVGRkVSLFxuICAgIElPU19DWUNMRSxcbiAgICBSQU5HRSxcbiAgICBZRUFSTFlfQ1lDTEUsXG59IGZyb20gJy4vbW9iaWxlLWNhbGVuZGFyLmNvbnN0JztcblxuY29uc3QgQU5EUk9JRF9DWUNMRV9IRUlHSFQgPSByZWR1Y2VDeWNsZShBTkRST0lEX0NZQ0xFKTtcbmNvbnN0IElPU19DWUNMRV9IRUlHSFQgPSByZWR1Y2VDeWNsZShJT1NfQ1lDTEUpO1xuXG5mdW5jdGlvbiByZWR1Y2VDeWNsZShcbiAgICBjeWNsZTogUmVhZG9ubHlBcnJheTxyZWFkb25seSBudW1iZXJbXT4sXG4gICAgbGFzdFllYXIgPSAyOCxcbiAgICBsYXN0TW9udGggPSAxMixcbik6IG51bWJlciB7XG4gICAgcmV0dXJuIGN5Y2xlLnJlZHVjZShcbiAgICAgICAgKHRvdGFsLCB5ZWFyLCB5ZWFySW5kZXgpID0+XG4gICAgICAgICAgICB5ZWFySW5kZXggPD0gbGFzdFllYXJcbiAgICAgICAgICAgICAgICA/IHRvdGFsICtcbiAgICAgICAgICAgICAgICAgIHllYXIucmVkdWNlKFxuICAgICAgICAgICAgICAgICAgICAgIChzdW0sIG1vbnRoLCBtb250aEluZGV4KSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFySW5kZXggPCBsYXN0WWVhciB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAoeWVhckluZGV4ID09PSBsYXN0WWVhciAmJiBtb250aEluZGV4IDwgbGFzdE1vbnRoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBzdW0gKyBtb250aFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBzdW0sXG4gICAgICAgICAgICAgICAgICAgICAgMCxcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICA6IHRvdGFsLFxuICAgICAgICAwLFxuICAgICk7XG59XG5cbi8qKlxuICogVGhpcyBzY3JvbGwgc3RyYXRlZ3kgaXMgaGFyZCB3aXJlZCB3aXRoIHN0eWxlcyBmb3IgaU9TIGFuZCBBbmRyb2lkLlxuICogSXQgaXMgZGVwZW5kZW50IG9uIG1vbnRoIGhlaWdodCBvbiB0aG9zZSBwbGF0Zm9ybXMgYW5kIGlzIGRlc2lnbmVkIHRvXG4gKiB3b3JrIGZvciB7QGxpbmsgVHVpTW9iaWxlQ2FsZW5kYXJ9IHdpdGggeWVhcnMgMTkwNiB0byAyMTAyXG4gKi9cbmV4cG9ydCBjbGFzcyBUdWlNb2JpbGVDYWxlbmRhclN0cmF0ZWd5IGltcGxlbWVudHMgVmlydHVhbFNjcm9sbFN0cmF0ZWd5IHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGluZGV4JCA9IG5ldyBTdWJqZWN0PG51bWJlcj4oKTtcblxuICAgIHByaXZhdGUgdmlld3BvcnQ6IENka1ZpcnR1YWxTY3JvbGxWaWV3cG9ydCB8IG51bGwgPSBudWxsO1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBpc0lPUzogYm9vbGVhbixcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBzY3JvbGxTZXJ2aWNlOiBUdWlTY3JvbGxTZXJ2aWNlLFxuICAgICkge31cblxuICAgIEB0dWlQdXJlXG4gICAgcHVibGljIGdldCBzY3JvbGxlZEluZGV4Q2hhbmdlKCk6IE9ic2VydmFibGU8bnVtYmVyPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmluZGV4JC5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhdHRhY2godmlld3BvcnQ6IENka1ZpcnR1YWxTY3JvbGxWaWV3cG9ydCk6IHZvaWQge1xuICAgICAgICBjb25zdCBjeWNsZSA9IHRoaXMuaXNJT1MgPyBJT1NfQ1lDTEVfSEVJR0hUIDogQU5EUk9JRF9DWUNMRV9IRUlHSFQ7XG5cbiAgICAgICAgdGhpcy52aWV3cG9ydCA9IHZpZXdwb3J0O1xuICAgICAgICB0aGlzLnZpZXdwb3J0LnNldFRvdGFsQ29udGVudFNpemUoY3ljbGUgKiA3KTtcbiAgICAgICAgdGhpcy51cGRhdGVSZW5kZXJlZFJhbmdlKHRoaXMudmlld3BvcnQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBkZXRhY2goKTogdm9pZCB7XG4gICAgICAgIHRoaXMuaW5kZXgkLmNvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMudmlld3BvcnQgPSBudWxsO1xuICAgICAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICAgICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkNvbnRlbnRTY3JvbGxlZCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMudmlld3BvcnQpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlUmVuZGVyZWRSYW5nZSh0aGlzLnZpZXdwb3J0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBUaGVzZSBkbyBub3QgbWF0dGVyIGZvciB0aGlzIGNhc2UgKi9cbiAgICBwdWJsaWMgb25EYXRhTGVuZ3RoQ2hhbmdlZCgpOiB2b2lkIHt9XG4gICAgcHVibGljIG9uQ29udGVudFJlbmRlcmVkKCk6IHZvaWQge31cbiAgICBwdWJsaWMgb25SZW5kZXJlZE9mZnNldENoYW5nZWQoKTogdm9pZCB7fVxuXG4gICAgcHVibGljIHNjcm9sbFRvSW5kZXgoaW5kZXg6IG51bWJlciwgYmVoYXZpb3I6IFNjcm9sbEJlaGF2aW9yKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy52aWV3cG9ydCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc2Nyb2xsVG9wID0gdGhpcy5nZXRPZmZzZXRGb3JJbmRleChpbmRleCk7XG5cbiAgICAgICAgaWYgKGJlaGF2aW9yICE9PSAnc21vb3RoJykge1xuICAgICAgICAgICAgdGhpcy52aWV3cG9ydC5zY3JvbGxUb09mZnNldChzY3JvbGxUb3AsIGJlaGF2aW9yKTtcblxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zY3JvbGxTZXJ2aWNlXG4gICAgICAgICAgICAuc2Nyb2xsJCh0aGlzLnZpZXdwb3J0LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgc2Nyb2xsVG9wKVxuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0T2Zmc2V0Rm9ySW5kZXgoaW5kZXg6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IG1vbnRoID0gaW5kZXggJSBNT05USFNfSU5fWUVBUjtcbiAgICAgICAgY29uc3QgeWVhciA9IChpbmRleCAtIG1vbnRoKSAvIE1PTlRIU19JTl9ZRUFSO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmNvbXB1dGVIZWlnaHQoeWVhciwgbW9udGgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0SW5kZXhGb3JPZmZzZXQob2Zmc2V0OiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBjeWNsZSA9IHRoaXMuaXNJT1MgPyBJT1NfQ1lDTEUgOiBBTkRST0lEX0NZQ0xFO1xuICAgICAgICBjb25zdCBjeWNsZUhlaWdodCA9IHRoaXMuaXNJT1MgPyBJT1NfQ1lDTEVfSEVJR0hUIDogQU5EUk9JRF9DWUNMRV9IRUlHSFQ7XG4gICAgICAgIGNvbnN0IHJlbWFpbmRlciA9IG9mZnNldCAlIGN5Y2xlSGVpZ2h0O1xuICAgICAgICBjb25zdCB5ZWFycyA9ICgob2Zmc2V0IC0gcmVtYWluZGVyKSAvIGN5Y2xlSGVpZ2h0KSAqIFlFQVJMWV9DWUNMRTtcblxuICAgICAgICBsZXQgYWNjdW11bGF0b3IgPSAwO1xuXG4gICAgICAgIGZvciAobGV0IHllYXIgPSAwOyB5ZWFyIDwgY3ljbGUubGVuZ3RoOyB5ZWFyKyspIHtcbiAgICAgICAgICAgIGZvciAobGV0IG1vbnRoID0gMDsgbW9udGggPCAoY3ljbGVbeWVhcl0/Lmxlbmd0aCA/PyAwKTsgbW9udGgrKykge1xuICAgICAgICAgICAgICAgIGFjY3VtdWxhdG9yICs9IGN5Y2xlW3llYXJdPy5bbW9udGhdID8/IDA7XG5cbiAgICAgICAgICAgICAgICBpZiAoYWNjdW11bGF0b3IgLSAoY3ljbGVbeWVhcl0/Llttb250aF0gPz8gMCkgLyAyID4gcmVtYWluZGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBNYXRoLm1heCgoeWVhcnMgKyB5ZWFyKSAqIE1PTlRIU19JTl9ZRUFSICsgbW9udGgsIDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBSQU5HRTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNvbXB1dGVIZWlnaHQoeWVhcjogbnVtYmVyLCBtb250aD86IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IGN5Y2xlID0gdGhpcy5pc0lPUyA/IElPU19DWUNMRSA6IEFORFJPSURfQ1lDTEU7XG4gICAgICAgIGNvbnN0IHJlbWFpbmRlciA9IHllYXIgJSBZRUFSTFlfQ1lDTEU7XG4gICAgICAgIGNvbnN0IHJlbWFpbmRlckhlaWdodCA9IHJlZHVjZUN5Y2xlKGN5Y2xlLCByZW1haW5kZXIsIG1vbnRoKTtcbiAgICAgICAgY29uc3QgZnVsbEN5Y2xlcyA9ICh5ZWFyIC0gcmVtYWluZGVyKSAvIFlFQVJMWV9DWUNMRTtcbiAgICAgICAgY29uc3QgZnVsbEN5Y2xlc0hlaWdodCA9IHRoaXMuaXNJT1NcbiAgICAgICAgICAgID8gZnVsbEN5Y2xlcyAqIElPU19DWUNMRV9IRUlHSFRcbiAgICAgICAgICAgIDogZnVsbEN5Y2xlcyAqIEFORFJPSURfQ1lDTEVfSEVJR0hUO1xuXG4gICAgICAgIHJldHVybiBmdWxsQ3ljbGVzSGVpZ2h0ICsgcmVtYWluZGVySGVpZ2h0O1xuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlUmVuZGVyZWRSYW5nZSh2aWV3cG9ydDogQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG9mZnNldCA9IHZpZXdwb3J0Lm1lYXN1cmVTY3JvbGxPZmZzZXQoKTtcbiAgICAgICAgY29uc3Qge3N0YXJ0LCBlbmR9ID0gdmlld3BvcnQuZ2V0UmVuZGVyZWRSYW5nZSgpO1xuICAgICAgICBjb25zdCB2aWV3cG9ydFNpemUgPSB2aWV3cG9ydC5nZXRWaWV3cG9ydFNpemUoKTtcbiAgICAgICAgY29uc3QgZGF0YUxlbmd0aCA9IHZpZXdwb3J0LmdldERhdGFMZW5ndGgoKTtcbiAgICAgICAgY29uc3QgbmV3UmFuZ2UgPSB7c3RhcnQsIGVuZH07XG4gICAgICAgIGNvbnN0IGZpcnN0VmlzaWJsZUluZGV4ID0gdGhpcy5nZXRJbmRleEZvck9mZnNldChvZmZzZXQpO1xuICAgICAgICBjb25zdCBzdGFydEJ1ZmZlciA9IG9mZnNldCAtIHRoaXMuZ2V0T2Zmc2V0Rm9ySW5kZXgoc3RhcnQpO1xuXG4gICAgICAgIGlmIChzdGFydEJ1ZmZlciA8IEJVRkZFUiAmJiBzdGFydCAhPT0gMCkge1xuICAgICAgICAgICAgbmV3UmFuZ2Uuc3RhcnQgPSBNYXRoLm1heCgwLCB0aGlzLmdldEluZGV4Rm9yT2Zmc2V0KG9mZnNldCAtIEJVRkZFUiAqIDIpKTtcbiAgICAgICAgICAgIG5ld1JhbmdlLmVuZCA9IE1hdGgubWluKFxuICAgICAgICAgICAgICAgIGRhdGFMZW5ndGgsXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRJbmRleEZvck9mZnNldChvZmZzZXQgKyB2aWV3cG9ydFNpemUgKyBCVUZGRVIpLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGVuZEJ1ZmZlciA9IHRoaXMuZ2V0T2Zmc2V0Rm9ySW5kZXgoZW5kKSAtIG9mZnNldCAtIHZpZXdwb3J0U2l6ZTtcblxuICAgICAgICAgICAgaWYgKGVuZEJ1ZmZlciA8IEJVRkZFUiAmJiBlbmQgIT09IGRhdGFMZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBuZXdSYW5nZS5zdGFydCA9IE1hdGgubWF4KDAsIHRoaXMuZ2V0SW5kZXhGb3JPZmZzZXQob2Zmc2V0IC0gQlVGRkVSKSk7XG4gICAgICAgICAgICAgICAgbmV3UmFuZ2UuZW5kID0gTWF0aC5taW4oXG4gICAgICAgICAgICAgICAgICAgIGRhdGFMZW5ndGgsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0SW5kZXhGb3JPZmZzZXQob2Zmc2V0ICsgdmlld3BvcnRTaXplICsgQlVGRkVSICogMiksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHZpZXdwb3J0LnNldFJlbmRlcmVkUmFuZ2UobmV3UmFuZ2UpO1xuICAgICAgICB2aWV3cG9ydC5zZXRSZW5kZXJlZENvbnRlbnRPZmZzZXQodGhpcy5nZXRPZmZzZXRGb3JJbmRleChuZXdSYW5nZS5zdGFydCkpO1xuICAgICAgICB0aGlzLmluZGV4JC5uZXh0KGZpcnN0VmlzaWJsZUluZGV4KTtcbiAgICB9XG59XG4iXX0=