design-angular-kit
Version:
Un toolkit Angular conforme alle linee guida di design per i servizi web della PA
301 lines (299 loc) • 31.9 kB
JavaScript
import { NgTemplateOutlet } from '@angular/common';
import { afterNextRender, ChangeDetectionStrategy, Component, DestroyRef, inject, Injector, Input, NgZone, signal, ViewChild, ViewEncapsulation, } from '@angular/core';
import { toObservable } from '@angular/core/rxjs-interop';
import { delay } from 'rxjs';
import videojs from 'video.js';
import { ItAbstractComponent } from '../../../abstracts/abstract.component';
import { VideoPlayerI18nService } from './video-player-i18n.service';
import { cookies } from './video-player.cookie';
import * as i0 from "@angular/core";
import * as i1 from "./video-player.config";
var ViewType;
(function (ViewType) {
ViewType["Default"] = "DEFAULT";
ViewType["Overlay"] = "OVERLAY";
})(ViewType || (ViewType = {}));
/**
* Video Player
* @description Component that allows playing a video.
*/
export class ItVideoPlayerComponent extends ItAbstractComponent {
#destroyRef;
constructor(config) {
super();
this.config = config;
this.player = null;
this.viewTypes = ViewType;
this.viewType = signal(undefined);
this.cookieAccepted = signal(false);
this.i18nService = inject(VideoPlayerI18nService);
this.#destroyRef = inject(DestroyRef);
this.ngZone = inject(NgZone);
this.injector = inject(Injector);
afterNextRender(() => {
if (this.viewType() === ViewType.Overlay && cookies.isChoiceRemembered('youtube.com')) {
this.hideOverlay();
}
});
this.#destroyRef.onDestroy(() => this.player?.dispose());
}
async ngOnInit() {
const config = this.config.mergeConfig(this.options);
this.setViewType(config);
// Avoid running change detections while the script is being loaded.
await this.ngZone.runOutsideAngular(() => this.config.configureTech(config));
if (!this.videoPlayerRef) {
// Note: No need to pipe with `takeUntilDestroyed`; `toObservable` is
// completed by Angular when the `DestroyRef` from the injector is destroyed.
toObservable(this.cookieAccepted, { injector: this.injector })
.pipe(delay(0))
.subscribe(value => {
if (value && !this.player) {
this.initVideoPlayer();
}
});
return;
}
this.initVideoPlayer();
}
acceptCookieHandler() {
this.rememberHandler();
this.hideOverlay();
this.cookieAccepted.set(true);
}
initVideoPlayer() {
const config = this.config.mergeConfig(this.options);
this.setVideoAttributes(config);
this.setVideoPlayer();
}
setVideoPlayer() {
const config = this.config.mergeConfig(this.options);
const onPlayerReadyCb = () => {
if (!this.player) {
return;
}
this.i18nService.init(this.player, this.#destroyRef);
};
const element = this.videoPlayerRef?.nativeElement;
if (!element) {
throw Error('videoPlayerRef is undefined');
}
this.player = this.ngZone.runOutsideAngular(() => videojs(element, config, onPlayerReadyCb));
}
setViewType(config) {
this.viewType.set(config.tech === 'youtube' ? ViewType.Overlay : ViewType.Default);
this.cookieAccepted.set(this.viewType() === ViewType.Overlay && cookies.isChoiceRemembered('youtube.com'));
}
hideOverlay() {
if (!this.acceptOverlayableRef) {
return;
}
const classes = ['show'];
this.acceptOverlayableRef.nativeElement.classList.remove(...classes);
if (!this.acceptOveralyRef) {
return;
}
this.acceptOveralyRef.nativeElement.classList.remove(...classes);
this.acceptOveralyRef.nativeElement.setAttribute('aria-hidden', 'true');
}
rememberHandler() {
if (!this.chrRememberRef) {
return;
}
const remember = this.chrRememberRef.nativeElement.checked;
cookies.rememberChoice('youtube.com', remember);
}
setVideoAttributes(options) {
if (!this.videoPlayerRef) {
return;
}
const v = this.videoPlayerRef.nativeElement;
const { autoplay, controls, loop, muted, poster, fluid } = options;
if (autoplay) {
v.setAttribute('autoplay', autoplay.toString());
}
if (controls) {
v.setAttribute('controls', '');
}
if (loop) {
v.setAttribute('loop', '');
}
if (muted) {
v.setAttribute('muted', '');
}
if (poster) {
v.setAttribute('poster', poster);
}
if (fluid) {
v.setAttribute('fluid', '');
}
v.setAttribute('preload', 'none');
v.setAttribute('playsinline', '');
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: ItVideoPlayerComponent, deps: [{ token: i1.VideoPlayerConfigService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.6", type: ItVideoPlayerComponent, isStandalone: true, selector: "it-video-player", inputs: { options: "options" }, viewQueries: [{ propertyName: "videoPlayerRef", first: true, predicate: ["videoPlayer"], descendants: true }, { propertyName: "acceptOveralyRef", first: true, predicate: ["acceptOveraly"], descendants: true }, { propertyName: "acceptOverlayableRef", first: true, predicate: ["acceptOverlayable"], descendants: true }, { propertyName: "chrRememberRef", first: true, predicate: ["chkRemember"], descendants: true }], usesInheritance: true, ngImport: i0, template: ` (viewType()) {
(viewTypes.Default) {
<div class="row">
<ng-container *ngTemplateOutlet="videoTemplate"></ng-container>
<ng-container *ngTemplateOutlet="transcriptionTemplate"></ng-container>
</div>
}
(viewTypes.Overlay) {
<div #acceptOverlayable class="acceptoverlayable show">
<div #acceptOveraly class="acceptoverlay acceptoverlay-primary fade show">
<div class="acceptoverlay-inner">
<div class="acceptoverlay-icon">
<svg class="icon icon-xl"><use href="/bootstrap-italia/dist/svg/sprites.svg#it-video"></use></svg>
</div>
<p>
Accetta i cookie di YouTube per vedere il video. Puoi gestire le preferenze nella
<a href="#" class="text-white">cookie policy</a>.
</p>
<div class="acceptoverlay-buttons bg-dark">
<button type="button" class="btn btn-primary" (click)="acceptCookieHandler()">Accetta</button>
<div class="form-check">
<input id="chk-remember{{ id }}" type="checkbox" #chkRemember />
<label for="chk-remember{{ id }}">Ricorda per tutti i video</label>
</div>
</div>
</div>
</div>
(cookieAccepted()) {
<div>
<ng-container *ngTemplateOutlet="videoTemplate"></ng-container>
<ng-container *ngTemplateOutlet="transcriptionTemplate"></ng-container>
</div>
}
</div>
}
{
<h1>No video provider</h1>
}
}
<ng-template #videoTemplate>
<div>
<video #videoPlayer class="video-js vjs-theme-bootstrap-italia vjs-fluid vjs-big-play-centered"></video>
</div>
</ng-template>
<ng-template #transcriptionTemplate>
<div class="vjs-transcription accordion">
<div class="accordion-item">
<h2 class="accordion-header " id="transcription-{{ id }}-head">
<button
class="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
[attr.data-bs-target]="'#transcription-' + id"
[attr.aria-controls]="'transcription-' + id"
aria-expanded="true">
<ng-content select="[transcriptionTitle]">Trascrizione</ng-content>
</button>
</h2>
<div
id="transcription-{{ id }}"
class="accordion-collapse collapse"
role="region"
[attr.aria-labelledby]="'transcription-' + id + '-head'">
<div class="accordion-body">
<ng-content select="[transcriptionText]">-</ng-content>
</div>
</div>
</div>
</div>
</ng-template> `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: ItVideoPlayerComponent, decorators: [{
type: Component,
args: [{
standalone: true,
selector: 'it-video-player',
template: ` (viewType()) {
(viewTypes.Default) {
<div class="row">
<ng-container *ngTemplateOutlet="videoTemplate"></ng-container>
<ng-container *ngTemplateOutlet="transcriptionTemplate"></ng-container>
</div>
}
(viewTypes.Overlay) {
<div #acceptOverlayable class="acceptoverlayable show">
<div #acceptOveraly class="acceptoverlay acceptoverlay-primary fade show">
<div class="acceptoverlay-inner">
<div class="acceptoverlay-icon">
<svg class="icon icon-xl"><use href="/bootstrap-italia/dist/svg/sprites.svg#it-video"></use></svg>
</div>
<p>
Accetta i cookie di YouTube per vedere il video. Puoi gestire le preferenze nella
<a href="#" class="text-white">cookie policy</a>.
</p>
<div class="acceptoverlay-buttons bg-dark">
<button type="button" class="btn btn-primary" (click)="acceptCookieHandler()">Accetta</button>
<div class="form-check">
<input id="chk-remember{{ id }}" type="checkbox" #chkRemember />
<label for="chk-remember{{ id }}">Ricorda per tutti i video</label>
</div>
</div>
</div>
</div>
(cookieAccepted()) {
<div>
<ng-container *ngTemplateOutlet="videoTemplate"></ng-container>
<ng-container *ngTemplateOutlet="transcriptionTemplate"></ng-container>
</div>
}
</div>
}
{
<h1>No video provider</h1>
}
}
<ng-template #videoTemplate>
<div>
<video #videoPlayer class="video-js vjs-theme-bootstrap-italia vjs-fluid vjs-big-play-centered"></video>
</div>
</ng-template>
<ng-template #transcriptionTemplate>
<div class="vjs-transcription accordion">
<div class="accordion-item">
<h2 class="accordion-header " id="transcription-{{ id }}-head">
<button
class="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
[attr.data-bs-target]="'#transcription-' + id"
[attr.aria-controls]="'transcription-' + id"
aria-expanded="true">
<ng-content select="[transcriptionTitle]">Trascrizione</ng-content>
</button>
</h2>
<div
id="transcription-{{ id }}"
class="accordion-collapse collapse"
role="region"
[attr.aria-labelledby]="'transcription-' + id + '-head'">
<div class="accordion-body">
<ng-content select="[transcriptionText]">-</ng-content>
</div>
</div>
</div>
</div>
</ng-template> `,
imports: [NgTemplateOutlet],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
}]
}], ctorParameters: () => [{ type: i1.VideoPlayerConfigService }], propDecorators: { options: [{
type: Input
}], videoPlayerRef: [{
type: ViewChild,
args: ['videoPlayer', { static: false }]
}], acceptOveralyRef: [{
type: ViewChild,
args: ['acceptOveraly', { static: false }]
}], acceptOverlayableRef: [{
type: ViewChild,
args: ['acceptOverlayable', { static: false }]
}], chrRememberRef: [{
type: ViewChild,
args: ['chkRemember', { static: false }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlkZW8tcGxheWVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Rlc2lnbi1hbmd1bGFyLWtpdC9zcmMvbGliL2NvbXBvbmVudHMvY29yZS92aWRlby1wbGF5ZXIvdmlkZW8tcGxheWVyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEVBQ0wsZUFBZSxFQUNmLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsVUFBVSxFQUVWLE1BQU0sRUFDTixRQUFRLEVBQ1IsS0FBSyxFQUNMLE1BQU0sRUFFTixNQUFNLEVBQ04sU0FBUyxFQUNULGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDMUQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLE9BQU8sTUFBTSxVQUFVLENBQUM7QUFHL0IsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDNUUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFckUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHVCQUF1QixDQUFDOzs7QUFHaEQsSUFBSyxRQUdKO0FBSEQsV0FBSyxRQUFRO0lBQ1gsK0JBQW1CLENBQUE7SUFDbkIsK0JBQW1CLENBQUE7QUFDckIsQ0FBQyxFQUhJLFFBQVEsS0FBUixRQUFRLFFBR1o7QUFFRDs7O0dBR0c7QUErRUgsTUFBTSxPQUFPLHNCQUF1QixTQUFRLG1CQUFtQjtJQXdCcEQsV0FBVyxDQUFzQjtJQUsxQyxZQUFvQixNQUFnQztRQUNsRCxLQUFLLEVBQUUsQ0FBQztRQURVLFdBQU0sR0FBTixNQUFNLENBQTBCO1FBZnBELFdBQU0sR0FB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QWEsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ1RlbXBsYXRlT3V0bGV0IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIGFmdGVyTmV4dFJlbmRlcixcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgRGVzdHJveVJlZixcbiAgRWxlbWVudFJlZixcbiAgaW5qZWN0LFxuICBJbmplY3RvcixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25Jbml0LFxuICBzaWduYWwsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdG9PYnNlcnZhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgZGVsYXkgfSBmcm9tICdyeGpzJztcbmltcG9ydCB2aWRlb2pzIGZyb20gJ3ZpZGVvLmpzJztcbmltcG9ydCB0eXBlIFBsYXllciBmcm9tICd2aWRlby5qcy9kaXN0L3R5cGVzL3BsYXllcic7XG5cbmltcG9ydCB7IEl0QWJzdHJhY3RDb21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi9hYnN0cmFjdHMvYWJzdHJhY3QuY29tcG9uZW50JztcbmltcG9ydCB7IFZpZGVvUGxheWVySTE4blNlcnZpY2UgfSBmcm9tICcuL3ZpZGVvLXBsYXllci1pMThuLnNlcnZpY2UnO1xuaW1wb3J0IHsgVGVjaCwgVmlkZW9QbGF5ZXJDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi92aWRlby1wbGF5ZXIuY29uZmlnJztcbmltcG9ydCB7IGNvb2tpZXMgfSBmcm9tICcuL3ZpZGVvLXBsYXllci5jb29raWUnO1xuaW1wb3J0IHsgSXRWaWRlb1BsYXllckNvbmZpZywgSXRWaWRlb1BsYXllck9wdGlvbnMgfSBmcm9tICcuL3ZpZGVvLXBsYXllci5tb2RlbCc7XG5cbmVudW0gVmlld1R5cGUge1xuICBEZWZhdWx0ID0gJ0RFRkFVTFQnLFxuICBPdmVybGF5ID0gJ09WRVJMQVknLFxufVxuXG4vKipcbiAqIFZpZGVvIFBsYXllclxuICogQGRlc2NyaXB0aW9uIENvbXBvbmVudCB0aGF0IGFsbG93cyBwbGF5aW5nIGEgdmlkZW8uXG4gKi9cbkBDb21wb25lbnQoe1xuICBzdGFuZGFsb25lOiB0cnVlLFxuICBzZWxlY3RvcjogJ2l0LXZpZGVvLXBsYXllcicsXG4gIHRlbXBsYXRlOiBgQHN3aXRjaCAodmlld1R5cGUoKSkge1xuICAgICAgQGNhc2UgKHZpZXdUeXBlcy5EZWZhdWx0KSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidmlkZW9UZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0cmFuc2NyaXB0aW9uVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG4gICAgICBAY2FzZSAodmlld1R5cGVzLk92ZXJsYXkpIHtcbiAgICAgICAgPGRpdiAjYWNjZXB0T3ZlcmxheWFibGUgY2xhc3M9XCJhY2NlcHRvdmVybGF5YWJsZSBzaG93XCI+XG4gICAgICAgICAgPGRpdiAjYWNjZXB0T3ZlcmFseSBjbGFzcz1cImFjY2VwdG92ZXJsYXkgYWNjZXB0b3ZlcmxheS1wcmltYXJ5IGZhZGUgc2hvd1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjY2VwdG92ZXJsYXktaW5uZXJcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjY2VwdG92ZXJsYXktaWNvblwiPlxuICAgICAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJpY29uIGljb24teGxcIj48dXNlIGhyZWY9XCIvYm9vdHN0cmFwLWl0YWxpYS9kaXN0L3N2Zy9zcHJpdGVzLnN2ZyNpdC12aWRlb1wiPjwvdXNlPjwvc3ZnPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPHA+XG4gICAgICAgICAgICAgICAgQWNjZXR0YSBpIGNvb2tpZSBkaSBZb3VUdWJlIHBlciB2ZWRlcmUgaWwgdmlkZW8uIFB1b2kgZ2VzdGlyZSBsZSBwcmVmZXJlbnplIG5lbGxhXG4gICAgICAgICAgICAgICAgPGEgaHJlZj1cIiNcIiBjbGFzcz1cInRleHQtd2hpdGVcIj5jb29raWUgcG9saWN5PC9hPi5cbiAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWNjZXB0b3ZlcmxheS1idXR0b25zIGJnLWRhcmtcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIChjbGljayk9XCJhY2NlcHRDb29raWVIYW5kbGVyKClcIj5BY2NldHRhPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tY2hlY2tcIj5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD1cImNoay1yZW1lbWJlcnt7IGlkIH19XCIgdHlwZT1cImNoZWNrYm94XCIgI2Noa1JlbWVtYmVyIC8+XG4gICAgICAgICAgICAgICAgICA8bGFiZWwgZm9yPVwiY2hrLXJlbWVtYmVye3sgaWQgfX1cIj5SaWNvcmRhIHBlciB0dXR0aSBpIHZpZGVvPC9sYWJlbD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICBAaWYgKGNvb2tpZUFjY2VwdGVkKCkpIHtcbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ2aWRlb1RlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0cmFuc2NyaXB0aW9uVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG4gICAgICBAZGVmYXVsdCB7XG4gICAgICAgIDxoMT5ObyB2aWRlbyBwcm92aWRlcjwvaDE+XG4gICAgICB9XG4gICAgfVxuICAgIDxuZy10ZW1wbGF0ZSAjdmlkZW9UZW1wbGF0ZT5cbiAgICAgIDxkaXY+XG4gICAgICAgIDx2aWRlbyAjdmlkZW9QbGF5ZXIgY2xhc3M9XCJ2aWRlby1qcyB2anMtdGhlbWUtYm9vdHN0cmFwLWl0YWxpYSB2anMtZmx1aWQgdmpzLWJpZy1wbGF5LWNlbnRlcmVkXCI+PC92aWRlbz5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICA8bmctdGVtcGxhdGUgI3RyYW5zY3JpcHRpb25UZW1wbGF0ZT5cbiAgICAgIDxkaXYgY2xhc3M9XCJ2anMtdHJhbnNjcmlwdGlvbiBhY2NvcmRpb25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImFjY29yZGlvbi1pdGVtXCI+XG4gICAgICAgICAgPGgyIGNsYXNzPVwiYWNjb3JkaW9uLWhlYWRlciBcIiBpZD1cInRyYW5zY3JpcHRpb24te3sgaWQgfX0taGVhZFwiPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICBjbGFzcz1cImFjY29yZGlvbi1idXR0b24gY29sbGFwc2VkXCJcbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGRhdGEtYnMtdG9nZ2xlPVwiY29sbGFwc2VcIlxuICAgICAgICAgICAgICBbYXR0ci5kYXRhLWJzLXRhcmdldF09XCInI3RyYW5zY3JpcHRpb24tJyArIGlkXCJcbiAgICAgICAgICAgICAgW2F0dHIuYXJpYS1jb250cm9sc109XCIndHJhbnNjcmlwdGlvbi0nICsgaWRcIlxuICAgICAgICAgICAgICBhcmlhLWV4cGFuZGVkPVwidHJ1ZVwiPlxuICAgICAgICAgICAgICA8bmctY29udGVudCBzZWxlY3Q9XCJbdHJhbnNjcmlwdGlvblRpdGxlXVwiPlRyYXNjcml6aW9uZTwvbmctY29udGVudD5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvaDI+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgaWQ9XCJ0cmFuc2NyaXB0aW9uLXt7IGlkIH19XCJcbiAgICAgICAgICAgIGNsYXNzPVwiYWNjb3JkaW9uLWNvbGxhcHNlIGNvbGxhcHNlXCJcbiAgICAgICAgICAgIHJvbGU9XCJyZWdpb25cIlxuICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbGxlZGJ5XT1cIid0cmFuc2NyaXB0aW9uLScgKyBpZCArICctaGVhZCdcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhY2NvcmRpb24tYm9keVwiPlxuICAgICAgICAgICAgICA8bmctY29udGVudCBzZWxlY3Q9XCJbdHJhbnNjcmlwdGlvblRleHRdXCI+LTwvbmctY29udGVudD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctdGVtcGxhdGU+IGAsXG4gIGltcG9ydHM6IFtOZ1RlbXBsYXRlT3V0bGV0XSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIEl0VmlkZW9QbGF5ZXJDb21wb25lbnQgZXh0ZW5kcyBJdEFic3RyYWN0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgLyoqXG4gICAqIE9wdGlvbnMgZm9yIHZpZGVvIHBsYXllciBjb25maWd1cmF0aW9uXG4gICAqL1xuICBASW5wdXQoKSBvcHRpb25zITogSXRWaWRlb1BsYXllck9wdGlvbnM7XG5cbiAgQFZpZXdDaGlsZCgndmlkZW9QbGF5ZXInLCB7IHN0YXRpYzogZmFsc2UgfSkgdmlkZW9QbGF5ZXJSZWY/OiBFbGVtZW50UmVmPEhUTUxWaWRlb0VsZW1lbnQ+O1xuXG4gIEBWaWV3Q2hpbGQoJ2FjY2VwdE92ZXJhbHknLCB7IHN0YXRpYzogZmFsc2UgfSkgYWNjZXB0T3ZlcmFseVJlZj86IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuXG4gIEBWaWV3Q2hpbGQoJ2FjY2VwdE92ZXJsYXlhYmxlJywgeyBzdGF0aWM6IGZhbHNlIH0pIGFjY2VwdE92ZXJsYXlhYmxlUmVmPzogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG5cbiAgQFZpZXdDaGlsZCgnY2hrUmVtZW1iZXInLCB7IHN0YXRpYzogZmFsc2UgfSkgY2hyUmVtZW1iZXJSZWY/OiBFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+O1xuXG4gIHBsYXllcjogUGxheWVyIHwgbnVsbCA9IG51bGw7XG5cbiAgcmVhZG9ubHkgdmlld1R5cGVzID0gVmlld1R5cGU7XG5cbiAgcmVhZG9ubHkgdmlld1R5cGUgPSBzaWduYWw8Vmlld1R5cGUgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG5cbiAgcmVhZG9ubHkgY29va2llQWNjZXB0ZWQgPSBzaWduYWwoZmFsc2UpO1xuXG4gIHByb3RlY3RlZCByZWFkb25seSBpMThuU2VydmljZSA9IGluamVjdChWaWRlb1BsYXllckkxOG5TZXJ2aWNlKTtcblxuICByZWFkb25seSAjZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcblxuICBwcml2YXRlIG5nWm9uZSA9IGluamVjdChOZ1pvbmUpO1xuICBwcml2YXRlIGluamVjdG9yID0gaW5qZWN0KEluamVjdG9yKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbmZpZzogVmlkZW9QbGF5ZXJDb25maWdTZXJ2aWNlKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGFmdGVyTmV4dFJlbmRlcigoKSA9PiB7XG4gICAgICBpZiAodGhpcy52aWV3VHlwZSgpID09PSBWaWV3VHlwZS5PdmVybGF5ICYmIGNvb2tpZXMuaXNDaG9pY2VSZW1lbWJlcmVkKCd5b3V0dWJlLmNvbScpKSB7XG4gICAgICAgIHRoaXMuaGlkZU92ZXJsYXkoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuI2Rlc3Ryb3lSZWYub25EZXN0cm95KCgpID0+IHRoaXMucGxheWVyPy5kaXNwb3NlKCkpO1xuICB9XG5cbiAgYXN5bmMgbmdPbkluaXQoKSB7XG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5jb25maWcubWVyZ2VDb25maWcodGhpcy5vcHRpb25zKTtcbiAgICB0aGlzLnNldFZpZXdUeXBlKGNvbmZpZyk7XG4gICAgLy8gQXZvaWQgcnVubmluZyBjaGFuZ2UgZGV0ZWN0aW9ucyB3aGlsZSB0aGUgc2NyaXB0IGlzIGJlaW5nIGxvYWRlZC5cbiAgICBhd2FpdCB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB0aGlzLmNvbmZpZy5jb25maWd1cmVUZWNoKGNvbmZpZyBhcyB7IHRlY2g6IFRlY2ggfSkpO1xuXG4gICAgaWYgKCF0aGlzLnZpZGVvUGxheWVyUmVmKSB7XG4gICAgICAvLyBOb3RlOiBObyBuZWVkIHRvIHBpcGUgd2l0aCBgdGFrZVVudGlsRGVzdHJveWVkYDsgYHRvT2JzZXJ2YWJsZWAgaXNcbiAgICAgIC8vIGNvbXBsZXRlZCBieSBBbmd1bGFyIHdoZW4gdGhlIGBEZXN0cm95UmVmYCBmcm9tIHRoZSBpbmplY3RvciBpcyBkZXN0cm95ZWQuXG4gICAgICB0b09ic2VydmFibGUodGhpcy5jb29raWVBY2NlcHRlZCwgeyBpbmplY3RvcjogdGhpcy5pbmplY3RvciB9KVxuICAgICAgICAucGlwZShkZWxheSgwKSlcbiAgICAgICAgLnN1YnNjcmliZSh2YWx1ZSA9PiB7XG4gICAgICAgICAgaWYgKHZhbHVlICYmICF0aGlzLnBsYXllcikge1xuICAgICAgICAgICAgdGhpcy5pbml0VmlkZW9QbGF5ZXIoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5pbml0VmlkZW9QbGF5ZXIoKTtcbiAgfVxuXG4gIGFjY2VwdENvb2tpZUhhbmRsZXIoKSB7XG4gICAgdGhpcy5yZW1lbWJlckhhbmRsZXIoKTtcbiAgICB0aGlzLmhpZGVPdmVybGF5KCk7XG4gICAgdGhpcy5jb29raWVBY2NlcHRlZC5zZXQodHJ1ZSk7XG4gIH1cblxuICBwcml2YXRlIGluaXRWaWRlb1BsYXllcigpIHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmNvbmZpZy5tZXJnZUNvbmZpZyh0aGlzLm9wdGlvbnMpO1xuICAgIHRoaXMuc2V0VmlkZW9BdHRyaWJ1dGVzKGNvbmZpZyk7XG4gICAgdGhpcy5zZXRWaWRlb1BsYXllcigpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRWaWRlb1BsYXllcigpIHtcbiAgICBjb25zdCBjb25maWcgPSB0aGlzLmNvbmZpZy5tZXJnZUNvbmZpZyh0aGlzLm9wdGlvbnMpO1xuICAgIGNvbnN0IG9uUGxheWVyUmVhZHlDYiA9ICgpID0+IHtcbiAgICAgIGlmICghdGhpcy5wbGF5ZXIpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5pMThuU2VydmljZS5pbml0KHRoaXMucGxheWVyLCB0aGlzLiNkZXN0cm95UmVmKTtcbiAgICB9O1xuXG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMudmlkZW9QbGF5ZXJSZWY/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICB0aHJvdyBFcnJvcigndmlkZW9QbGF5ZXJSZWYgaXMgdW5kZWZpbmVkJyk7XG4gICAgfVxuXG4gICAgdGhpcy5wbGF5ZXIgPSB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB2aWRlb2pzKGVsZW1lbnQsIGNvbmZpZywgb25QbGF5ZXJSZWFkeUNiKSk7XG4gIH1cblxuICBwcml2YXRlIHNldFZpZXdUeXBlKGNvbmZpZzogSXRWaWRlb1BsYXllckNvbmZpZykge1xuICAgIHRoaXMudmlld1R5cGUuc2V0KGNvbmZpZy50ZWNoID09PSAneW91dHViZScgPyBWaWV3VHlwZS5PdmVybGF5IDogVmlld1R5cGUuRGVmYXVsdCk7XG5cbiAgICB0aGlzLmNvb2tpZUFjY2VwdGVkLnNldCh0aGlzLnZpZXdUeXBlKCkgPT09IFZpZXdUeXBlLk92ZXJsYXkgJiYgY29va2llcy5pc0Nob2ljZVJlbWVtYmVyZWQoJ3lvdXR1YmUuY29tJykpO1xuICB9XG5cbiAgcHJpdmF0ZSBoaWRlT3ZlcmxheSgpIHtcbiAgICBpZiAoIXRoaXMuYWNjZXB0T3ZlcmxheWFibGVSZWYpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY2xhc3NlcyA9IFsnc2hvdyddO1xuICAgIHRoaXMuYWNjZXB0T3ZlcmxheWFibGVSZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKC4uLmNsYXNzZXMpO1xuICAgIGlmICghdGhpcy5hY2NlcHRPdmVyYWx5UmVmKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYWNjZXB0T3ZlcmFseVJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoLi4uY2xhc3Nlcyk7XG4gICAgdGhpcy5hY2NlcHRPdmVyYWx5UmVmLm5hdGl2ZUVsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLWhpZGRlbicsICd0cnVlJyk7XG4gIH1cblxuICBwcml2YXRlIHJlbWVtYmVySGFuZGxlcigpIHtcbiAgICBpZiAoIXRoaXMuY2hyUmVtZW1iZXJSZWYpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmVtZW1iZXIgPSB0aGlzLmNoclJlbWVtYmVyUmVmLm5hdGl2ZUVsZW1lbnQuY2hlY2tlZDtcbiAgICBjb29raWVzLnJlbWVtYmVyQ2hvaWNlKCd5b3V0dWJlLmNvbScsIHJlbWVtYmVyKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0VmlkZW9BdHRyaWJ1dGVzKG9wdGlvbnM6IEl0VmlkZW9QbGF5ZXJPcHRpb25zKSB7XG4gICAgaWYgKCF0aGlzLnZpZGVvUGxheWVyUmVmKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHYgPSB0aGlzLnZpZGVvUGxheWVyUmVmLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICBjb25zdCB7IGF1dG9wbGF5LCBjb250cm9scywgbG9vcCwgbXV0ZWQsIHBvc3RlciwgZmx1aWQgfSA9IG9wdGlvbnM7XG5cbiAgICBpZiAoYXV0b3BsYXkpIHtcbiAgICAgIHYuc2V0QXR0cmlidXRlKCdhdXRvcGxheScsIGF1dG9wbGF5LnRvU3RyaW5nKCkpO1xuICAgIH1cblxuICAgIGlmIChjb250cm9scykge1xuICAgICAgdi5zZXRBdHRyaWJ1dGUoJ2NvbnRyb2xzJywgJycpO1xuICAgIH1cblxuICAgIGlmIChsb29wKSB7XG4gICAgICB2LnNldEF0dHJpYnV0ZSgnbG9vcCcsICcnKTtcbiAgICB9XG5cbiAgICBpZiAobXV0ZWQpIHtcbiAgICAgIHYuc2V0QXR0cmlidXRlKCdtdXRlZCcsICcnKTtcbiAgICB9XG5cbiAgICBpZiAocG9zdGVyKSB7XG4gICAgICB2LnNldEF0dHJpYnV0ZSgncG9zdGVyJywgcG9zdGVyKTtcbiAgICB9XG5cbiAgICBpZiAoZmx1aWQpIHtcbiAgICAgIHYuc2V0QXR0cmlidXRlKCdmbHVpZCcsICcnKTtcbiAgICB9XG5cbiAgICB2LnNldEF0dHJpYnV0ZSgncHJlbG9hZCcsICdub25lJyk7XG4gICAgdi5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgJycpO1xuICB9XG59XG4iXX0=