UNPKG

@fullcalendar/angular

Version:

The official Angular component for FullCalendar

198 lines 30.6 kB
import { Component, ContentChild, Input, ViewEncapsulation, } from '@angular/core'; import { Calendar } from '@fullcalendar/core'; import { CustomRenderingStore } from '@fullcalendar/core/internal'; import { OPTION_INPUT_NAMES, OPTION_IS_DEEP } from './options'; import { deepCopy, shallowCopy, mapHash } from './utils/obj'; import { deepEqual } from './utils/fast-deep-equal'; import * as i0 from "@angular/core"; import * as i1 from "./utils/offscreen-fragment.component"; import * as i2 from "./utils/transport-container.component"; import * as i3 from "@angular/common"; export class FullCalendarComponent { constructor(element, changeDetector) { this.element = element; this.calendar = null; this.optionSnapshot = {}; // for diffing this.customRenderingMap = new Map(); this.templateMap = {}; const customRenderingStore = new CustomRenderingStore(); customRenderingStore.subscribe((customRenderingMap) => { this.customRenderingMap = customRenderingMap; this.customRenderingArray = undefined; // clear cache changeDetector.detectChanges(); }); this.handleCustomRendering = customRenderingStore.handle.bind(customRenderingStore); this.templateMap = this; // alias to this } ngAfterViewInit() { const { deepChangeDetection } = this; const options = { ...this.options, ...this.buildInputOptions(), }; // initialize snapshot this.optionSnapshot = mapHash(options, (optionVal, optionName) => ((deepChangeDetection && OPTION_IS_DEEP[optionName]) ? deepCopy(optionVal) : optionVal)); this.calendar = new Calendar(this.element.nativeElement, { ...options, ...this.buildExtraOptions(), }); this.calendar.render(); } /* allows us to manually detect complex input changes, internal mutations to certain options. called before ngOnChanges. called much more often than ngOnChanges. */ ngDoCheck() { if (this.calendar) { // not the initial render const { deepChangeDetection, optionSnapshot } = this; const newOptions = { ...this.options, ...this.buildInputOptions(), }; const newProcessedOptions = {}; let anyChanges = false; // detect adds and updates (and update snapshot) for (const optionName in newOptions) { if (newOptions.hasOwnProperty(optionName)) { let optionVal = newOptions[optionName]; if (deepChangeDetection && OPTION_IS_DEEP[optionName]) { if (!deepEqual(optionSnapshot[optionName], optionVal)) { optionSnapshot[optionName] = deepCopy(optionVal); anyChanges = true; // trick FC into knowing about a nested change. // TODO: future versions won't need this. // can't use the previously-made deep copy because it blows away prototype-association. optionVal = shallowCopy(optionVal); } } else { if (optionSnapshot[optionName] !== optionVal) { optionSnapshot[optionName] = optionVal; anyChanges = true; } } newProcessedOptions[optionName] = optionVal; } } const oldOptionNames = Object.keys(optionSnapshot); // detect removals (and update snapshot) for (const optionName of oldOptionNames) { if (!(optionName in newOptions)) { // doesn't exist in new options? delete optionSnapshot[optionName]; anyChanges = true; } } if (anyChanges) { this.calendar.pauseRendering(); this.calendar.resetOptions({ ...newProcessedOptions, ...this.buildExtraOptions(), }); } } } ngAfterContentChecked() { if (this.calendar) { // too defensive? this.calendar.resumeRendering(); } } ngOnDestroy() { if (this.calendar) { // too defensive? this.calendar.destroy(); this.calendar = null; } } get customRenderings() { return this.customRenderingArray || (this.customRenderingArray = [...this.customRenderingMap.values()]); } getApi() { return this.calendar; } buildInputOptions() { const options = {}; for (const inputName of OPTION_INPUT_NAMES) { const inputValue = this[inputName]; if (inputValue != null) { // exclude both null and undefined options[inputName] = inputValue; } } return options; } buildExtraOptions() { return { handleCustomRendering: this.handleCustomRendering, customRenderingMetaMap: this.templateMap, customRenderingReplacesEl: true, }; } // for `trackBy` in loop trackCustomRendering(index, customRendering) { return customRendering.id; } } FullCalendarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FullCalendarComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); FullCalendarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: FullCalendarComponent, selector: "full-calendar", inputs: { options: "options", deepChangeDetection: "deepChangeDetection", events: "events", eventSources: "eventSources", resources: "resources" }, queries: [{ propertyName: "dayHeaderContent", first: true, predicate: ["dayHeaderContent"], descendants: true, static: true }, { propertyName: "dayCellContent", first: true, predicate: ["dayCellContent"], descendants: true, static: true }, { propertyName: "weekNumberContent", first: true, predicate: ["weekNumberContent"], descendants: true, static: true }, { propertyName: "nowIndicatorContent", first: true, predicate: ["nowIndicatorContent"], descendants: true, static: true }, { propertyName: "eventContent", first: true, predicate: ["eventContent"], descendants: true, static: true }, { propertyName: "slotLaneContent", first: true, predicate: ["slotLaneContent"], descendants: true, static: true }, { propertyName: "slotLabelContent", first: true, predicate: ["slotLabelContent"], descendants: true, static: true }, { propertyName: "allDayContent", first: true, predicate: ["allDayContent"], descendants: true, static: true }, { propertyName: "moreLinkContent", first: true, predicate: ["moreLinkContent"], descendants: true, static: true }, { propertyName: "noEventsContent", first: true, predicate: ["noEventsContent"], descendants: true, static: true }, { propertyName: "resourceAreaHeaderContent", first: true, predicate: ["resourceAreaHeaderContent"], descendants: true, static: true }, { propertyName: "resourceGroupLabelContent", first: true, predicate: ["resourceGroupLabelContent"], descendants: true, static: true }, { propertyName: "resourceLabelContent", first: true, predicate: ["resourceLabelContent"], descendants: true, static: true }, { propertyName: "resourceLaneContent", first: true, predicate: ["resourceLaneContent"], descendants: true, static: true }, { propertyName: "resourceGroupLaneContent", first: true, predicate: ["resourceGroupLaneContent"], descendants: true, static: true }], ngImport: i0, template: "<offscreen-fragment>\n <transport-container *ngFor=\"let customRendering of customRenderings; trackBy:trackCustomRendering\"\n [inPlaceOf]=\"customRendering.containerEl\"\n [reportEl]=\"customRendering.reportNewContainerEl\"\n [elTag]=\"customRendering.elTag\"\n [elClasses]=\"customRendering.elClasses\"\n [elStyle]=\"customRendering.elStyle\"\n [elAttrs]=\"customRendering.elAttrs\"\n [template]=\"templateMap[customRendering.generatorName]!\"\n [renderProps]=\"customRendering.renderProps\"\n ></transport-container>\n</offscreen-fragment>\n", components: [{ type: i1.OffscreenFragmentComponent, selector: "offscreen-fragment" }, { type: i2.TransportContainerComponent, selector: "transport-container", inputs: ["inPlaceOf", "reportEl", "elTag", "elClasses", "elStyle", "elAttrs", "template", "renderProps"] }], directives: [{ type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: FullCalendarComponent, decorators: [{ type: Component, args: [{ selector: 'full-calendar', encapsulation: ViewEncapsulation.None // the styles are root-level, not scoped within the component , template: "<offscreen-fragment>\n <transport-container *ngFor=\"let customRendering of customRenderings; trackBy:trackCustomRendering\"\n [inPlaceOf]=\"customRendering.containerEl\"\n [reportEl]=\"customRendering.reportNewContainerEl\"\n [elTag]=\"customRendering.elTag\"\n [elClasses]=\"customRendering.elClasses\"\n [elStyle]=\"customRendering.elStyle\"\n [elAttrs]=\"customRendering.elAttrs\"\n [template]=\"templateMap[customRendering.generatorName]!\"\n [renderProps]=\"customRendering.renderProps\"\n ></transport-container>\n</offscreen-fragment>\n" }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { options: [{ type: Input }], deepChangeDetection: [{ type: Input }], events: [{ type: Input }], eventSources: [{ type: Input }], resources: [{ type: Input }], dayHeaderContent: [{ type: ContentChild, args: ['dayHeaderContent', { static: true }] }], dayCellContent: [{ type: ContentChild, args: ['dayCellContent', { static: true }] }], weekNumberContent: [{ type: ContentChild, args: ['weekNumberContent', { static: true }] }], nowIndicatorContent: [{ type: ContentChild, args: ['nowIndicatorContent', { static: true }] }], eventContent: [{ type: ContentChild, args: ['eventContent', { static: true }] }], slotLaneContent: [{ type: ContentChild, args: ['slotLaneContent', { static: true }] }], slotLabelContent: [{ type: ContentChild, args: ['slotLabelContent', { static: true }] }], allDayContent: [{ type: ContentChild, args: ['allDayContent', { static: true }] }], moreLinkContent: [{ type: ContentChild, args: ['moreLinkContent', { static: true }] }], noEventsContent: [{ type: ContentChild, args: ['noEventsContent', { static: true }] }], resourceAreaHeaderContent: [{ type: ContentChild, args: ['resourceAreaHeaderContent', { static: true }] }], resourceGroupLabelContent: [{ type: ContentChild, args: ['resourceGroupLabelContent', { static: true }] }], resourceLabelContent: [{ type: ContentChild, args: ['resourceLabelContent', { static: true }] }], resourceLaneContent: [{ type: ContentChild, args: ['resourceLaneContent', { static: true }] }], resourceGroupLaneContent: [{ type: ContentChild, args: ['resourceGroupLaneContent', { static: true }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnVsbC1jYWxlbmRhci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvc3JjL2Z1bGwtY2FsZW5kYXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vbGliL3NyYy9mdWxsLWNhbGVuZGFyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsWUFBWSxFQUdaLEtBQUssRUFLTCxpQkFBaUIsR0FFbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFFBQVEsRUFBbUIsTUFBTSxvQkFBb0IsQ0FBQztBQUMvRCxPQUFPLEVBQW1CLG9CQUFvQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDcEYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGNBQWMsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUUvRCxPQUFPLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDN0QsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDOzs7OztBQU9wRCxNQUFNLE9BQU8scUJBQXFCO0lBc0NoQyxZQUNVLE9BQW1CLEVBQzNCLGNBQWlDO1FBRHpCLFlBQU8sR0FBUCxPQUFPLENBQVk7UUFSckIsYUFBUSxHQUFvQixJQUFJLENBQUM7UUFDakMsbUJBQWMsR0FBd0IsRUFBRSxDQUFDLENBQUMsY0FBYztRQUV4RCx1QkFBa0IsR0FBRyxJQUFJLEdBQUcsRUFBZ0MsQ0FBQTtRQUU3RCxnQkFBVyxHQUFpRCxFQUFFLENBQUE7UUFNbkUsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLG9CQUFvQixFQUFFLENBQUM7UUFFeEQsb0JBQW9CLENBQUMsU0FBUyxDQUFDLENBQUMsa0JBQWtCLEVBQUUsRUFBRTtZQUNwRCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsa0JBQWtCLENBQUM7WUFDN0MsSUFBSSxDQUFDLG9CQUFvQixHQUFHLFNBQVMsQ0FB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QWlCLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUNHLGdCQUFnQjtzQkFBbkUsWUFBWTt1QkFBQyxrQkFBa0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBQ0QsYUFBYTtzQkFBN0QsWUFBWTt1QkFBQyxlQUFlLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUNJLGVBQWU7c0JBQWpFLFlBQVk7dUJBQUMsaUJBQWlCLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUNFLGVBQWU7c0JBQWpFLFlBQVk7dUJBQUMsaUJBQWlCLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUNZLHlCQUF5QjtzQkFBckYsWUFBWTt1QkFBQywyQkFBMkIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBQ0UseUJBQXlCO3NCQUFyRixZQUFZO3VCQUFDLDJCQUEyQixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFDSCxvQkFBb0I7c0JBQTNFLFlBQVk7dUJBQUMsc0JBQXNCLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUNDLG1CQUFtQjtzQkFBekUsWUFBWTt1QkFBQyxxQkFBcUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBQ08sd0JBQXdCO3NCQUFuRixZQUFZO3VCQUFDLDBCQUEwQixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkLFxuICBUZW1wbGF0ZVJlZixcbiAgRWxlbWVudFJlZixcbiAgSW5wdXQsXG4gIEFmdGVyVmlld0luaXQsXG4gIERvQ2hlY2ssXG4gIEFmdGVyQ29udGVudENoZWNrZWQsXG4gIE9uRGVzdHJveSxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIENoYW5nZURldGVjdG9yUmVmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENhbGVuZGFyLCBDYWxlbmRhck9wdGlvbnMgfSBmcm9tICdAZnVsbGNhbGVuZGFyL2NvcmUnO1xuaW1wb3J0IHsgQ3VzdG9tUmVuZGVyaW5nLCBDdXN0b21SZW5kZXJpbmdTdG9yZSB9IGZyb20gJ0BmdWxsY2FsZW5kYXIvY29yZS9pbnRlcm5hbCc7XG5pbXBvcnQgeyBPUFRJT05fSU5QVVRfTkFNRVMsIE9QVElPTl9JU19ERUVQIH0gZnJvbSAnLi9vcHRpb25zJztcbmltcG9ydCB7IENhbGVuZGFyT3B0aW9uLCBDYWxlbmRhclRlbXBsYXRlUmVmIH0gZnJvbSAnLi9wcml2YXRlLXR5cGVzJztcbmltcG9ydCB7IGRlZXBDb3B5LCBzaGFsbG93Q29weSwgbWFwSGFzaCB9IGZyb20gJy4vdXRpbHMvb2JqJztcbmltcG9ydCB7IGRlZXBFcXVhbCB9IGZyb20gJy4vdXRpbHMvZmFzdC1kZWVwLWVxdWFsJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZnVsbC1jYWxlbmRhcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9mdWxsLWNhbGVuZGFyLmNvbXBvbmVudC5odG1sJyxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSAvLyB0aGUgc3R5bGVzIGFyZSByb290LWxldmVsLCBub3Qgc2NvcGVkIHdpdGhpbiB0aGUgY29tcG9uZW50XG59KVxuZXhwb3J0IGNsYXNzIEZ1bGxDYWxlbmRhckNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIERvQ2hlY2ssIEFmdGVyQ29udGVudENoZWNrZWQsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIG9wdGlvbnM/OiBDYWxlbmRhck9wdGlvbnM7XG4gIEBJbnB1dCgpIGRlZXBDaGFuZ2VEZXRlY3Rpb24/OiBib29sZWFuO1xuXG4gIC8qXG4gIE9wdGlvbnMgYXMgaW5kaXZpZHVhbCBJbnB1dHNcbiAgTk9URToga2VlcCBpbiBzeW5jIHdpdGggT1BUSU9OX0lOUFVUX05BTUVTXG4gICovXG4gIEBJbnB1dCgpIGV2ZW50cz86IENhbGVuZGFyT3B0aW9uPCdldmVudHMnPiB8IG51bGwgfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIGV2ZW50U291cmNlcz86IENhbGVuZGFyT3B0aW9uPCdldmVudFNvdXJjZXMnPiB8IG51bGwgfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIHJlc291cmNlcz86IENhbGVuZGFyT3B0aW9uPCdyZXNvdXJjZXMnPiB8IG51bGwgfCB1bmRlZmluZWQ7XG5cbiAgLypcbiAgVGVtcGxhdGVzXG4gICovXG4gIEBDb250ZW50Q2hpbGQoJ2RheUhlYWRlckNvbnRlbnQnLCB7IHN0YXRpYzogdHJ1ZSB9KSBkYXlIZWFkZXJDb250ZW50PzogQ2FsZW5kYXJUZW1wbGF0ZVJlZjwnZGF5SGVhZGVyQ29udGVudCc+O1xuICBAQ29udGVudENoaWxkKCdkYXlDZWxsQ29udGVudCcsIHsgc3RhdGljOiB0cnVlIH0pIGRheUNlbGxDb250ZW50PzogQ2FsZW5kYXJUZW1wbGF0ZVJlZjwnZGF5Q2VsbENvbnRlbnQnPjtcbiAgQENvbnRlbnRDaGlsZCgnd2Vla051bWJlckNvbnRlbnQnLCB7IHN0YXRpYzogdHJ1ZSB9KSB3ZWVrTnVtYmVyQ29udGVudD86IENhbGVuZGFyVGVtcGxhdGVSZWY8J3dlZWtOdW1iZXJDb250ZW50Jz47XG4gIEBDb250ZW50Q2hpbGQoJ25vd0luZGljYXRvckNvbnRlbnQnLCB7IHN0YXRpYzogdHJ1ZSB9KSBub3dJbmRpY2F0b3JDb250ZW50PzogQ2FsZW5kYXJUZW1wbGF0ZVJlZjwnbm93SW5kaWNhdG9yQ29udGVudCc+O1xuICBAQ29udGVudENoaWxkKCdldmVudENvbnRlbnQnLCB7IHN0YXRpYzogdHJ1ZSB9KSBldmVudENvbnRlbnQ/OiBDYWxlbmRhclRlbXBsYXRlUmVmPCdldmVudENvbnRlbnQnPjtcbiAgQENvbnRlbnRDaGlsZCgnc2xvdExhbmVDb250ZW50JywgeyBzdGF0aWM6IHRydWUgfSkgc2xvdExhbmVDb250ZW50PzogQ2FsZW5kYXJUZW1wbGF0ZVJlZjwnc2xvdExhbmVDb250ZW50Jz47XG4gIEBDb250ZW50Q2hpbGQoJ3Nsb3RMYWJlbENvbnRlbnQnLCB7IHN0YXRpYzogdHJ1ZSB9KSBzbG90TGFiZWxDb250ZW50PzogQ2FsZW5kYXJUZW1wbGF0ZVJlZjwnc2xvdExhYmVsQ29udGVudCc+O1xuICBAQ29udGVudENoaWxkKCdhbGxEYXlDb250ZW50JywgeyBzdGF0aWM6IHRydWUgfSkgYWxsRGF5Q29udGVudD86IENhbGVuZGFyVGVtcGxhdGVSZWY8J2FsbERheUNvbnRlbnQnPjtcbiAgQENvbnRlbnRDaGlsZCgnbW9yZUxpbmtDb250ZW50JywgeyBzdGF0aWM6IHRydWUgfSkgbW9yZUxpbmtDb250ZW50PzogQ2FsZW5kYXJUZW1wbGF0ZVJlZjwnbW9yZUxpbmtDb250ZW50Jz47XG4gIEBDb250ZW50Q2hpbGQoJ25vRXZlbnRzQ29udGVudCcsIHsgc3RhdGljOiB0cnVlIH0pIG5vRXZlbnRzQ29udGVudD86IENhbGVuZGFyVGVtcGxhdGVSZWY8J25vRXZlbnRzQ29udGVudCc+O1xuICBAQ29udGVudENoaWxkKCdyZXNvdXJjZUFyZWFIZWFkZXJDb250ZW50JywgeyBzdGF0aWM6IHRydWUgfSkgcmVzb3VyY2VBcmVhSGVhZGVyQ29udGVudD86IENhbGVuZGFyVGVtcGxhdGVSZWY8J3Jlc291cmNlQXJlYUhlYWRlckNvbnRlbnQnPjtcbiAgQENvbnRlbnRDaGlsZCgncmVzb3VyY2VHcm91cExhYmVsQ29udGVudCcsIHsgc3RhdGljOiB0cnVlIH0pIHJlc291cmNlR3JvdXBMYWJlbENvbnRlbnQ/OiBDYWxlbmRhclRlbXBsYXRlUmVmPCdyZXNvdXJjZUdyb3VwTGFiZWxDb250ZW50Jz47XG4gIEBDb250ZW50Q2hpbGQoJ3Jlc291cmNlTGFiZWxDb250ZW50JywgeyBzdGF0aWM6IHRydWUgfSkgcmVzb3VyY2VMYWJlbENvbnRlbnQ/OiBDYWxlbmRhclRlbXBsYXRlUmVmPCdyZXNvdXJjZUxhYmVsQ29udGVudCc+O1xuICBAQ29udGVudENoaWxkKCdyZXNvdXJjZUxhbmVDb250ZW50JywgeyBzdGF0aWM6IHRydWUgfSkgcmVzb3VyY2VMYW5lQ29udGVudD86IENhbGVuZGFyVGVtcGxhdGVSZWY8J3Jlc291cmNlTGFuZUNvbnRlbnQnPjtcbiAgQENvbnRlbnRDaGlsZCgncmVzb3VyY2VHcm91cExhbmVDb250ZW50JywgeyBzdGF0aWM6IHRydWUgfSkgcmVzb3VyY2VHcm91cExhbmVDb250ZW50PzogQ2FsZW5kYXJUZW1wbGF0ZVJlZjwncmVzb3VyY2VHcm91cExhbmVDb250ZW50Jz47XG5cbiAgcHJpdmF0ZSBjYWxlbmRhcjogQ2FsZW5kYXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBvcHRpb25TbmFwc2hvdDogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9OyAvLyBmb3IgZGlmZmluZ1xuICBwcml2YXRlIGhhbmRsZUN1c3RvbVJlbmRlcmluZzogKGN1c3RvbVJlbmRlcmluZzogQ3VzdG9tUmVuZGVyaW5nPGFueT4pID0+IHZvaWRcbiAgcHJpdmF0ZSBjdXN0b21SZW5kZXJpbmdNYXAgPSBuZXcgTWFwPHN0cmluZywgQ3VzdG9tUmVuZGVyaW5nPGFueT4+KClcbiAgcHJpdmF0ZSBjdXN0b21SZW5kZXJpbmdBcnJheT86IEN1c3RvbVJlbmRlcmluZzxhbnk+W11cbiAgcHVibGljIHRlbXBsYXRlTWFwOiB7IFt0ZW1wbGF0ZU5hbWU6IHN0cmluZ106IFRlbXBsYXRlUmVmPGFueT4gfSA9IHt9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBlbGVtZW50OiBFbGVtZW50UmVmLFxuICAgIGNoYW5nZURldGVjdG9yOiBDaGFuZ2VEZXRlY3RvclJlZlxuICApIHtcbiAgICBjb25zdCBjdXN0b21SZW5kZXJpbmdTdG9yZSA9IG5ldyBDdXN0b21SZW5kZXJpbmdTdG9yZSgpO1xuXG4gICAgY3VzdG9tUmVuZGVyaW5nU3RvcmUuc3Vic2NyaWJlKChjdXN0b21SZW5kZXJpbmdNYXApID0+IHtcbiAgICAgIHRoaXMuY3VzdG9tUmVuZGVyaW5nTWFwID0gY3VzdG9tUmVuZGVyaW5nTWFwO1xuICAgICAgdGhpcy5jdXN0b21SZW5kZXJpbmdBcnJheSA9IHVuZGVmaW5lZDsgLy8gY2xlYXIgY2FjaGVcbiAgICAgIGNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuaGFuZGxlQ3VzdG9tUmVuZGVyaW5nID0gY3VzdG9tUmVuZGVyaW5nU3RvcmUuaGFuZGxlLmJpbmQoY3VzdG9tUmVuZGVyaW5nU3RvcmUpO1xuICAgIHRoaXMudGVtcGxhdGVNYXAgPSB0aGlzIGFzIGFueTsgLy8gYWxpYXMgdG8gdGhpc1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIGNvbnN0IHsgZGVlcENoYW5nZURldGVjdGlvbiB9ID0gdGhpcztcbiAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgLi4udGhpcy5vcHRpb25zLFxuICAgICAgLi4udGhpcy5idWlsZElucHV0T3B0aW9ucygpLFxuICAgIH07XG5cbiAgICAvLyBpbml0aWFsaXplIHNuYXBzaG90XG4gICAgdGhpcy5vcHRpb25TbmFwc2hvdCA9IG1hcEhhc2gob3B0aW9ucywgKG9wdGlvblZhbDogYW55LCBvcHRpb25OYW1lOiBzdHJpbmcpID0+IChcbiAgICAgIChkZWVwQ2hhbmdlRGV0ZWN0aW9uICYmIE9QVElPTl9JU19ERUVQW29wdGlvbk5hbWVdKVxuICAgICAgICA/IGRlZXBDb3B5KG9wdGlvblZhbClcbiAgICAgICAgOiBvcHRpb25WYWxcbiAgICApKTtcblxuICAgIHRoaXMuY2FsZW5kYXIgPSBuZXcgQ2FsZW5kYXIodGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQsIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAuLi50aGlzLmJ1aWxkRXh0cmFPcHRpb25zKCksXG4gICAgfSk7XG4gICAgdGhpcy5jYWxlbmRhci5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qXG4gIGFsbG93cyB1cyB0byBtYW51YWxseSBkZXRlY3QgY29tcGxleCBpbnB1dCBjaGFuZ2VzLCBpbnRlcm5hbCBtdXRhdGlvbnMgdG8gY2VydGFpbiBvcHRpb25zLlxuICBjYWxsZWQgYmVmb3JlIG5nT25DaGFuZ2VzLiBjYWxsZWQgbXVjaCBtb3JlIG9mdGVuIHRoYW4gbmdPbkNoYW5nZXMuXG4gICovXG4gIG5nRG9DaGVjaygpIHtcbiAgICBpZiAodGhpcy5jYWxlbmRhcikgeyAvLyBub3QgdGhlIGluaXRpYWwgcmVuZGVyXG4gICAgICBjb25zdCB7IGRlZXBDaGFuZ2VEZXRlY3Rpb24sIG9wdGlvblNuYXBzaG90IH0gPSB0aGlzO1xuICAgICAgY29uc3QgbmV3T3B0aW9ucyA9IHtcbiAgICAgICAgLi4udGhpcy5vcHRpb25zLFxuICAgICAgICAuLi50aGlzLmJ1aWxkSW5wdXRPcHRpb25zKCksXG4gICAgICB9O1xuICAgICAgY29uc3QgbmV3UHJvY2Vzc2VkT3B0aW9uczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgICAgbGV0IGFueUNoYW5nZXMgPSBmYWxzZTtcblxuICAgICAgLy8gZGV0ZWN0IGFkZHMgYW5kIHVwZGF0ZXMgKGFuZCB1cGRhdGUgc25hcHNob3QpXG4gICAgICBmb3IgKGNvbnN0IG9wdGlvbk5hbWUgaW4gbmV3T3B0aW9ucykge1xuICAgICAgICBpZiAobmV3T3B0aW9ucy5oYXNPd25Qcm9wZXJ0eShvcHRpb25OYW1lKSkge1xuICAgICAgICAgIGxldCBvcHRpb25WYWwgPSBuZXdPcHRpb25zW29wdGlvbk5hbWUgYXMga2V5b2YgQ2FsZW5kYXJPcHRpb25zXTtcblxuICAgICAgICAgIGlmIChkZWVwQ2hhbmdlRGV0ZWN0aW9uICYmIE9QVElPTl9JU19ERUVQW29wdGlvbk5hbWVdKSB7XG4gICAgICAgICAgICBpZiAoIWRlZXBFcXVhbChvcHRpb25TbmFwc2hvdFtvcHRpb25OYW1lXSwgb3B0aW9uVmFsKSkge1xuICAgICAgICAgICAgICBvcHRpb25TbmFwc2hvdFtvcHRpb25OYW1lXSA9IGRlZXBDb3B5KG9wdGlvblZhbCk7XG4gICAgICAgICAgICAgIGFueUNoYW5nZXMgPSB0cnVlO1xuXG4gICAgICAgICAgICAgIC8vIHRyaWNrIEZDIGludG8ga25vd2luZyBhYm91dCBhIG5lc3RlZCBjaGFuZ2UuXG4gICAgICAgICAgICAgIC8vIFRPRE86IGZ1dHVyZSB2ZXJzaW9ucyB3b24ndCBuZWVkIHRoaXMuXG4gICAgICAgICAgICAgIC8vIGNhbid0IHVzZSB0aGUgcHJldmlvdXNseS1tYWRlIGRlZXAgY29weSBiZWNhdXNlIGl0IGJsb3dzIGF3YXkgcHJvdG90eXBlLWFzc29jaWF0aW9uLlxuICAgICAgICAgICAgICBvcHRpb25WYWwgPSBzaGFsbG93Q29weShvcHRpb25WYWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAob3B0aW9uU25hcHNob3Rbb3B0aW9uTmFtZV0gIT09IG9wdGlvblZhbCkge1xuICAgICAgICAgICAgICBvcHRpb25TbmFwc2hvdFtvcHRpb25OYW1lXSA9IG9wdGlvblZhbDtcbiAgICAgICAgICAgICAgYW55Q2hhbmdlcyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbmV3UHJvY2Vzc2VkT3B0aW9uc1tvcHRpb25OYW1lXSA9IG9wdGlvblZhbDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBvbGRPcHRpb25OYW1lcyA9IE9iamVjdC5rZXlzKG9wdGlvblNuYXBzaG90KTtcblxuICAgICAgLy8gZGV0ZWN0IHJlbW92YWxzIChhbmQgdXBkYXRlIHNuYXBzaG90KVxuICAgICAgZm9yIChjb25zdCBvcHRpb25OYW1lIG9mIG9sZE9wdGlvbk5hbWVzKSB7XG4gICAgICAgIGlmICghKG9wdGlvbk5hbWUgaW4gbmV3T3B0aW9ucykpIHsgLy8gZG9lc24ndCBleGlzdCBpbiBuZXcgb3B0aW9ucz9cbiAgICAgICAgICBkZWxldGUgb3B0aW9uU25hcHNob3Rbb3B0aW9uTmFtZV07XG4gICAgICAgICAgYW55Q2hhbmdlcyA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGFueUNoYW5nZXMpIHtcbiAgICAgICAgdGhpcy5jYWxlbmRhci5wYXVzZVJlbmRlcmluZygpO1xuICAgICAgICB0aGlzLmNhbGVuZGFyLnJlc2V0T3B0aW9ucyh7XG4gICAgICAgICAgLi4ubmV3UHJvY2Vzc2VkT3B0aW9ucyxcbiAgICAgICAgICAuLi50aGlzLmJ1aWxkRXh0cmFPcHRpb25zKCksXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50Q2hlY2tlZCgpIHtcbiAgICBpZiAodGhpcy5jYWxlbmRhcikgeyAvLyB0b28gZGVmZW5zaXZlP1xuICAgICAgdGhpcy5jYWxlbmRhci5yZXN1bWVSZW5kZXJpbmcoKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5jYWxlbmRhcikgeyAvLyB0b28gZGVmZW5zaXZlP1xuICAgICAgdGhpcy5jYWxlbmRhci5kZXN0cm95KCk7XG4gICAgICB0aGlzLmNhbGVuZGFyID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBnZXQgY3VzdG9tUmVuZGVyaW5ncygpOiBDdXN0b21SZW5kZXJpbmc8YW55PltdIHtcbiAgICByZXR1cm4gdGhpcy5jdXN0b21SZW5kZXJpbmdBcnJheSB8fFxuICAgICAgKHRoaXMuY3VzdG9tUmVuZGVyaW5nQXJyYXkgPSBbLi4udGhpcy5jdXN0b21SZW5kZXJpbmdNYXAudmFsdWVzKCldKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRBcGkoKTogQ2FsZW5kYXIge1xuICAgIHJldHVybiB0aGlzLmNhbGVuZGFyITtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRJbnB1dE9wdGlvbnMoKTogQ2FsZW5kYXJPcHRpb25zIHtcbiAgICBjb25zdCBvcHRpb25zOiBDYWxlbmRhck9wdGlvbnMgPSB7fVxuXG4gICAgZm9yIChjb25zdCBpbnB1dE5hbWUgb2YgT1BUSU9OX0lOUFVUX05BTUVTKSB7XG4gICAgICBjb25zdCBpbnB1dFZhbHVlID0gKHRoaXMgYXMgYW55KVtpbnB1dE5hbWVdO1xuXG4gICAgICBpZiAoaW5wdXRWYWx1ZSAhPSBudWxsKSB7IC8vIGV4Y2x1ZGUgYm90aCBudWxsIGFuZCB1bmRlZmluZWRcbiAgICAgICAgKG9wdGlvbnMgYXMgYW55KVtpbnB1dE5hbWVdID0gaW5wdXRWYWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb3B0aW9ucztcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRFeHRyYU9wdGlvbnMoKTogQ2FsZW5kYXJPcHRpb25zIHtcbiAgICByZXR1cm4ge1xuICAgICAgaGFuZGxlQ3VzdG9tUmVuZGVyaW5nOiB0aGlzLmhhbmRsZUN1c3RvbVJlbmRlcmluZyxcbiAgICAgIGN1c3RvbVJlbmRlcmluZ01ldGFNYXA6IHRoaXMudGVtcGxhdGVNYXAsXG4gICAgICBjdXN0b21SZW5kZXJpbmdSZXBsYWNlc0VsOiB0cnVlLFxuICAgIH07XG4gIH1cblxuICAvLyBmb3IgYHRyYWNrQnlgIGluIGxvb3BcbiAgdHJhY2tDdXN0b21SZW5kZXJpbmcoaW5kZXg6IG51bWJlciwgY3VzdG9tUmVuZGVyaW5nOiBDdXN0b21SZW5kZXJpbmc8YW55Pik6IGFueSB7XG4gICAgcmV0dXJuIGN1c3RvbVJlbmRlcmluZy5pZFxuICB9XG59XG4iLCI8b2Zmc2NyZWVuLWZyYWdtZW50PlxuICA8dHJhbnNwb3J0LWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY3VzdG9tUmVuZGVyaW5nIG9mIGN1c3RvbVJlbmRlcmluZ3M7IHRyYWNrQnk6dHJhY2tDdXN0b21SZW5kZXJpbmdcIlxuICAgIFtpblBsYWNlT2ZdPVwiY3VzdG9tUmVuZGVyaW5nLmNvbnRhaW5lckVsXCJcbiAgICBbcmVwb3J0RWxdPVwiY3VzdG9tUmVuZGVyaW5nLnJlcG9ydE5ld0NvbnRhaW5lckVsXCJcbiAgICBbZWxUYWddPVwiY3VzdG9tUmVuZGVyaW5nLmVsVGFnXCJcbiAgICBbZWxDbGFzc2VzXT1cImN1c3RvbVJlbmRlcmluZy5lbENsYXNzZXNcIlxuICAgIFtlbFN0eWxlXT1cImN1c3RvbVJlbmRlcmluZy5lbFN0eWxlXCJcbiAgICBbZWxBdHRyc109XCJjdXN0b21SZW5kZXJpbmcuZWxBdHRyc1wiXG4gICAgW3RlbXBsYXRlXT1cInRlbXBsYXRlTWFwW2N1c3RvbVJlbmRlcmluZy5nZW5lcmF0b3JOYW1lXSFcIlxuICAgIFtyZW5kZXJQcm9wc109XCJjdXN0b21SZW5kZXJpbmcucmVuZGVyUHJvcHNcIlxuICA+PC90cmFuc3BvcnQtY29udGFpbmVyPlxuPC9vZmZzY3JlZW4tZnJhZ21lbnQ+XG4iXX0=