ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
252 lines • 36.1 kB
JavaScript
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
import { DOCUMENT } from '@angular/common';
import { ChangeDetectionStrategy, Component, Inject, Input } from '@angular/core';
import { getPixelRatio, getStyleStr, reRendering, rotateWatermark } from './util';
import * as i0 from "@angular/core";
/**
* Base size of the canvas, 1 for parallel layout and 2 for alternate layout
* Only alternate layout is currently supported
*/
const BaseSize = 2;
const FontGap = 3;
export class NzWaterMarkComponent {
constructor(el, document, cdr) {
this.el = el;
this.document = document;
this.cdr = cdr;
this.nzWidth = 120;
this.nzHeight = 64;
this.nzRotate = -22;
this.nzZIndex = 9;
this.nzImage = '';
this.nzContent = '';
this.nzFont = {};
this.nzGap = [100, 100];
this.nzOffset = [this.nzGap[0] / 2, this.nzGap[1] / 2];
this.waterMarkElement = this.document.createElement('div');
this.stopObservation = false;
this.observer = new MutationObserver(mutations => {
if (this.stopObservation) {
return;
}
mutations.forEach(mutation => {
if (reRendering(mutation, this.waterMarkElement)) {
this.destroyWatermark();
this.renderWatermark();
}
});
});
}
ngOnInit() {
this.observer.observe(this.el.nativeElement, {
subtree: true,
childList: true,
attributeFilter: ['style', 'class']
});
}
ngAfterViewInit() {
this.renderWatermark();
}
ngOnChanges(changes) {
const { nzRotate, nzZIndex, nzWidth, nzHeight, nzImage, nzContent, nzFont, gapX, gapY, offsetLeft, offsetTop } = changes;
if (nzRotate ||
nzZIndex ||
nzWidth ||
nzHeight ||
nzImage ||
nzContent ||
nzFont ||
gapX ||
gapY ||
offsetLeft ||
offsetTop) {
this.renderWatermark();
}
}
getFont() {
const font = {
color: 'rgba(0,0,0,.15)',
fontSize: 16,
fontWeight: 'normal',
fontFamily: 'sans-serif',
fontStyle: 'normal'
};
this.nzFont = { ...font, ...this.nzFont };
this.cdr.markForCheck();
}
getMarkStyle() {
const markStyle = {
zIndex: this.nzZIndex,
position: 'absolute',
left: 0,
top: 0,
width: '100%',
height: '100%',
pointerEvents: 'none',
backgroundRepeat: 'repeat',
visibility: 'visible'
};
/** Calculate the style of the nzOffset */
let positionLeft = (this.nzOffset?.[0] ?? this.nzGap[0] / 2) - this.nzGap[0] / 2;
let positionTop = (this.nzOffset?.[1] ?? this.nzGap[1] / 2) - this.nzGap[1] / 2;
if (positionLeft > 0) {
markStyle.left = `${positionLeft}px`;
markStyle.width = `calc(100% - ${positionLeft}px)`;
positionLeft = 0;
}
if (positionTop > 0) {
markStyle.top = `${positionTop}px`;
markStyle.height = `calc(100% - ${positionTop}px)`;
positionTop = 0;
}
markStyle.backgroundPosition = `${positionLeft}px ${positionTop}px`;
return markStyle;
}
destroyWatermark() {
if (this.waterMarkElement) {
this.waterMarkElement.remove();
}
}
appendWatermark(base64Url, markWidth) {
this.stopObservation = true;
this.waterMarkElement.setAttribute('style', getStyleStr({
...this.getMarkStyle(),
backgroundImage: `url('${base64Url}')`,
backgroundSize: `${(this.nzGap[0] + markWidth) * BaseSize}px`
}));
this.el.nativeElement.append(this.waterMarkElement);
this.cdr.markForCheck();
// Delayed execution
setTimeout(() => {
this.stopObservation = false;
this.cdr.markForCheck();
});
}
getMarkSize(ctx) {
let defaultWidth = 120;
let defaultHeight = 64;
if (!this.nzImage && ctx.measureText) {
ctx.font = `${Number(this.nzFont.fontSize)}px ${this.nzFont.fontFamily}`;
const contents = Array.isArray(this.nzContent) ? this.nzContent : [this.nzContent];
const widths = contents.map(item => ctx.measureText(item).width);
defaultWidth = Math.ceil(Math.max(...widths));
defaultHeight = Number(this.nzFont.fontSize) * contents.length + (contents.length - 1) * FontGap;
}
return [this.nzWidth ?? defaultWidth, this.nzHeight ?? defaultHeight];
}
fillTexts(ctx, drawX, drawY, drawWidth, drawHeight) {
const ratio = getPixelRatio();
const mergedFontSize = Number(this.nzFont.fontSize) * ratio;
ctx.font = `${this.nzFont.fontStyle} normal ${this.nzFont.fontWeight} ${mergedFontSize}px/${drawHeight}px ${this.nzFont.fontFamily}`;
if (this.nzFont.color)
ctx.fillStyle = this.nzFont.color;
ctx.textAlign = 'center';
ctx.textBaseline = 'top';
ctx.translate(drawWidth / 2, 0);
const contents = Array.isArray(this.nzContent) ? this.nzContent : [this.nzContent];
contents?.forEach((item, index) => {
ctx.fillText(item ?? '', drawX, drawY + index * (mergedFontSize + FontGap * ratio));
});
}
drawText(canvas, ctx, drawX, drawY, drawWidth, drawHeight, alternateRotateX, alternateRotateY, alternateDrawX, alternateDrawY, markWidth) {
this.fillTexts(ctx, drawX, drawY, drawWidth, drawHeight);
/** Fill the interleaved text after rotation */
ctx.restore();
rotateWatermark(ctx, alternateRotateX, alternateRotateY, this.nzRotate);
this.fillTexts(ctx, alternateDrawX, alternateDrawY, drawWidth, drawHeight);
this.appendWatermark(canvas.toDataURL(), markWidth);
}
renderWatermark() {
if (!this.nzContent && !this.nzImage) {
return;
}
const canvas = this.document.createElement('canvas');
const ctx = canvas.getContext('2d');
if (ctx) {
if (!this.waterMarkElement) {
this.waterMarkElement = this.document.createElement('div');
}
this.getFont();
const ratio = getPixelRatio();
const [markWidth, markHeight] = this.getMarkSize(ctx);
const canvasWidth = (this.nzGap[0] + markWidth) * ratio;
const canvasHeight = (this.nzGap[1] + markHeight) * ratio;
canvas.setAttribute('width', `${canvasWidth * BaseSize}px`);
canvas.setAttribute('height', `${canvasHeight * BaseSize}px`);
const drawX = (this.nzGap[0] * ratio) / 2;
const drawY = (this.nzGap[1] * ratio) / 2;
const drawWidth = markWidth * ratio;
const drawHeight = markHeight * ratio;
const rotateX = (drawWidth + this.nzGap[0] * ratio) / 2;
const rotateY = (drawHeight + this.nzGap[1] * ratio) / 2;
/** Alternate drawing parameters */
const alternateDrawX = drawX + canvasWidth;
const alternateDrawY = drawY + canvasHeight;
const alternateRotateX = rotateX + canvasWidth;
const alternateRotateY = rotateY + canvasHeight;
ctx.save();
rotateWatermark(ctx, rotateX, rotateY, this.nzRotate);
if (this.nzImage) {
const img = new Image();
img.onload = () => {
ctx.drawImage(img, drawX, drawY, drawWidth, drawHeight);
/** Draw interleaved pictures after rotation */
ctx.restore();
rotateWatermark(ctx, alternateRotateX, alternateRotateY, this.nzRotate);
ctx.drawImage(img, alternateDrawX, alternateDrawY, drawWidth, drawHeight);
this.appendWatermark(canvas.toDataURL(), markWidth);
};
img.onerror = () => this.drawText(canvas, ctx, drawX, drawY, drawWidth, drawHeight, alternateRotateX, alternateRotateY, alternateDrawX, alternateDrawY, markWidth);
img.crossOrigin = 'anonymous';
img.referrerPolicy = 'no-referrer';
img.src = this.nzImage;
}
else {
this.drawText(canvas, ctx, drawX, drawY, drawWidth, drawHeight, alternateRotateX, alternateRotateY, alternateDrawX, alternateDrawY, markWidth);
}
}
}
ngOnDestroy() {
this.observer.disconnect();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: NzWaterMarkComponent, deps: [{ token: i0.ElementRef }, { token: DOCUMENT }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: NzWaterMarkComponent, isStandalone: true, selector: "nz-water-mark", inputs: { nzWidth: "nzWidth", nzHeight: "nzHeight", nzRotate: "nzRotate", nzZIndex: "nzZIndex", nzImage: "nzImage", nzContent: "nzContent", nzFont: "nzFont", nzGap: "nzGap", nzOffset: "nzOffset" }, host: { classAttribute: "ant-water-mark" }, exportAs: ["NzWaterMark"], usesOnChanges: true, ngImport: i0, template: ` <ng-content></ng-content> `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: NzWaterMarkComponent, decorators: [{
type: Component,
args: [{
selector: 'nz-water-mark',
standalone: true,
exportAs: 'NzWaterMark',
changeDetection: ChangeDetectionStrategy.OnPush,
template: ` <ng-content></ng-content> `,
host: {
class: 'ant-water-mark'
}
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: Document, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }, { type: i0.ChangeDetectorRef }], propDecorators: { nzWidth: [{
type: Input
}], nzHeight: [{
type: Input
}], nzRotate: [{
type: Input
}], nzZIndex: [{
type: Input
}], nzImage: [{
type: Input
}], nzContent: [{
type: Input
}], nzFont: [{
type: Input
}], nzGap: [{
type: Input
}], nzOffset: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2F0ZXItbWFyay5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9jb21wb25lbnRzL3dhdGVyLW1hcmsvd2F0ZXItbWFyay5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFFTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUVULE1BQU0sRUFDTixLQUFLLEVBS04sTUFBTSxlQUFlLENBQUM7QUFHdkIsT0FBTyxFQUFFLGFBQWEsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLGVBQWUsRUFBRSxNQUFNLFFBQVEsQ0FBQzs7QUFFbEY7OztHQUdHO0FBQ0gsTUFBTSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBQ25CLE1BQU0sT0FBTyxHQUFHLENBQUMsQ0FBQztBQVlsQixNQUFNLE9BQU8sb0JBQW9CO0lBMEIvQixZQUNVLEVBQWMsRUFDSSxRQUFrQixFQUNwQyxHQUFzQjtRQUZ0QixPQUFFLEdBQUYsRUFBRSxDQUFZO1FBQ0ksYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNwQyxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQTVCdkIsWUFBTyxHQUFXLEdBQUcsQ0FBQztRQUN0QixhQUFRLEdBQVcsRUFBRSxDQUFDO1FBQ3RCLGFBQVEsR0FBVyxDQUFDLEVBQUUsQ0FBQztRQUN2QixhQUFRLEdBQVcsQ0FBQyxDQUFDO1FBQ3JCLFlBQU8sR0FBVyxFQUFFLENBQUM7UUFDckIsY0FBUyxHQUFzQixFQUFFLENBQUM7UUFDbEMsV0FBTSxHQUFhLEVBQUUsQ0FBQztRQUN0QixVQUFLLEdBQXFCLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3JDLGFBQVEsR0FBcUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FB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QVE7c0JBQWhCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgU2ltcGxlQ2hhbmdlc1xufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgTWFya1N0eWxlVHlwZSwgRm9udFR5cGUgfSBmcm9tICcuL3R5cGluZ3MnO1xuaW1wb3J0IHsgZ2V0UGl4ZWxSYXRpbywgZ2V0U3R5bGVTdHIsIHJlUmVuZGVyaW5nLCByb3RhdGVXYXRlcm1hcmsgfSBmcm9tICcuL3V0aWwnO1xuXG4vKipcbiAqIEJhc2Ugc2l6ZSBvZiB0aGUgY2FudmFzLCAxIGZvciBwYXJhbGxlbCBsYXlvdXQgYW5kIDIgZm9yIGFsdGVybmF0ZSBsYXlvdXRcbiAqIE9ubHkgYWx0ZXJuYXRlIGxheW91dCBpcyBjdXJyZW50bHkgc3VwcG9ydGVkXG4gKi9cbmNvbnN0IEJhc2VTaXplID0gMjtcbmNvbnN0IEZvbnRHYXAgPSAzO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduei13YXRlci1tYXJrJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgZXhwb3J0QXM6ICdOeldhdGVyTWFyaycsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZTogYCA8bmctY29udGVudD48L25nLWNvbnRlbnQ+IGAsXG4gIGhvc3Q6IHtcbiAgICBjbGFzczogJ2FudC13YXRlci1tYXJrJ1xuICB9XG59KVxuZXhwb3J0IGNsYXNzIE56V2F0ZXJNYXJrQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIG56V2lkdGg6IG51bWJlciA9IDEyMDtcbiAgQElucHV0KCkgbnpIZWlnaHQ6IG51bWJlciA9IDY0O1xuICBASW5wdXQoKSBuelJvdGF0ZTogbnVtYmVyID0gLTIyO1xuICBASW5wdXQoKSBuelpJbmRleDogbnVtYmVyID0gOTtcbiAgQElucHV0KCkgbnpJbWFnZTogc3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpIG56Q29udGVudDogc3RyaW5nIHwgc3RyaW5nW10gPSAnJztcbiAgQElucHV0KCkgbnpGb250OiBGb250VHlwZSA9IHt9O1xuICBASW5wdXQoKSBuekdhcDogW251bWJlciwgbnVtYmVyXSA9IFsxMDAsIDEwMF07XG4gIEBJbnB1dCgpIG56T2Zmc2V0OiBbbnVtYmVyLCBudW1iZXJdID0gW3RoaXMubnpHYXBbMF0gLyAyLCB0aGlzLm56R2FwWzFdIC8gMl07XG5cbiAgd2F0ZXJNYXJrRWxlbWVudDogSFRNTERpdkVsZW1lbnQgPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICBzdG9wT2JzZXJ2YXRpb246IGJvb2xlYW4gPSBmYWxzZTtcblxuICBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKG11dGF0aW9ucyA9PiB7XG4gICAgaWYgKHRoaXMuc3RvcE9ic2VydmF0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIG11dGF0aW9ucy5mb3JFYWNoKG11dGF0aW9uID0+IHtcbiAgICAgIGlmIChyZVJlbmRlcmluZyhtdXRhdGlvbiwgdGhpcy53YXRlck1hcmtFbGVtZW50KSkge1xuICAgICAgICB0aGlzLmRlc3Ryb3lXYXRlcm1hcmsoKTtcbiAgICAgICAgdGhpcy5yZW5kZXJXYXRlcm1hcmsoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBlbDogRWxlbWVudFJlZixcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIGRvY3VtZW50OiBEb2N1bWVudCxcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWZcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMub2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQsIHtcbiAgICAgIHN1YnRyZWU6IHRydWUsXG4gICAgICBjaGlsZExpc3Q6IHRydWUsXG4gICAgICBhdHRyaWJ1dGVGaWx0ZXI6IFsnc3R5bGUnLCAnY2xhc3MnXVxuICAgIH0pO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyV2F0ZXJtYXJrKCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgY29uc3QgeyBuelJvdGF0ZSwgbnpaSW5kZXgsIG56V2lkdGgsIG56SGVpZ2h0LCBuekltYWdlLCBuekNvbnRlbnQsIG56Rm9udCwgZ2FwWCwgZ2FwWSwgb2Zmc2V0TGVmdCwgb2Zmc2V0VG9wIH0gPVxuICAgICAgY2hhbmdlcztcblxuICAgIGlmIChcbiAgICAgIG56Um90YXRlIHx8XG4gICAgICBuelpJbmRleCB8fFxuICAgICAgbnpXaWR0aCB8fFxuICAgICAgbnpIZWlnaHQgfHxcbiAgICAgIG56SW1hZ2UgfHxcbiAgICAgIG56Q29udGVudCB8fFxuICAgICAgbnpGb250IHx8XG4gICAgICBnYXBYIHx8XG4gICAgICBnYXBZIHx8XG4gICAgICBvZmZzZXRMZWZ0IHx8XG4gICAgICBvZmZzZXRUb3BcbiAgICApIHtcbiAgICAgIHRoaXMucmVuZGVyV2F0ZXJtYXJrKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0Rm9udCgpOiB2b2lkIHtcbiAgICBjb25zdCBmb250OiBGb250VHlwZSA9IHtcbiAgICAgIGNvbG9yOiAncmdiYSgwLDAsMCwuMTUpJyxcbiAgICAgIGZvbnRTaXplOiAxNixcbiAgICAgIGZvbnRXZWlnaHQ6ICdub3JtYWwnLFxuICAgICAgZm9udEZhbWlseTogJ3NhbnMtc2VyaWYnLFxuICAgICAgZm9udFN0eWxlOiAnbm9ybWFsJ1xuICAgIH07XG5cbiAgICB0aGlzLm56Rm9udCA9IHsgLi4uZm9udCwgLi4udGhpcy5uekZvbnQgfTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIGdldE1hcmtTdHlsZSgpOiBNYXJrU3R5bGVUeXBlIHtcbiAgICBjb25zdCBtYXJrU3R5bGU6IE1hcmtTdHlsZVR5cGUgPSB7XG4gICAgICB6SW5kZXg6IHRoaXMubnpaSW5kZXgsXG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIGxlZnQ6IDAsXG4gICAgICB0b3A6IDAsXG4gICAgICB3aWR0aDogJzEwMCUnLFxuICAgICAgaGVpZ2h0OiAnMTAwJScsXG4gICAgICBwb2ludGVyRXZlbnRzOiAnbm9uZScsXG4gICAgICBiYWNrZ3JvdW5kUmVwZWF0OiAncmVwZWF0JyxcbiAgICAgIHZpc2liaWxpdHk6ICd2aXNpYmxlJ1xuICAgIH07XG5cbiAgICAvKiogQ2FsY3VsYXRlIHRoZSBzdHlsZSBvZiB0aGUgbnpPZmZzZXQgKi9cbiAgICBsZXQgcG9zaXRpb25MZWZ0ID0gKHRoaXMubnpPZmZzZXQ/LlswXSA/PyB0aGlzLm56R2FwWzBdIC8gMikgLSB0aGlzLm56R2FwWzBdIC8gMjtcbiAgICBsZXQgcG9zaXRpb25Ub3AgPSAodGhpcy5uek9mZnNldD8uWzFdID8/IHRoaXMubnpHYXBbMV0gLyAyKSAtIHRoaXMubnpHYXBbMV0gLyAyO1xuICAgIGlmIChwb3NpdGlvbkxlZnQgPiAwKSB7XG4gICAgICBtYXJrU3R5bGUubGVmdCA9IGAke3Bvc2l0aW9uTGVmdH1weGA7XG4gICAgICBtYXJrU3R5bGUud2lkdGggPSBgY2FsYygxMDAlIC0gJHtwb3NpdGlvbkxlZnR9cHgpYDtcbiAgICAgIHBvc2l0aW9uTGVmdCA9IDA7XG4gICAgfVxuICAgIGlmIChwb3NpdGlvblRvcCA+IDApIHtcbiAgICAgIG1hcmtTdHlsZS50b3AgPSBgJHtwb3NpdGlvblRvcH1weGA7XG4gICAgICBtYXJrU3R5bGUuaGVpZ2h0ID0gYGNhbGMoMTAwJSAtICR7cG9zaXRpb25Ub3B9cHgpYDtcbiAgICAgIHBvc2l0aW9uVG9wID0gMDtcbiAgICB9XG4gICAgbWFya1N0eWxlLmJhY2tncm91bmRQb3NpdGlvbiA9IGAke3Bvc2l0aW9uTGVmdH1weCAke3Bvc2l0aW9uVG9wfXB4YDtcblxuICAgIHJldHVybiBtYXJrU3R5bGU7XG4gIH1cblxuICBkZXN0cm95V2F0ZXJtYXJrKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLndhdGVyTWFya0VsZW1lbnQpIHtcbiAgICAgIHRoaXMud2F0ZXJNYXJrRWxlbWVudC5yZW1vdmUoKTtcbiAgICB9XG4gIH1cblxuICBhcHBlbmRXYXRlcm1hcmsoYmFzZTY0VXJsOiBzdHJpbmcsIG1hcmtXaWR0aDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5zdG9wT2JzZXJ2YXRpb24gPSB0cnVlO1xuICAgIHRoaXMud2F0ZXJNYXJrRWxlbWVudC5zZXRBdHRyaWJ1dGUoXG4gICAgICAnc3R5bGUnLFxuICAgICAgZ2V0U3R5bGVTdHIoe1xuICAgICAgICAuLi50aGlzLmdldE1hcmtTdHlsZSgpLFxuICAgICAgICBiYWNrZ3JvdW5kSW1hZ2U6IGB1cmwoJyR7YmFzZTY0VXJsfScpYCxcbiAgICAgICAgYmFja2dyb3VuZFNpemU6IGAkeyh0aGlzLm56R2FwWzBdICsgbWFya1dpZHRoKSAqIEJhc2VTaXplfXB4YFxuICAgICAgfSlcbiAgICApO1xuICAgIHRoaXMuZWwubmF0aXZlRWxlbWVudC5hcHBlbmQodGhpcy53YXRlck1hcmtFbGVtZW50KTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcblxuICAgIC8vIERlbGF5ZWQgZXhlY3V0aW9uXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnN0b3BPYnNlcnZhdGlvbiA9IGZhbHNlO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfSk7XG4gIH1cblxuICBnZXRNYXJrU2l6ZShjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCk6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgIGxldCBkZWZhdWx0V2lkdGggPSAxMjA7XG4gICAgbGV0IGRlZmF1bHRIZWlnaHQgPSA2NDtcbiAgICBpZiAoIXRoaXMubnpJbWFnZSAmJiBjdHgubWVhc3VyZVRleHQpIHtcbiAgICAgIGN0eC5mb250ID0gYCR7TnVtYmVyKHRoaXMubnpGb250LmZvbnRTaXplKX1weCAke3RoaXMubnpGb250LmZvbnRGYW1pbHl9YDtcbiAgICAgIGNvbnN0IGNvbnRlbnRzID0gQXJyYXkuaXNBcnJheSh0aGlzLm56Q29udGVudCkgPyB0aGlzLm56Q29udGVudCA6IFt0aGlzLm56Q29udGVudF07XG4gICAgICBjb25zdCB3aWR0aHMgPSBjb250ZW50cy5tYXAoaXRlbSA9PiBjdHgubWVhc3VyZVRleHQoaXRlbSEpLndpZHRoKTtcbiAgICAgIGRlZmF1bHRXaWR0aCA9IE1hdGguY2VpbChNYXRoLm1heCguLi53aWR0aHMpKTtcbiAgICAgIGRlZmF1bHRIZWlnaHQgPSBOdW1iZXIodGhpcy5uekZvbnQuZm9udFNpemUpICogY29udGVudHMubGVuZ3RoICsgKGNvbnRlbnRzLmxlbmd0aCAtIDEpICogRm9udEdhcDtcbiAgICB9XG4gICAgcmV0dXJuIFt0aGlzLm56V2lkdGggPz8gZGVmYXVsdFdpZHRoLCB0aGlzLm56SGVpZ2h0ID8/IGRlZmF1bHRIZWlnaHRdO1xuICB9XG5cbiAgZmlsbFRleHRzKGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELCBkcmF3WDogbnVtYmVyLCBkcmF3WTogbnVtYmVyLCBkcmF3V2lkdGg6IG51bWJlciwgZHJhd0hlaWdodDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgcmF0aW8gPSBnZXRQaXhlbFJhdGlvKCk7XG4gICAgY29uc3QgbWVyZ2VkRm9udFNpemUgPSBOdW1iZXIodGhpcy5uekZvbnQuZm9udFNpemUpICogcmF0aW87XG4gICAgY3R4LmZvbnQgPSBgJHt0aGlzLm56Rm9udC5mb250U3R5bGV9IG5vcm1hbCAke3RoaXMubnpGb250LmZvbnRXZWlnaHR9ICR7bWVyZ2VkRm9udFNpemV9cHgvJHtkcmF3SGVpZ2h0fXB4ICR7dGhpcy5uekZvbnQuZm9udEZhbWlseX1gO1xuICAgIGlmICh0aGlzLm56Rm9udC5jb2xvcikgY3R4LmZpbGxTdHlsZSA9IHRoaXMubnpGb250LmNvbG9yO1xuICAgIGN0eC50ZXh0QWxpZ24gPSAnY2VudGVyJztcbiAgICBjdHgudGV4dEJhc2VsaW5lID0gJ3RvcCc7XG4gICAgY3R4LnRyYW5zbGF0ZShkcmF3V2lkdGggLyAyLCAwKTtcbiAgICBjb25zdCBjb250ZW50cyA9IEFycmF5LmlzQXJyYXkodGhpcy5uekNvbnRlbnQpID8gdGhpcy5uekNvbnRlbnQgOiBbdGhpcy5uekNvbnRlbnRdO1xuICAgIGNvbnRlbnRzPy5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuICAgICAgY3R4LmZpbGxUZXh0KGl0ZW0gPz8gJycsIGRyYXdYLCBkcmF3WSArIGluZGV4ICogKG1lcmdlZEZvbnRTaXplICsgRm9udEdhcCAqIHJhdGlvKSk7XG4gICAgfSk7XG4gIH1cblxuICBkcmF3VGV4dChcbiAgICBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50LFxuICAgIGN0eDogQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELFxuICAgIGRyYXdYOiBudW1iZXIsXG4gICAgZHJhd1k6IG51bWJlcixcbiAgICBkcmF3V2lkdGg6IG51bWJlcixcbiAgICBkcmF3SGVpZ2h0OiBudW1iZXIsXG4gICAgYWx0ZXJuYXRlUm90YXRlWDogbnVtYmVyLFxuICAgIGFsdGVybmF0ZVJvdGF0ZVk6IG51bWJlcixcbiAgICBhbHRlcm5hdGVEcmF3WDogbnVtYmVyLFxuICAgIGFsdGVybmF0ZURyYXdZOiBudW1iZXIsXG4gICAgbWFya1dpZHRoOiBudW1iZXJcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5maWxsVGV4dHMoY3R4LCBkcmF3WCwgZHJhd1ksIGRyYXdXaWR0aCwgZHJhd0hlaWdodCk7XG5cbiAgICAvKiogRmlsbCB0aGUgaW50ZXJsZWF2ZWQgdGV4dCBhZnRlciByb3RhdGlvbiAqL1xuICAgIGN0eC5yZXN0b3JlKCk7XG4gICAgcm90YXRlV2F0ZXJtYXJrKGN0eCwgYWx0ZXJuYXRlUm90YXRlWCwgYWx0ZXJuYXRlUm90YXRlWSwgdGhpcy5uelJvdGF0ZSk7XG4gICAgdGhpcy5maWxsVGV4dHMoY3R4LCBhbHRlcm5hdGVEcmF3WCwgYWx0ZXJuYXRlRHJhd1ksIGRyYXdXaWR0aCwgZHJhd0hlaWdodCk7XG4gICAgdGhpcy5hcHBlbmRXYXRlcm1hcmsoY2FudmFzLnRvRGF0YVVSTCgpLCBtYXJrV2lkdGgpO1xuICB9XG5cbiAgcmVuZGVyV2F0ZXJtYXJrKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5uekNvbnRlbnQgJiYgIXRoaXMubnpJbWFnZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50ID0gdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICBjb25zdCBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKSBhcyBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ7XG5cbiAgICBpZiAoY3R4KSB7XG4gICAgICBpZiAoIXRoaXMud2F0ZXJNYXJrRWxlbWVudCkge1xuICAgICAgICB0aGlzLndhdGVyTWFya0VsZW1lbnQgPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgfVxuICAgICAgdGhpcy5nZXRGb250KCk7XG4gICAgICBjb25zdCByYXRpbyA9IGdldFBpeGVsUmF0aW8oKTtcbiAgICAgIGNvbnN0IFttYXJrV2lkdGgsIG1hcmtIZWlnaHRdID0gdGhpcy5nZXRNYXJrU2l6ZShjdHgpO1xuICAgICAgY29uc3QgY2FudmFzV2lkdGggPSAodGhpcy5uekdhcFswXSArIG1hcmtXaWR0aCkgKiByYXRpbztcbiAgICAgIGNvbnN0IGNhbnZhc0hlaWdodCA9ICh0aGlzLm56R2FwWzFdICsgbWFya0hlaWdodCkgKiByYXRpbztcbiAgICAgIGNhbnZhcy5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgYCR7Y2FudmFzV2lkdGggKiBCYXNlU2l6ZX1weGApO1xuICAgICAgY2FudmFzLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgYCR7Y2FudmFzSGVpZ2h0ICogQmFzZVNpemV9cHhgKTtcblxuICAgICAgY29uc3QgZHJhd1ggPSAodGhpcy5uekdhcFswXSAqIHJhdGlvKSAvIDI7XG4gICAgICBjb25zdCBkcmF3WSA9ICh0aGlzLm56R2FwWzFdICogcmF0aW8pIC8gMjtcbiAgICAgIGNvbnN0IGRyYXdXaWR0aCA9IG1hcmtXaWR0aCAqIHJhdGlvO1xuICAgICAgY29uc3QgZHJhd0hlaWdodCA9IG1hcmtIZWlnaHQgKiByYXRpbztcbiAgICAgIGNvbnN0IHJvdGF0ZVggPSAoZHJhd1dpZHRoICsgdGhpcy5uekdhcFswXSAqIHJhdGlvKSAvIDI7XG4gICAgICBjb25zdCByb3RhdGVZID0gKGRyYXdIZWlnaHQgKyB0aGlzLm56R2FwWzFdICogcmF0aW8pIC8gMjtcblxuICAgICAgLyoqIEFsdGVybmF0ZSBkcmF3aW5nIHBhcmFtZXRlcnMgKi9cbiAgICAgIGNvbnN0IGFsdGVybmF0ZURyYXdYID0gZHJhd1ggKyBjYW52YXNXaWR0aDtcbiAgICAgIGNvbnN0IGFsdGVybmF0ZURyYXdZID0gZHJhd1kgKyBjYW52YXNIZWlnaHQ7XG4gICAgICBjb25zdCBhbHRlcm5hdGVSb3RhdGVYID0gcm90YXRlWCArIGNhbnZhc1dpZHRoO1xuICAgICAgY29uc3QgYWx0ZXJuYXRlUm90YXRlWSA9IHJvdGF0ZVkgKyBjYW52YXNIZWlnaHQ7XG5cbiAgICAgIGN0eC5zYXZlKCk7XG4gICAgICByb3RhdGVXYXRlcm1hcmsoY3R4LCByb3RhdGVYLCByb3RhdGVZLCB0aGlzLm56Um90YXRlKTtcblxuICAgICAgaWYgKHRoaXMubnpJbWFnZSkge1xuICAgICAgICBjb25zdCBpbWcgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgaW1nLm9ubG9hZCA9ICgpID0+IHtcbiAgICAgICAgICBjdHguZHJhd0ltYWdlKGltZywgZHJhd1gsIGRyYXdZLCBkcmF3V2lkdGgsIGRyYXdIZWlnaHQpO1xuXG4gICAgICAgICAgLyoqIERyYXcgaW50ZXJsZWF2ZWQgcGljdHVyZXMgYWZ0ZXIgcm90YXRpb24gKi9cbiAgICAgICAgICBjdHgucmVzdG9yZSgpO1xuICAgICAgICAgIHJvdGF0ZVdhdGVybWFyayhjdHgsIGFsdGVybmF0ZVJvdGF0ZVgsIGFsdGVybmF0ZVJvdGF0ZVksIHRoaXMubnpSb3RhdGUpO1xuICAgICAgICAgIGN0eC5kcmF3SW1hZ2UoaW1nLCBhbHRlcm5hdGVEcmF3WCwgYWx0ZXJuYXRlRHJhd1ksIGRyYXdXaWR0aCwgZHJhd0hlaWdodCk7XG4gICAgICAgICAgdGhpcy5hcHBlbmRXYXRlcm1hcmsoY2FudmFzLnRvRGF0YVVSTCgpLCBtYXJrV2lkdGgpO1xuICAgICAgICB9O1xuICAgICAgICBpbWcub25lcnJvciA9ICgpID0+XG4gICAgICAgICAgdGhpcy5kcmF3VGV4dChcbiAgICAgICAgICAgIGNhbnZhcyxcbiAgICAgICAgICAgIGN0eCxcbiAgICAgICAgICAgIGRyYXdYLFxuICAgICAgICAgICAgZHJhd1ksXG4gICAgICAgICAgICBkcmF3V2lkdGgsXG4gICAgICAgICAgICBkcmF3SGVpZ2h0LFxuICAgICAgICAgICAgYWx0ZXJuYXRlUm90YXRlWCxcbiAgICAgICAgICAgIGFsdGVybmF0ZVJvdGF0ZVksXG4gICAgICAgICAgICBhbHRlcm5hdGVEcmF3WCxcbiAgICAgICAgICAgIGFsdGVybmF0ZURyYXdZLFxuICAgICAgICAgICAgbWFya1dpZHRoXG4gICAgICAgICAgKTtcbiAgICAgICAgaW1nLmNyb3NzT3JpZ2luID0gJ2Fub255bW91cyc7XG4gICAgICAgIGltZy5yZWZlcnJlclBvbGljeSA9ICduby1yZWZlcnJlcic7XG4gICAgICAgIGltZy5zcmMgPSB0aGlzLm56SW1hZ2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmRyYXdUZXh0KFxuICAgICAgICAgIGNhbnZhcyxcbiAgICAgICAgICBjdHgsXG4gICAgICAgICAgZHJhd1gsXG4gICAgICAgICAgZHJhd1ksXG4gICAgICAgICAgZHJhd1dpZHRoLFxuICAgICAgICAgIGRyYXdIZWlnaHQsXG4gICAgICAgICAgYWx0ZXJuYXRlUm90YXRlWCxcbiAgICAgICAgICBhbHRlcm5hdGVSb3RhdGVZLFxuICAgICAgICAgIGFsdGVybmF0ZURyYXdYLFxuICAgICAgICAgIGFsdGVybmF0ZURyYXdZLFxuICAgICAgICAgIG1hcmtXaWR0aFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMub2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICB9XG59XG4iXX0=