ng-devui
Version:
DevUI components based on Angular
255 lines (253 loc) • 32.3 kB
JavaScript
import { THEME_KEY } from './key-config';
import { PrefersColorSchemeMediaQuery } from './media-query';
import { ContextService, EventBus, StorageService } from './utils/index';
const THEME_CHANGE_TIME = 400;
const THEME_CHANGE_DELAY = 100;
/**
* 负责CSS变量主题的装卸,主题元数据转换成主题数据
*/
export class ThemeService {
set appendClasses(classes) {
if (this._appendedClasses) {
this.removeAppendedClass(this._appendedClasses);
}
if (classes) {
this.addAppendClass(classes);
}
this._appendedClasses = classes;
}
get appendClasses() {
return this._appendedClasses;
}
constructor(eventBus, storage, context) {
this.eventBus = eventBus === undefined ? new EventBus() : eventBus;
this.storage = storage === undefined ? new StorageService() : storage;
this.context = context === undefined ? new ContextService() : context;
}
initializeTheme(specificThemeId, allowDynamicTheme) {
const themeId = specificThemeId
|| this.storage.tryGetLocalStorage(THEME_KEY.userLastPreferTheme)
|| this.context.getDataFromNameSpace(THEME_KEY.currentTheme);
let theme;
if (themeId) {
const themes = this.context.getDataFromNameSpace(THEME_KEY.themeCollection);
if (themes && Object.keys(themes).length > 0) {
theme = themes[themeId];
if (!theme) {
const key = Object.keys(themes).find(t => themes[t].id === themeId);
theme = themes[key];
}
}
}
this.currentTheme = theme || {
id: 'empty-theme',
name: '',
data: {},
isDark: false
};
this.createColorTransition();
if (!theme && allowDynamicTheme) {
document.body.setAttribute(THEME_KEY.uiThemeAttributeName, 'empty-theme');
return;
}
this.applyTheme(this.currentTheme);
}
formatCSSVariables(themeData) {
return Object.keys(themeData).map(cssVar => ('--' + cssVar + ':' + themeData[cssVar])).join(';');
}
applyTheme(theme) {
if (typeof window === 'undefined' || typeof document === 'undefined') {
return;
}
if (theme.isDark === this.currentTheme.isDark) {
this.addColorTransition();
this.renderTheme(theme);
// 通知外部主题变更
this.notify(theme, 'themeChanged');
setTimeout(() => { this.removeColorTransition(); }, THEME_CHANGE_TIME + THEME_CHANGE_DELAY);
}
else {
this.themeHidden();
setTimeout(() => {
this.removeColorTransition();
this.renderTheme(theme);
// 通知外部主题变更
this.notify(theme, 'themeChanged');
this.themeShow();
setTimeout(() => { this.removeColorTransition(); }, THEME_CHANGE_TIME + THEME_CHANGE_DELAY);
}, THEME_CHANGE_TIME);
}
}
renderTheme(theme) {
this.currentTheme = theme;
if (!this.contentElement) {
const styleElement = document.getElementById(THEME_KEY.styleElementId);
if (styleElement) {
this.contentElement = styleElement;
}
else {
this.contentElement = document.createElement('style');
this.contentElement.id = THEME_KEY.styleElementId;
document.head.appendChild(this.contentElement);
}
}
this.contentElement.innerText = ':root { ' + this.formatCSSVariables(theme.data) + ' }';
this.contentElement.setAttribute(THEME_KEY.uiThemeAttributeName, this.currentTheme.id);
document.body.setAttribute(THEME_KEY.uiThemeAttributeName, this.currentTheme.id);
// 用于挂载额外变量和类名
this.applyExtraData();
this.saveCustomTheme(this.currentTheme);
}
saveCustomTheme(customTheme) {
this.storage.trySetLocalStorage(THEME_KEY.userLastPreferTheme, customTheme.id);
this.storage.trySetLocalStorage(THEME_KEY.userLastPreferThemeData, JSON.stringify(customTheme.data));
this.context.setDataFromNameSpace(THEME_KEY.currentTheme, customTheme.id);
}
notify(theme, eventType) {
if (!this.eventBus) {
return;
}
this.eventBus.trigger(eventType, theme);
}
setEventBus(eb) {
this.eventBus = eb;
}
addAppendClass(classNames) {
if (typeof document === 'undefined') {
return;
}
document.body.classList.add(...classNames);
}
removeAppendedClass(classNames) {
if (typeof document === 'undefined') {
return;
}
document.body.classList.remove(...classNames);
}
setExtraData(data, apply = false) {
this.extraData = data;
if (apply) {
this.applyExtraData();
}
}
applyExtraData() {
const theme = this.currentTheme;
if (this.extraData && this.extraData[theme.id] && this.extraData[theme.id].cssVariables) {
this.contentElement.innerText
= ':root { ' + this.formatCSSVariables(theme.data) + ' }'
+ ':root { ' + this.formatCSSVariables(this.extraData[theme.id].cssVariables) + ' }';
}
if (this.extraData && this.extraData[theme.id] && this.extraData[theme.id].appendClasses) {
this.appendClasses = this.extraData[theme.id].appendClasses;
}
else {
this.appendClasses = undefined;
}
}
unloadTheme() {
if (typeof document === 'undefined') {
return null;
}
if (this.contentElement && document.contains(this.contentElement)) {
this.contentElement.parentElement.removeChild(this.contentElement);
}
if (this.appendClasses) {
this.appendClasses = undefined;
}
}
registerMediaQuery() {
if (!this.mediaQuery) {
this.mediaQuery = new PrefersColorSchemeMediaQuery();
}
this.mediaQuery.register();
}
unregisterMediaQuery() {
if (!this.mediaQuery) {
return;
}
this.mediaQuery.unregister();
this.mediaQuery = undefined;
}
createColorTransition() {
if (typeof document === 'undefined') {
return;
}
this.colorTransitionElement = document.createElement('style');
this.darkChangeHiddenElement = document.createElement('style');
this.darkChangeShowElement = document.createElement('style');
;
this.colorTransitionElement.id = THEME_KEY.transitionStyleElementId;
this.darkChangeHiddenElement.id = THEME_KEY.transitionStyleElementId;
this.darkChangeShowElement.id = THEME_KEY.transitionStyleElementId;
this.colorTransitionElement.innerText = `
* { transition: background .3s ease-out, background-color .3s ease-out,
border .3s ease-out, border-color .3s ease-out,
box-shadow .3s ease-out, box-shadow-color .3s ease-out}
`;
this.darkChangeHiddenElement.innerText = `
* {
transition: background .3s ease-out, background-color .3s ease-out,
border .3s ease-out, border-color .3s ease-out,
box-shadow .3s ease-out, box-shadow-color .3s ease-out
}
body {
animation-duration: 400ms;
animation-name: hidden;
animation-iteration-count: 1;
}
hidden {
from {
opacity: 1;
}
to {
opacity: 0.1;
}
}
`;
this.darkChangeShowElement.innerText = `
body {
animation-duration: 400ms;
animation-name: show;
animation-iteration-count: 1;
}
show {
from {
opacity: 0.1;
}
to {
opacity: 1;
}
}
`;
}
themeHidden() {
if (typeof document === 'undefined') {
return;
}
document.head.appendChild(this.darkChangeHiddenElement);
}
themeShow() {
if (typeof document === 'undefined') {
return;
}
document.head.appendChild(this.darkChangeShowElement);
}
addColorTransition() {
if (typeof document === 'undefined') {
return;
}
document.head.appendChild(this.colorTransitionElement);
}
removeColorTransition() {
if (this.colorTransitionElement.parentElement) {
this.colorTransitionElement.parentElement.removeChild(this.colorTransitionElement);
}
if (this.darkChangeShowElement.parentElement) {
this.darkChangeShowElement.parentElement.removeChild(this.darkChangeShowElement);
}
if (this.darkChangeHiddenElement.parentElement) {
this.darkChangeHiddenElement.parentElement.removeChild(this.darkChangeHiddenElement);
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhlbWUtc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2RldnVpL3RoZW1lL3RoZW1lLXNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN6QyxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFN0QsT0FBTyxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQStDLGNBQWMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV0SCxNQUFNLGlCQUFpQixHQUFHLEdBQUcsQ0FBQztBQUM5QixNQUFNLGtCQUFrQixHQUFHLEdBQUcsQ0FBQztBQUUvQjs7R0FFRztBQUNILE1BQU0sT0FBTyxZQUFZO0lBa0J2QixJQUFJLGFBQWEsQ0FBQyxPQUFzQjtRQUN0QyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUNsRCxDQUFDO1FBQ0QsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNaLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDL0IsQ0FBQztRQUNELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxPQUFPLENBQUM7SUFDbEMsQ0FBQztJQUVELElBQUksYUFBYTtRQUNmLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDO0lBQy9CLENBQUM7SUFJRCxZQUFZLFFBQW9CLEVBQUUsT0FBeUIsRUFBRSxPQUF5QjtRQUNwRixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztRQUNuRSxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksY0FBYyxFQUFFLENBQUMsQ0FB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QyxDQUFDO0lBQ3hELENBQUM7SUFFTyxrQkFBa0I7UUFDeEIsSUFBSSxPQUFPLFFBQVEsS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUNwQyxPQUFPO1FBQ1QsQ0FBQztRQUNELFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFDTyxxQkFBcUI7UUFDM0IsSUFBSSxJQUFJLENBQUMsc0JBQXNCLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDOUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDckYsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLHFCQUFxQixDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzdDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQ25GLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUMvQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUN2RixDQUFDO0lBRUgsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVEhFTUVfS0VZIH0gZnJvbSAnLi9rZXktY29uZmlnJztcbmltcG9ydCB7IFByZWZlcnNDb2xvclNjaGVtZU1lZGlhUXVlcnkgfSBmcm9tICcuL21lZGlhLXF1ZXJ5JztcbmltcG9ydCB7IFRoZW1lIH0gZnJvbSAnLi90aGVtZSc7XG5pbXBvcnQgeyBDb250ZXh0U2VydmljZSwgRXZlbnRCdXMsIElDb250ZXh0U2VydmljZSwgSUV2ZW50QnVzLCBJU3RvcmFnZVNlcnZpY2UsIFN0b3JhZ2VTZXJ2aWNlIH0gZnJvbSAnLi91dGlscy9pbmRleCc7XG5cbmNvbnN0IFRIRU1FX0NIQU5HRV9USU1FID0gNDAwO1xuY29uc3QgVEhFTUVfQ0hBTkdFX0RFTEFZID0gMTAwO1xuXG4vKipcbiAqIOi0n+i0o0NTU+WPmOmHj+S4u+mimOeahOijheWNuO+8jOS4u+mimOWFg+aVsOaNrui9rOaNouaIkOS4u+mimOaVsOaNrlxuICovXG5leHBvcnQgY2xhc3MgVGhlbWVTZXJ2aWNlIHtcbiAgZXZlbnRCdXM6IElFdmVudEJ1cztcbiAgc3RvcmFnZTogSVN0b3JhZ2VTZXJ2aWNlO1xuICBjb250ZXh0OiBJQ29udGV4dFNlcnZpY2U7XG4gIGN1cnJlbnRUaGVtZTogVGhlbWU7XG4gIGNvbnRlbnRFbGVtZW50OiBIVE1MU3R5bGVFbGVtZW50O1xuICBjb2xvclRyYW5zaXRpb25FbGVtZW50OiBIVE1MU3R5bGVFbGVtZW50O1xuICBkYXJrQ2hhbmdlSGlkZGVuRWxlbWVudDogSFRNTFN0eWxlRWxlbWVudDtcbiAgZGFya0NoYW5nZVNob3dFbGVtZW50OiBIVE1MU3R5bGVFbGVtZW50O1xuICBleHRyYURhdGE6IHtcbiAgICBbdGhlbWVJZDogc3RyaW5nXToge1xuICAgICAgY3NzVmFyaWFibGVzPzoge1xuICAgICAgICBbdmFybmFtZTogc3RyaW5nXTogc3RyaW5nO1xuICAgICAgfTtcbiAgICAgIGFwcGVuZENsYXNzZXM/OiBBcnJheTxzdHJpbmc+O1xuICAgIH07XG4gIH07XG4gIHByaXZhdGUgX2FwcGVuZGVkQ2xhc3NlczogQXJyYXk8c3RyaW5nPjtcbiAgc2V0IGFwcGVuZENsYXNzZXMoY2xhc3NlczogQXJyYXk8c3RyaW5nPikge1xuICAgIGlmICh0aGlzLl9hcHBlbmRlZENsYXNzZXMpIHtcbiAgICAgIHRoaXMucmVtb3ZlQXBwZW5kZWRDbGFzcyh0aGlzLl9hcHBlbmRlZENsYXNzZXMpO1xuICAgIH1cbiAgICBpZiAoY2xhc3Nlcykge1xuICAgICAgdGhpcy5hZGRBcHBlbmRDbGFzcyhjbGFzc2VzKTtcbiAgICB9XG4gICAgdGhpcy5fYXBwZW5kZWRDbGFzc2VzID0gY2xhc3NlcztcbiAgfVxuXG4gIGdldCBhcHBlbmRDbGFzc2VzKCkge1xuICAgIHJldHVybiB0aGlzLl9hcHBlbmRlZENsYXNzZXM7XG4gIH1cblxuICBwdWJsaWMgbWVkaWFRdWVyeTogUHJlZmVyc0NvbG9yU2NoZW1lTWVkaWFRdWVyeTtcblxuICBjb25zdHJ1Y3RvcihldmVudEJ1cz86IElFdmVudEJ1cywgc3RvcmFnZT86IElTdG9yYWdlU2VydmljZSwgY29udGV4dD86IElDb250ZXh0U2VydmljZSkge1xuICAgIHRoaXMuZXZlbnRCdXMgPSBldmVudEJ1cyA9PT0gdW5kZWZpbmVkID8gbmV3IEV2ZW50QnVzKCkgOiBldmVudEJ1cztcbiAgICB0aGlzLnN0b3JhZ2UgPSBzdG9yYWdlID09PSB1bmRlZmluZWQgPyBuZXcgU3RvcmFnZVNlcnZpY2UoKSA6IHN0b3JhZ2U7XG4gICAgdGhpcy5jb250ZXh0ID0gY29udGV4dCA9PT0gdW5kZWZpbmVkID8gbmV3IENvbnRleHRTZXJ2aWNlKCkgOiBjb250ZXh0O1xuICB9XG5cbiAgaW5pdGlhbGl6ZVRoZW1lKHNwZWNpZmljVGhlbWVJZD86IHN0cmluZywgYWxsb3dEeW5hbWljVGhlbWU/OiBib29sZWFuKSB7XG4gICAgY29uc3QgdGhlbWVJZCA9IHNwZWNpZmljVGhlbWVJZFxuICAgICAgICAgICAgICAgIHx8IHRoaXMuc3RvcmFnZS50cnlHZXRMb2NhbFN0b3JhZ2UoVEhFTUVfS0VZLnVzZXJMYXN0UHJlZmVyVGhlbWUpXG4gICAgICAgICAgICAgICAgfHwgdGhpcy5jb250ZXh0LmdldERhdGFGcm9tTmFtZVNwYWNlKFRIRU1FX0tFWS5jdXJyZW50VGhlbWUpO1xuICAgIGxldCB0aGVtZTtcblxuICAgIGlmICh0aGVtZUlkKSB7XG4gICAgICBjb25zdCB0aGVtZXMgPSB0aGlzLmNvbnRleHQuZ2V0RGF0YUZyb21OYW1lU3BhY2UoVEhFTUVfS0VZLnRoZW1lQ29sbGVjdGlvbik7XG4gICAgICBpZiAodGhlbWVzICYmIE9iamVjdC5rZXlzKHRoZW1lcykubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGVtZSA9IHRoZW1lc1t0aGVtZUlkXTtcbiAgICAgICAgaWYgKCF0aGVtZSkge1xuICAgICAgICAgIGNvbnN0IGtleSA9IE9iamVjdC5rZXlzKHRoZW1lcykuZmluZCh0ID0+IHRoZW1lc1t0XS5pZCA9PT0gdGhlbWVJZCk7XG4gICAgICAgICAgdGhlbWUgPSB0aGVtZXNba2V5XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmN1cnJlbnRUaGVtZSA9IHRoZW1lIHx8IHtcbiAgICAgIGlkOiAnZW1wdHktdGhlbWUnLFxuICAgICAgbmFtZTogJycsXG4gICAgICBkYXRhOiB7fSxcbiAgICAgIGlzRGFyazogZmFsc2VcbiAgICB9O1xuICAgIHRoaXMuY3JlYXRlQ29sb3JUcmFuc2l0aW9uKCk7XG4gICAgaWYgKCF0aGVtZSAmJiBhbGxvd0R5bmFtaWNUaGVtZSkge1xuICAgICAgZG9jdW1lbnQuYm9keS5zZXRBdHRyaWJ1dGUoVEhFTUVfS0VZLnVpVGhlbWVBdHRyaWJ1dGVOYW1lLCAnZW1wdHktdGhlbWUnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5hcHBseVRoZW1lKHRoaXMuY3VycmVudFRoZW1lKTtcbiAgfVxuXG4gIGZvcm1hdENTU1ZhcmlhYmxlcyh0aGVtZURhdGE6IFRoZW1lWydkYXRhJ10pIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhlbWVEYXRhKS5tYXAoXG4gICAgICBjc3NWYXIgPT4gKCctLScgKyBjc3NWYXIgKyAnOicgKyB0aGVtZURhdGFbY3NzVmFyXSlcbiAgICApLmpvaW4oJzsnKTtcbiAgfVxuXG4gIGFwcGx5VGhlbWUodGhlbWU6IFRoZW1lKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnIHx8IHR5cGVvZiBkb2N1bWVudCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoZW1lLmlzRGFyayA9PT0gdGhpcy5jdXJyZW50VGhlbWUuaXNEYXJrKSB7XG4gICAgICB0aGlzLmFkZENvbG9yVHJhbnNpdGlvbigpO1xuICAgICAgdGhpcy5yZW5kZXJUaGVtZSh0aGVtZSk7XG4gICAgICAvLyDpgJrnn6XlpJbpg6jkuLvpopjlj5jmm7RcbiAgICAgIHRoaXMubm90aWZ5KHRoZW1lLCAndGhlbWVDaGFuZ2VkJyk7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHt0aGlzLnJlbW92ZUNvbG9yVHJhbnNpdGlvbigpOyB9LCBUSEVNRV9DSEFOR0VfVElNRSArIFRIRU1FX0NIQU5HRV9ERUxBWSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGhlbWVIaWRkZW4oKTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLnJlbW92ZUNvbG9yVHJhbnNpdGlvbigpO1xuICAgICAgICB0aGlzLnJlbmRlclRoZW1lKHRoZW1lKTtcblxuICAgICAgICAvLyDpgJrnn6XlpJbpg6jkuLvpopjlj5jmm7RcbiAgICAgICAgdGhpcy5ub3RpZnkodGhlbWUsICd0aGVtZUNoYW5nZWQnKTtcbiAgICAgICAgdGhpcy50aGVtZVNob3coKTtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7dGhpcy5yZW1vdmVDb2xvclRyYW5zaXRpb24oKTsgfSwgVEhFTUVfQ0hBTkdFX1RJTUUgKyBUSEVNRV9DSEFOR0VfREVMQVkpO1xuICAgICAgfSwgVEhFTUVfQ0hBTkdFX1RJTUUpO1xuICAgIH1cblxuICB9XG5cbiAgcmVuZGVyVGhlbWUodGhlbWU6IFRoZW1lKSB7XG4gICAgdGhpcy5jdXJyZW50VGhlbWUgPSB0aGVtZTtcbiAgICBpZiAoIXRoaXMuY29udGVudEVsZW1lbnQpIHtcbiAgICAgIGNvbnN0IHN0eWxlRWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFRIRU1FX0tFWS5zdHlsZUVsZW1lbnRJZCk7XG4gICAgICBpZiAoc3R5bGVFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuY29udGVudEVsZW1lbnQgPSA8SFRNTFN0eWxlRWxlbWVudD5zdHlsZUVsZW1lbnQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNvbnRlbnRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgICAgICAgdGhpcy5jb250ZW50RWxlbWVudC5pZCA9IFRIRU1FX0tFWS5zdHlsZUVsZW1lbnRJZDtcbiAgICAgICAgZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZCh0aGlzLmNvbnRlbnRFbGVtZW50KTtcbiAgICAgIH1cblxuICAgIH1cbiAgICB0aGlzLmNvbnRlbnRFbGVtZW50LmlubmVyVGV4dCA9ICc6cm9vdCB7ICcgKyB0aGlzLmZvcm1hdENTU1ZhcmlhYmxlcyh0aGVtZS5kYXRhKSArICcgfSc7XG4gICAgdGhpcy5jb250ZW50RWxlbWVudC5zZXRBdHRyaWJ1dGUoVEhFTUVfS0VZLnVpVGhlbWVBdHRyaWJ1dGVOYW1lLCB0aGlzLmN1cnJlbnRUaGVtZS5pZCk7XG4gICAgZG9jdW1lbnQuYm9keS5zZXRBdHRyaWJ1dGUoVEhFTUVfS0VZLnVpVGhlbWVBdHRyaWJ1dGVOYW1lLCB0aGlzLmN1cnJlbnRUaGVtZS5pZCk7XG5cbiAgICAvLyDnlKjkuo7mjILovb3pop3lpJblj5jph4/lkoznsbvlkI1cbiAgICB0aGlzLmFwcGx5RXh0cmFEYXRhKCk7XG4gICAgdGhpcy5zYXZlQ3VzdG9tVGhlbWUodGhpcy5jdXJyZW50VGhlbWUpO1xuICB9XG5cbiAgc2F2ZUN1c3RvbVRoZW1lKGN1c3RvbVRoZW1lOiBUaGVtZSkge1xuICAgIHRoaXMuc3RvcmFnZS50cnlTZXRMb2NhbFN0b3JhZ2UoVEhFTUVfS0VZLnVzZXJMYXN0UHJlZmVyVGhlbWUsIGN1c3RvbVRoZW1lLmlkKTtcbiAgICB0aGlzLnN0b3JhZ2UudHJ5U2V0TG9jYWxTdG9yYWdlKFRIRU1FX0tFWS51c2VyTGFzdFByZWZlclRoZW1lRGF0YSwgSlNPTi5zdHJpbmdpZnkoY3VzdG9tVGhlbWUuZGF0YSkpO1xuICAgIHRoaXMuY29udGV4dC5zZXREYXRhRnJvbU5hbWVTcGFjZShUSEVNRV9LRVkuY3VycmVudFRoZW1lLCBjdXN0b21UaGVtZS5pZCk7XG4gIH1cblxuICBwcml2YXRlIG5vdGlmeSh0aGVtZTogVGhlbWUsIGV2ZW50VHlwZTogc3RyaW5nKSB7XG4gICAgaWYgKCF0aGlzLmV2ZW50QnVzKSB7IHJldHVybjsgfVxuICAgIHRoaXMuZXZlbnRCdXMudHJpZ2dlcihldmVudFR5cGUsIHRoZW1lKTtcbiAgfVxuXG4gIHNldEV2ZW50QnVzKGViOiBJRXZlbnRCdXMpIHtcbiAgICB0aGlzLmV2ZW50QnVzID0gZWI7XG4gIH1cblxuICBwcml2YXRlIGFkZEFwcGVuZENsYXNzKGNsYXNzTmFtZXM6IEFycmF5PHN0cmluZz4pIHtcbiAgICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoLi4uY2xhc3NOYW1lcyk7XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZUFwcGVuZGVkQ2xhc3MoY2xhc3NOYW1lczogQXJyYXk8c3RyaW5nPikge1xuICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSguLi5jbGFzc05hbWVzKTtcbiAgfVxuXG4gIHNldEV4dHJhRGF0YShkYXRhLCBhcHBseSA9IGZhbHNlKSB7XG4gICAgdGhpcy5leHRyYURhdGEgPSBkYXRhO1xuICAgIGlmIChhcHBseSkge1xuICAgICAgdGhpcy5hcHBseUV4dHJhRGF0YSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXBwbHlFeHRyYURhdGEoKSB7XG4gICAgY29uc3QgdGhlbWUgPSB0aGlzLmN1cnJlbnRUaGVtZTtcbiAgICBpZiAodGhpcy5leHRyYURhdGEgJiYgdGhpcy5leHRyYURhdGFbdGhlbWUuaWRdICYmIHRoaXMuZXh0cmFEYXRhW3RoZW1lLmlkXS5jc3NWYXJpYWJsZXMpIHtcbiAgICAgIHRoaXMuY29udGVudEVsZW1lbnQuaW5uZXJUZXh0XG4gICAgICA9ICc6cm9vdCB7ICcgKyB0aGlzLmZvcm1hdENTU1ZhcmlhYmxlcyh0aGVtZS5kYXRhKSArICcgfSdcbiAgICAgICsgJzpyb290IHsgJyArIHRoaXMuZm9ybWF0Q1NTVmFyaWFibGVzKHRoaXMuZXh0cmFEYXRhW3RoZW1lLmlkXS5jc3NWYXJpYWJsZXMpICsgJyB9JztcbiAgICB9XG4gICAgaWYgKHRoaXMuZXh0cmFEYXRhICYmIHRoaXMuZXh0cmFEYXRhW3RoZW1lLmlkXSAmJiB0aGlzLmV4dHJhRGF0YVt0aGVtZS5pZF0uYXBwZW5kQ2xhc3Nlcykge1xuICAgICAgdGhpcy5hcHBlbmRDbGFzc2VzID0gdGhpcy5leHRyYURhdGFbdGhlbWUuaWRdLmFwcGVuZENsYXNzZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXBwZW5kQ2xhc3NlcyA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgdW5sb2FkVGhlbWUoKSB7XG4gICAgaWYgKHR5cGVvZiBkb2N1bWVudCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAodGhpcy5jb250ZW50RWxlbWVudCAmJiBkb2N1bWVudC5jb250YWlucyh0aGlzLmNvbnRlbnRFbGVtZW50KSkge1xuICAgICAgdGhpcy5jb250ZW50RWxlbWVudC5wYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKHRoaXMuY29udGVudEVsZW1lbnQpO1xuICAgIH1cbiAgICBpZiAodGhpcy5hcHBlbmRDbGFzc2VzKSB7XG4gICAgICB0aGlzLmFwcGVuZENsYXNzZXMgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVyTWVkaWFRdWVyeSgpIHtcbiAgICBpZiAoIXRoaXMubWVkaWFRdWVyeSkge1xuICAgICAgdGhpcy5tZWRpYVF1ZXJ5ID0gbmV3IFByZWZlcnNDb2xvclNjaGVtZU1lZGlhUXVlcnkoKTtcbiAgICB9XG4gICAgdGhpcy5tZWRpYVF1ZXJ5LnJlZ2lzdGVyKCk7XG4gIH1cblxuICBwdWJsaWMgdW5yZWdpc3Rlck1lZGlhUXVlcnkoKSB7XG4gICAgaWYgKCF0aGlzLm1lZGlhUXVlcnkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5tZWRpYVF1ZXJ5LnVucmVnaXN0ZXIoKTtcbiAgICB0aGlzLm1lZGlhUXVlcnkgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUNvbG9yVHJhbnNpdGlvbigpIHtcbiAgICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNvbG9yVHJhbnNpdGlvbkVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuICAgIHRoaXMuZGFya0NoYW5nZUhpZGRlbkVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuICAgIHRoaXMuZGFya0NoYW5nZVNob3dFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTs7XG4gICAgdGhpcy5jb2xvclRyYW5zaXRpb25FbGVtZW50LmlkID0gVEhFTUVfS0VZLnRyYW5zaXRpb25TdHlsZUVsZW1lbnRJZDtcbiAgICB0aGlzLmRhcmtDaGFuZ2VIaWRkZW5FbGVtZW50LmlkID0gVEhFTUVfS0VZLnRyYW5zaXRpb25TdHlsZUVsZW1lbnRJZDtcbiAgICB0aGlzLmRhcmtDaGFuZ2VTaG93RWxlbWVudC5pZCA9IFRIRU1FX0tFWS50cmFuc2l0aW9uU3R5bGVFbGVtZW50SWQ7XG4gICAgdGhpcy5jb2xvclRyYW5zaXRpb25FbGVtZW50LmlubmVyVGV4dCA9IGBcbiAgICAgICogeyB0cmFuc2l0aW9uOiBiYWNrZ3JvdW5kIC4zcyBlYXNlLW91dCwgYmFja2dyb3VuZC1jb2xvciAuM3MgZWFzZS1vdXQsXG4gICAgICAgICAgICAgICAgICAgIGJvcmRlciAuM3MgZWFzZS1vdXQsIGJvcmRlci1jb2xvciAuM3MgZWFzZS1vdXQsXG4gICAgICAgICAgICAgICAgICAgIGJveC1zaGFkb3cgLjNzIGVhc2Utb3V0LCBib3gtc2hhZG93LWNvbG9yIC4zcyBlYXNlLW91dH1cbiAgICBgO1xuXG4gICAgdGhpcy5kYXJrQ2hhbmdlSGlkZGVuRWxlbWVudC5pbm5lclRleHQgPSBgXG4gICAgICAqIHtcbiAgICAgICAgdHJhbnNpdGlvbjogYmFja2dyb3VuZCAuM3MgZWFzZS1vdXQsIGJhY2tncm91bmQtY29sb3IgLjNzIGVhc2Utb3V0LFxuICAgICAgICBib3JkZXIgLjNzIGVhc2Utb3V0LCBib3JkZXItY29sb3IgLjNzIGVhc2Utb3V0LFxuICAgICAgICBib3gtc2hhZG93IC4zcyBlYXNlLW91dCwgYm94LXNoYWRvdy1jb2xvciAuM3MgZWFzZS1vdXRcbiAgICAgIH1cbiAgICAgIGJvZHkge1xuICAgICAgICBhbmltYXRpb24tZHVyYXRpb246IDQwMG1zO1xuICAgICAgICBhbmltYXRpb24tbmFtZTogaGlkZGVuO1xuICAgICAgICBhbmltYXRpb24taXRlcmF0aW9uLWNvdW50OiAxO1xuICAgICAgfVxuICAgICAgQGtleWZyYW1lcyBoaWRkZW4ge1xuICAgICAgICBmcm9tIHtcbiAgICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICB9XG4gICAgICBcbiAgICAgICAgdG8ge1xuICAgICAgICAgIG9wYWNpdHk6IDAuMTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIGA7XG5cbiAgICB0aGlzLmRhcmtDaGFuZ2VTaG93RWxlbWVudC5pbm5lclRleHQgPSBgXG4gICAgICBib2R5IHtcbiAgICAgICAgYW5pbWF0aW9uLWR1cmF0aW9uOiA0MDBtcztcbiAgICAgICAgYW5pbWF0aW9uLW5hbWU6IHNob3c7XG4gICAgICAgIGFuaW1hdGlvbi1pdGVyYXRpb24tY291bnQ6IDE7XG4gICAgICB9XG4gICAgICBAa2V5ZnJhbWVzIHNob3cge1xuICAgICAgICBmcm9tIHtcbiAgICAgICAgICBvcGFjaXR5OiAwLjE7XG4gICAgICAgIH1cbiAgICAgIFxuICAgICAgICB0byB7XG4gICAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIGA7XG4gIH1cblxuICBwcml2YXRlIHRoZW1lSGlkZGVuKCkge1xuICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQodGhpcy5kYXJrQ2hhbmdlSGlkZGVuRWxlbWVudCk7XG4gIH1cblxuICBwcml2YXRlIHRoZW1lU2hvdygpIHtcbiAgICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHRoaXMuZGFya0NoYW5nZVNob3dFbGVtZW50KTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkQ29sb3JUcmFuc2l0aW9uKCkge1xuICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQodGhpcy5jb2xvclRyYW5zaXRpb25FbGVtZW50KTtcbiAgfVxuICBwcml2YXRlIHJlbW92ZUNvbG9yVHJhbnNpdGlvbigpIHtcbiAgICBpZiAodGhpcy5jb2xvclRyYW5zaXRpb25FbGVtZW50LnBhcmVudEVsZW1lbnQpIHtcbiAgICAgIHRoaXMuY29sb3JUcmFuc2l0aW9uRWxlbWVudC5wYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKHRoaXMuY29sb3JUcmFuc2l0aW9uRWxlbWVudCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZGFya0NoYW5nZVNob3dFbGVtZW50LnBhcmVudEVsZW1lbnQpIHtcbiAgICAgIHRoaXMuZGFya0NoYW5nZVNob3dFbGVtZW50LnBhcmVudEVsZW1lbnQucmVtb3ZlQ2hpbGQodGhpcy5kYXJrQ2hhbmdlU2hvd0VsZW1lbnQpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmRhcmtDaGFuZ2VIaWRkZW5FbGVtZW50LnBhcmVudEVsZW1lbnQpIHtcbiAgICAgIHRoaXMuZGFya0NoYW5nZUhpZGRlbkVsZW1lbnQucGFyZW50RWxlbWVudC5yZW1vdmVDaGlsZCh0aGlzLmRhcmtDaGFuZ2VIaWRkZW5FbGVtZW50KTtcbiAgICB9XG5cbiAgfVxufVxuIl19