231 lines
37 KiB
Plaintext
231 lines
37 KiB
Plaintext
import { has, intersection, isNumber, isObjectLike } from "/_nuxt/node_modules/.cache/vite/client/deps/lodash-es.js?v=e4f18c29";
|
|
import { UnformattableSerializedViewerStateError } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/viewer/errors/index.js";
|
|
import { coerceUndefinedValuesToNull } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/core/index.js";
|
|
export const defaultViewModeEdgeColorValue = 'DEFAULT_EDGE_COLOR';
|
|
/** Redefining these is unfortunate. Especially since they are not part of viewer-core */
|
|
export var MeasurementType;
|
|
(function (MeasurementType) {
|
|
MeasurementType[MeasurementType["PERPENDICULAR"] = 0] = "PERPENDICULAR";
|
|
MeasurementType[MeasurementType["POINTTOPOINT"] = 1] = "POINTTOPOINT";
|
|
MeasurementType[MeasurementType["AREA"] = 2] = "AREA";
|
|
MeasurementType[MeasurementType["POINT"] = 3] = "POINT";
|
|
})(MeasurementType || (MeasurementType = {}));
|
|
export const defaultMeasurementOptions = Object.freeze({
|
|
visible: true,
|
|
type: MeasurementType.POINTTOPOINT,
|
|
vertexSnap: false,
|
|
units: 'm',
|
|
precision: 2
|
|
});
|
|
/**
|
|
* v1 -> v1.1
|
|
* - ui.filters.propertyFilter.isApplied field added
|
|
* - ui.spotlightUserId swapped for spotlightUserSessionId
|
|
* v1.1 -> v1.2
|
|
* - ui.diff added
|
|
* v1.2 -> v1.3
|
|
* - ui.filters.selectedObjectIds removed in favor of ui.filters.selectedObjectApplicationIds
|
|
* v1.3 -> 1.4
|
|
* - ui.viewMode -> ui.viewMode.mode
|
|
* - ui.viewMode has new keys: edgesEnabled, edgesWeight, outlineOpacity, edgesColor
|
|
* v1.4 -> 1.5
|
|
* - ui.measurement.measurements added
|
|
* v1.5 -> 1.6
|
|
* - ui.filters.propertyFilter -> propertyFilters
|
|
* - activeColorFilterId added
|
|
* v1.6 -> 1.7
|
|
* - ui.filters.filterLogic added
|
|
* - ui.filters.propertyFilters.condition updated
|
|
* v1.7 -> 1.8
|
|
* - ui.filters.propertyFilters.numericRange added
|
|
*/
|
|
export const SERIALIZED_VIEWER_STATE_VERSION = 1.8;
|
|
/**
|
|
* Note: This only does superficial validation. To really ensure that all of the keys are there, even if prefilled with default values, make sure you invoke
|
|
* formatSerializedViewerState() on the state afterwards
|
|
*/
|
|
export const isSerializedViewerState = (val) => {
|
|
if (!val)
|
|
return false;
|
|
const keys = [
|
|
'projectId',
|
|
'sessionId',
|
|
'resources',
|
|
'ui',
|
|
'viewer'
|
|
];
|
|
if (!isObjectLike(val))
|
|
return false;
|
|
const valKeys = Object.keys(val);
|
|
if (intersection(valKeys, keys).length !== keys.length)
|
|
return false;
|
|
return true;
|
|
};
|
|
const initializeMissingData = (state) => {
|
|
const throwInvalidError = (missingPath) => {
|
|
throw new UnformattableSerializedViewerStateError('Required data missing from SerializedViewerState: ' + missingPath);
|
|
};
|
|
const measurementOptions = {
|
|
...defaultMeasurementOptions,
|
|
...state.ui?.measurement?.options
|
|
};
|
|
const selectedObjectApplicationIds = {
|
|
// Parse legacy object ids array as object
|
|
...(state.ui?.filters?.selectedObjectIds?.reduce((ret, id) => {
|
|
ret[id] = null;
|
|
return ret;
|
|
}, {}) ?? {}),
|
|
// Sanitize incoming object
|
|
...coerceUndefinedValuesToNull(state.ui?.filters?.selectedObjectApplicationIds || {})
|
|
};
|
|
const viewModeType = isNumber(state.ui?.viewMode)
|
|
? state.ui.viewMode
|
|
: state.ui?.viewMode?.mode;
|
|
const viewModeSettings = isNumber(state.ui?.viewMode) ? {} : state.ui?.viewMode;
|
|
return {
|
|
projectId: state.projectId || throwInvalidError('projectId'),
|
|
sessionId: state.sessionId || `nullSessionId-${Math.random() * 1000}`,
|
|
viewer: {
|
|
...(state.viewer || {}),
|
|
metadata: {
|
|
...(state.viewer?.metadata || {}),
|
|
filteringState: state.viewer?.metadata?.filteringState || null
|
|
}
|
|
},
|
|
resources: {
|
|
...(state.resources || {}),
|
|
request: {
|
|
...(state.resources?.request || {}),
|
|
resourceIdString: state.resources?.request?.resourceIdString ||
|
|
throwInvalidError('resources.request.resourceIdString'),
|
|
threadFilters: {
|
|
...(state.resources?.request?.threadFilters || {}),
|
|
includeArchived: state.resources?.request?.threadFilters?.includeArchived || false,
|
|
loadedVersionsOnly: state.resources?.request?.threadFilters?.loadedVersionsOnly || false
|
|
}
|
|
}
|
|
},
|
|
ui: {
|
|
...(state.ui || {}),
|
|
threads: {
|
|
...(state.ui?.threads || {}),
|
|
openThread: {
|
|
...(state.ui?.threads?.openThread || {}),
|
|
threadId: state.ui?.threads?.openThread?.threadId || null,
|
|
isTyping: state.ui?.threads?.openThread?.isTyping || false,
|
|
newThreadEditor: state.ui?.threads?.openThread?.newThreadEditor || false
|
|
}
|
|
},
|
|
diff: {
|
|
...(state.ui?.diff || {}),
|
|
command: state.ui?.diff?.command || null,
|
|
time: state.ui?.diff?.time || 0.5,
|
|
mode: state.ui?.diff?.mode || 1
|
|
},
|
|
spotlightUserSessionId: state.ui?.spotlightUserSessionId || null,
|
|
filters: (() => {
|
|
const baseFilters = {
|
|
...(state.ui?.filters || {}),
|
|
isolatedObjectIds: state.ui?.filters?.isolatedObjectIds || [],
|
|
hiddenObjectIds: state.ui?.filters?.hiddenObjectIds || [],
|
|
selectedObjectApplicationIds,
|
|
activeColorFilterId: state.ui?.filters?.activeColorFilterId || null
|
|
};
|
|
// Migration logic: handle legacy propertyFilter and new propertyFilters
|
|
let propertyFilters = [];
|
|
// If new propertyFilters exist and are not empty, use them
|
|
if (state.ui?.filters?.propertyFilters &&
|
|
Array.isArray(state.ui.filters.propertyFilters) &&
|
|
state.ui.filters.propertyFilters.length > 0) {
|
|
// Map legacy condition values to new format
|
|
propertyFilters = state.ui.filters.propertyFilters.map((filter) => ({
|
|
...filter,
|
|
condition: filter.condition === 'AND'
|
|
? 'is'
|
|
: filter.condition === 'OR'
|
|
? 'is'
|
|
: filter.condition
|
|
}));
|
|
}
|
|
// If legacy propertyFilter exists but no propertyFilters (or empty propertyFilters), migrate it
|
|
else if (state.ui?.filters?.propertyFilter?.key) {
|
|
propertyFilters = [
|
|
{
|
|
key: state.ui.filters.propertyFilter.key,
|
|
isApplied: state.ui.filters.propertyFilter.isApplied || false,
|
|
selectedValues: [], // Legacy didn't have selectedValues
|
|
id: 'legacy-filter', // Generate a consistent ID for legacy filter
|
|
condition: 'is'
|
|
}
|
|
];
|
|
}
|
|
return {
|
|
...baseFilters,
|
|
propertyFilters,
|
|
filterLogic: state.ui?.filters?.filterLogic || 'all'
|
|
};
|
|
})(),
|
|
camera: {
|
|
...(state.ui?.camera || {}),
|
|
position: state.ui?.camera?.position || throwInvalidError('ui.camera.position'),
|
|
target: state.ui?.camera?.target || throwInvalidError('ui.camera.target'),
|
|
isOrthoProjection: state.ui?.camera?.isOrthoProjection || false,
|
|
zoom: state.ui?.camera?.zoom || 1
|
|
},
|
|
viewMode: {
|
|
mode: viewModeType ?? 0,
|
|
edgesEnabled: viewModeSettings?.edgesEnabled ?? false,
|
|
edgesWeight: viewModeSettings?.edgesWeight ?? 1,
|
|
outlineOpacity: viewModeSettings?.outlineOpacity ?? 0.75,
|
|
edgesColor: viewModeSettings?.edgesColor ?? defaultViewModeEdgeColorValue
|
|
},
|
|
sectionBox: state.ui?.sectionBox?.min?.length && state.ui?.sectionBox.max?.length
|
|
? // Complains otherwise
|
|
state.ui.sectionBox
|
|
: null,
|
|
lightConfig: {
|
|
...(state.ui?.lightConfig || {}),
|
|
intensity: state.ui?.lightConfig?.intensity,
|
|
indirectLightIntensity: state.ui?.lightConfig?.indirectLightIntensity,
|
|
elevation: state.ui?.lightConfig?.elevation,
|
|
azimuth: state.ui?.lightConfig?.azimuth
|
|
},
|
|
explodeFactor: state.ui?.explodeFactor || 0,
|
|
selection: state.ui?.selection || null,
|
|
measurement: {
|
|
enabled: state.ui?.measurement?.enabled ?? false,
|
|
options: measurementOptions,
|
|
measurements: state.ui?.measurement?.measurements || []
|
|
}
|
|
}
|
|
};
|
|
};
|
|
/**
|
|
* Formats SerializedViewerState by bringing it up to date with the structure of the latest version
|
|
* and ensuring missing keys are initialized with default values
|
|
*/
|
|
export const formatSerializedViewerState = (state) => {
|
|
const finalState = initializeMissingData(state);
|
|
return finalState;
|
|
};
|
|
export const inputToVersionedState = (inputSerializedViewerState) => {
|
|
const state = isSerializedViewerState(inputSerializedViewerState)
|
|
? formatSerializedViewerState(inputSerializedViewerState)
|
|
: null;
|
|
if (!state)
|
|
return null;
|
|
return {
|
|
version: SERIALIZED_VIEWER_STATE_VERSION,
|
|
state
|
|
};
|
|
};
|
|
export const isVersionedSerializedViewerState = (data) => {
|
|
if (!data || !isObjectLike(data))
|
|
return false;
|
|
if (!has(data, 'version'))
|
|
return false;
|
|
const stateRaw = data.state;
|
|
return isSerializedViewerState(stateRaw);
|
|
};
|
|
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdmlld2VyL2hlbHBlcnMvc3RhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEdBQUcsRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQUduRSxPQUFPLEVBQUUsdUNBQXVDLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUM1RSxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQUVqRSxNQUFNLENBQUMsTUFBTSw2QkFBNkIsR0FBRyxvQkFBb0IsQ0FBQTtBQUVqRSx5RkFBeUY7QUFDekYsTUFBTSxDQUFOLElBQVksZUFLWDtBQUxELFdBQVksZUFBZTtJQUN6Qix1RUFBaUIsQ0FBQTtJQUNqQixxRUFBZ0IsQ0FBQTtJQUNoQixxREFBUSxDQUFBO0lBQ1IsdURBQVMsQ0FBQTtBQUNYLENBQUMsRUFMVyxlQUFlLEtBQWYsZUFBZSxRQUsxQjtBQXdCRCxNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBaUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNuRixPQUFPLEVBQUUsSUFBSTtJQUNiLElBQUksRUFBRSxlQUFlLENBQUMsWUFBWTtJQUNsQyxVQUFVLEVBQUUsS0FBSztJQUNqQixLQUFLLEVBQUUsR0FBRztJQUNWLFNBQVMsRUFBRSxDQUFDO0NBQ2IsQ0FBQyxDQUFBO0FBUUY7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILE1BQU0sQ0FBQyxNQUFNLCtCQUErQixHQUFHLEdBQUcsQ0FBQTtBQXVHbEQ7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxHQUFZLEVBQWdDLEVBQUU7SUFDcEYsSUFBSSxDQUFDLEdBQUc7UUFBRSxPQUFPLEtBQUssQ0FBQTtJQUN0QixNQUFNLElBQUksR0FBdUM7UUFDL0MsV0FBVztRQUNYLFdBQVc7UUFDWCxX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RSxLQUFLLENBQUMsRUFBRSxFQUFFLFdBQVcsRUFBRSxZQUFZLElBQUksRUFBRTthQUN4RDtTQUNGO0tBQ0YsQ0FBQTtBQUNILENBQUMsQ0FBQTtBQUVEOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLDJCQUEyQixHQUFHLENBQ3pDLEtBQXVCLEVBQ0EsRUFBRTtJQUN6QixNQUFNLFVBQVUsR0FBRyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUMvQyxPQUFPLFVBQVUsQ0FBQTtBQUNuQixDQUFDLENBQUE7QUFFRCxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxDQUNuQywwQkFBbUMsRUFDTyxFQUFFO0lBQzVDLE1BQU0sS0FBSyxHQUFHLHVCQUF1QixDQUFDLDBCQUEwQixDQUFDO1FBQy9ELENBQUMsQ0FBQywyQkFBMkIsQ0FBQywwQkFBMEIsQ0FBQztRQUN6RCxDQUFDLENBQUMsSUFBSSxDQUFBO0lBQ1IsSUFBSSxDQUFDLEtBQUs7UUFBRSxPQUFPLElBQUksQ0FBQTtJQUV2QixPQUFPO1FBQ0wsT0FBTyxFQUFFLCtCQUErQjtRQUN4QyxLQUFLO0tBQ04sQ0FBQTtBQUNILENBQUMsQ0FBQTtBQUVELE1BQU0sQ0FBQyxNQUFNLGdDQUFnQyxHQUFHLENBQzlDLElBQWEsRUFDMkIsRUFBRTtJQUMxQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQztRQUFFLE9BQU8sS0FBSyxDQUFBO0lBQzlDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQztRQUFFLE9BQU8sS0FBSyxDQUFBO0lBQ3ZDLE1BQU0sUUFBUSxHQUFJLElBQWdDLENBQUMsS0FBSyxDQUFBO0lBQ3hELE9BQU8sdUJBQXVCLENBQUMsUUFBUSxDQUFDLENBQUE7QUFDMUMsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaGFzLCBpbnRlcnNlY3Rpb24sIGlzTnVtYmVyLCBpc09iamVjdExpa2UgfSBmcm9tICcjbG9kYXNoJ1xyXG5pbXBvcnQgdHlwZSB7IE1heWJlTnVsbE9yVW5kZWZpbmVkLCBOdWxsYWJsZSB9IGZyb20gJy4uLy4uL2NvcmUvaGVscGVycy91dGlsaXR5VHlwZXMuanMnXHJcbmltcG9ydCB0eXBlIHsgUGFydGlhbERlZXAgfSBmcm9tICd0eXBlLWZlc3QnXHJcbmltcG9ydCB7IFVuZm9ybWF0dGFibGVTZXJpYWxpemVkVmlld2VyU3RhdGVFcnJvciB9IGZyb20gJy4uL2Vycm9ycy9pbmRleC5qcydcclxuaW1wb3J0IHsgY29lcmNlVW5kZWZpbmVkVmFsdWVzVG9OdWxsIH0gZnJvbSAnLi4vLi4vY29yZS9pbmRleC5qcydcclxuXHJcbmV4cG9ydCBjb25zdCBkZWZhdWx0Vmlld01vZGVFZGdlQ29sb3JWYWx1ZSA9ICdERUZBVUxUX0VER0VfQ09MT1InXHJcblxyXG4vKiogUmVkZWZpbmluZyB0aGVzZSBpcyB1bmZvcnR1bmF0ZS4gRXNwZWNpYWxseSBzaW5jZSB0aGV5IGFyZSBub3QgcGFydCBvZiB2aWV3ZXItY29yZSAqL1xyXG5leHBvcnQgZW51bSBNZWFzdXJlbWVudFR5cGUge1xyXG4gIFBFUlBFTkRJQ1VMQVIgPSAwLFxyXG4gIFBPSU5UVE9QT0lOVCA9IDEsXHJcbiAgQVJFQSA9IDIsXHJcbiAgUE9JTlQgPSAzXHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgTWVhc3VyZW1lbnRPcHRpb25zIHtcclxuICB2aXNpYmxlOiBib29sZWFuXHJcbiAgdHlwZT86IE1lYXN1cmVtZW50VHlwZVxyXG4gIHZlcnRleFNuYXA/OiBib29sZWFuXHJcbiAgdW5pdHM/OiBzdHJpbmdcclxuICBwcmVjaXNpb24/OiBudW1iZXJcclxuICBjaGFpbj86IGJvb2xlYW5cclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBNZWFzdXJlbWVudERhdGEge1xyXG4gIHR5cGU6IE1lYXN1cmVtZW50VHlwZVxyXG4gIHN0YXJ0UG9pbnQ6IHJlYWRvbmx5IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSAvLyB2ZWMzXHJcbiAgZW5kUG9pbnQ6IHJlYWRvbmx5IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSAvLyB2ZWMzXHJcbiAgc3RhcnROb3JtYWw6IHJlYWRvbmx5IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSAvLyB2ZWMzXHJcbiAgZW5kTm9ybWFsOiByZWFkb25seSBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gLy8gdmVjM1xyXG4gIHZhbHVlOiBudW1iZXJcclxuICBpbm5lclBvaW50cz86IChyZWFkb25seSBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0pW10gLy8gYXJyYXkgb2YgdmVjM1xyXG4gIHVuaXRzPzogc3RyaW5nXHJcbiAgcHJlY2lzaW9uPzogbnVtYmVyXHJcbiAgdXVpZDogc3RyaW5nXHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBkZWZhdWx0TWVhc3VyZW1lbnRPcHRpb25zOiBSZWFkb25seTxNZWFzdXJlbWVudE9wdGlvbnM+ID0gT2JqZWN0LmZyZWV6ZSh7XHJcbiAgdmlzaWJsZTogdHJ1ZSxcclxuICB0eXBlOiBNZWFzdXJlbWVudFR5cGUuUE9JTlRUT1BPSU5ULFxyXG4gIHZlcnRleFNuYXA6IGZhbHNlLFxyXG4gIHVuaXRzOiAnbScsXHJcbiAgcHJlY2lzaW9uOiAyXHJcbn0pXHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFNlY3Rpb25Cb3hEYXRhIHtcclxuICBtaW46IG51bWJlcltdXHJcbiAgbWF4OiBudW1iZXJbXVxyXG4gIHJvdGF0aW9uPzogbnVtYmVyW11cclxufVxyXG5cclxuLyoqXHJcbiAqIHYxIC0+IHYxLjFcclxuICogLSB1aS5maWx0ZXJzLnByb3BlcnR5RmlsdGVyLmlzQXBwbGllZCBmaWVsZCBhZGRlZFxyXG4gKiAtIHVpLnNwb3RsaWdodFVzZXJJZCBzd2FwcGVkIGZvciBzcG90bGlnaHRVc2VyU2Vzc2lvbklkXHJcbiAqIHYxLjEgLT4gdjEuMlxyXG4gKiAtIHVpLmRpZmYgYWRkZWRcclxuICogdjEuMiAtPiB2MS4zXHJcbiAqIC0gdWkuZmlsdGVycy5zZWxlY3RlZE9iamVjdElkcyByZW1vdmVkIGluIGZhdm9yIG9mIHVpLmZpbHRlcnMuc2VsZWN0ZWRPYmplY3RBcHBsaWNhdGlvbklkc1xyXG4gKiB2MS4zIC0+IDEuNFxyXG4gKiAtIHVpLnZpZXdNb2RlIC0+IHVpLnZpZXdNb2RlLm1vZGVcclxuICogLSB1aS52aWV3TW9kZSBoYXMgbmV3IGtleXM6IGVkZ2VzRW5hYmxlZCwgZWRnZXNXZWlnaHQsIG91dGxpbmVPcGFjaXR5LCBlZGdlc0NvbG9yXHJcbiAqIHYxLjQgLT4gMS41XHJcbiAqIC0gdWkubWVhc3VyZW1lbnQubWVhc3VyZW1lbnRzIGFkZGVkXHJcbiAqIHYxLjUgLT4gMS42XHJcbiAqIC0gdWkuZmlsdGVycy5wcm9wZXJ0eUZpbHRlciAtPiBwcm9wZXJ0eUZpbHRlcnNcclxuICogLSBhY3RpdmVDb2xvckZpbHRlcklkIGFkZGVkXHJcbiAqIHYxLjYgLT4gMS43XHJcbiAqIC0gdWkuZmlsdGVycy5maWx0ZXJMb2dpYyBhZGRlZFxyXG4gKiAtIHVpLmZpbHRlcnMucHJvcGVydHlGaWx0ZXJzLmNvbmRpdGlvbiB1cGRhdGVkXHJcbiAqIHYxLjcgLT4gMS44XHJcbiAqIC0gdWkuZmlsdGVycy5wcm9wZXJ0eUZpbHRlcnMubnVtZXJpY1JhbmdlIGFkZGVkXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgU0VSSUFMSVpFRF9WSUVXRVJfU1RBVEVfVkVSU0lPTiA9IDEuOFxyXG5cclxuZXhwb3J0IHR5cGUgU2VyaWFsaXplZFZpZXdlclN0YXRlID0ge1xyXG4gIHByb2plY3RJZDogc3RyaW5nXHJcbiAgc2Vzc2lvbklkOiBzdHJpbmdcclxuICB2aWV3ZXI6IHtcclxuICAgIG1ldGFkYXRhOiB7XHJcbiAgICAgIGZpbHRlcmluZ1N0YXRlOiBOdWxsYWJsZTx7XHJcbiAgICAgICAgcGFzc01pbj86IE1heWJlTnVsbE9yVW5kZWZpbmVkPG51bWJlcj5cclxuICAgICAgICBwYXNzTWF4PzogTWF5YmVOdWxsT3JVbmRlZmluZWQ8bnVtYmVyPlxyXG4gICAgICB9PlxyXG4gICAgfVxyXG4gIH1cclxuICByZXNvdXJjZXM6IHtcclxuICAgIHJlcXVlc3Q6IHtcclxuICAgICAgcmVzb3VyY2VJZFN0cmluZzogc3RyaW5nXHJcbiAgICAgIHRocmVhZEZpbHRlcnM6IHtcclxuICAgICAgICBpbmNsdWRlQXJjaGl2ZWQ/OiBNYXliZU51bGxPclVuZGVmaW5lZDxib29sZWFuPlxyXG4gICAgICAgIGxvYWRlZFZlcnNpb25zT25seT86IE1heWJlTnVsbE9yVW5kZWZpbmVkPGJvb2xlYW4+XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbiAgdWk6IHtcclxuICAgIHRocmVhZHM6IHtcclxuICAgICAgb3BlblRocmVhZDoge1xyXG4gICAgICAgIHRocmVhZElkOiBOdWxsYWJsZTxzdHJpbmc+XHJcbiAgICAgICAgaXNUeXBpbmc6IGJvb2xlYW5cclxuICAgICAgICBuZXdUaHJlYWRFZGl0b3I6IGJvb2xlYW5cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgZGlmZjoge1xyXG4gICAgICBjb21tYW5kOiBOdWxsYWJsZTxzdHJpbmc+XHJcbiAgICAgIHRpbWU6IG51bWJlclxyXG4gICAgICBtb2RlOiBudW1iZXJcclxuICAgIH1cclxuICAgIHNwb3RsaWdodFVzZXJTZXNzaW9uSWQ6IE51bGxhYmxlPHN0cmluZz5cclxuICAgIGZpbHRlcnM6IHtcclxuICAgICAgaXNvbGF0ZWRPYmplY3RJZHM6IHN0cmluZ1tdXHJcbiAgICAgIGhpZGRlbk9iamVjdElkczogc3RyaW5nW11cclxuICAgICAgLyoqIE1hcCBvZiBvYmplY3QgaWQgPT4gYXBwbGljYXRpb24gaWQgb3IgbnVsbCwgaWYgbm8gYXBwbGljYXRpb24gaWQgKi9cclxuICAgICAgc2VsZWN0ZWRPYmplY3RBcHBsaWNhdGlvbklkczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVsbD5cclxuICAgICAgcHJvcGVydHlGaWx0ZXJzOiBBcnJheTx7XHJcbiAgICAgICAga2V5OiBOdWxsYWJsZTxzdHJpbmc+XHJcbiAgICAgICAgaXNBcHBsaWVkOiBib29sZWFuXHJcbiAgICAgICAgc2VsZWN0ZWRWYWx1ZXM6IHN0cmluZ1tdXHJcbiAgICAgICAgaWQ6IHN0cmluZ1xyXG4gICAgICAgIGNvbmRpdGlvbjogc3RyaW5nXHJcbiAgICAgICAgbnVtZXJpY1JhbmdlPzogeyBtaW46IG51bWJlcjsgbWF4OiBudW1iZXIgfVxyXG4gICAgICB9PlxyXG4gICAgICBhY3RpdmVDb2xvckZpbHRlcklkOiBOdWxsYWJsZTxzdHJpbmc+XHJcbiAgICAgIGZpbHRlckxvZ2ljOiBzdHJpbmdcclxuICAgIH1cclxuICAgIGNhbWVyYToge1xyXG4gICAgICBwb3NpdGlvbjogbnVtYmVyW11cclxuICAgICAgdGFyZ2V0OiBudW1iZXJbXVxyXG4gICAgICBpc09ydGhvUHJvamVjdGlvbjogYm9vbGVhblxyXG4gICAgICB6b29tOiBudW1iZXJcclxuICAgIH1cclxuICAgIHZpZXdNb2RlOiB7XHJcbiAgICAgIG1vZGU6IG51bWJlclxyXG4gICAgICBlZGdlc0VuYWJsZWQ6IGJvb2xlYW5cclxuICAgICAgZWRnZXNXZWlnaHQ6IG51bWJlclxyXG4gICAgICBvdXRsaW5lT3BhY2l0eTogbnVtYmVyXHJcbiAgICAgIGVkZ2VzQ29sb3I6IHR5cGVvZiBkZWZhdWx0Vmlld01vZGVFZGdlQ29sb3JWYWx1ZSB8IG51bWJlclxyXG4gICAgfVxyXG4gICAgc2VjdGlvbkJveDogTnVsbGFibGU8U2VjdGlvbkJveERhdGE+XHJcbiAgICBsaWdodENvbmZpZzoge1xyXG4gICAgICBpbnRlbnNpdHk/OiBudW1iZXJcclxuICAgICAgaW5kaXJlY3RMaWdodEludGVuc2l0eT86IG51bWJlclxyXG4gICAgICBlbGV2YXRpb24/OiBudW1iZXJcclxuICAgICAgYXppbXV0aD86IG51bWJlclxyXG4gICAgfVxyXG4gICAgZXhwbG9kZUZhY3RvcjogbnVtYmVyXHJcbiAgICBzZWxlY3Rpb246IE51bGxhYmxlPG51bWJlcltdPlxyXG4gICAgbWVhc3VyZW1lbnQ6IHtcclxuICAgICAgZW5hYmxlZDogYm9vbGVhblxyXG4gICAgICBvcHRpb25zOiBOdWxsYWJsZTxNZWFzdXJlbWVudE9wdGlvbnM+XHJcbiAgICAgIG1lYXN1cmVtZW50czogQXJyYXk8TWVhc3VyZW1lbnREYXRhPlxyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IHR5cGUgVmVyc2lvbmVkU2VyaWFsaXplZFZpZXdlclN0YXRlID0ge1xyXG4gIHZlcnNpb246IG51bWJlclxyXG4gIHN0YXRlOiBTZXJpYWxpemVkVmlld2VyU3RhdGVcclxufVxyXG5cclxudHlwZSBVbmZvcm1hdHRlZFN0YXRlID0gUGFydGlhbERlZXA8XHJcbiAgU2VyaWFsaXplZFZpZXdlclN0YXRlICYge1xyXG4gICAgLy8gUHJvcGVydGllcyByZW1vdmVkIGZyb20gZWFybGllciB2aWV3ZXIgc3RhdGUgdmVyc2lvbnNcclxuICAgIHVpOiB7XHJcbiAgICAgIGZpbHRlcnM6IHtcclxuICAgICAgICBzZWxlY3RlZE9iamVjdElkczogc3RyaW5nW11cclxuICAgICAgICAvLyBMZWdhY3kgc2luZ2xlIHByb3BlcnR5RmlsdGVyIGZvciBtaWdyYXRpb25cclxuICAgICAgICBwcm9wZXJ0eUZpbHRlcjoge1xyXG4gICAgICAgICAga2V5OiBOdWxsYWJsZTxzdHJpbmc+XHJcbiAgICAgICAgICBpc0FwcGxpZWQ6IGJvb2xlYW5cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbj5cclxuXHJcbi8qKlxyXG4gKiBOb3RlOiBUaGlzIG9ubHkgZG9lcyBzdXBlcmZpY2lhbCB2YWxpZGF0aW9uLiBUbyByZWFsbHkgZW5zdXJlIHRoYXQgYWxsIG9mIHRoZSBrZXlzIGFyZSB0aGVyZSwgZXZlbiBpZiBwcmVmaWxsZWQgd2l0aCBkZWZhdWx0IHZhbHVlcywgbWFrZSBzdXJlIHlvdSBpbnZva2VcclxuICogZm9ybWF0U2VyaWFsaXplZFZpZXdlclN0YXRlKCkgb24gdGhlIHN0YXRlIGFmdGVyd2FyZHNcclxuICovXHJcbmV4cG9ydCBjb25zdCBpc1NlcmlhbGl6ZWRWaWV3ZXJTdGF0ZSA9ICh2YWw6IHVua25vd24pOiB2YWwgaXMgU2VyaWFsaXplZFZpZXdlclN0YXRlID0+IHtcclxuICBpZiAoIXZhbCkgcmV0dXJuIGZhbHNlXHJcbiAgY29uc3Qga2V5czogQXJyYXk8a2V5b2YgU2VyaWFsaXplZFZpZXdlclN0YXRlPiA9IFtcclxuICAgICdwcm9qZWN0SWQnLFxyXG4gICAgJ3Nlc3Npb25JZCcsXHJcbiAgICAncmVzb3VyY2VzJyxcclxuICAgICd1aScsXHJcbiAgICAndmlld2VyJ1xyXG4gIF1cclxuICBpZiAoIWlzT2JqZWN0TGlrZSh2YWwpKSByZXR1cm4gZmFsc2VcclxuXHJcbiAgY29uc3QgdmFsS2V5cyA9IE9iamVjdC5rZXlzKHZhbCBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilcclxuICBpZiAoaW50ZXJzZWN0aW9uKHZhbEtleXMsIGtleXMpLmxlbmd0aCAhPT0ga2V5cy5sZW5ndGgpIHJldHVybiBmYWxzZVxyXG5cclxuICByZXR1cm4gdHJ1ZVxyXG59XHJcblxyXG5jb25zdCBpbml0aWFsaXplTWlzc2luZ0RhdGEgPSAoc3RhdGU6IFVuZm9ybWF0dGVkU3RhdGUpOiBTZXJpYWxpemVkVmlld2VyU3RhdGUgPT4ge1xyXG4gIGNvbnN0IHRocm93SW52YWxpZEVycm9yID0gKG1pc3NpbmdQYXRoOiBzdHJpbmcpOiBuZXZlciA9PiB7XHJcbiAgICB0aHJvdyBuZXcgVW5mb3JtYXR0YWJsZVNlcmlhbGl6ZWRWaWV3ZXJTdGF0ZUVycm9yKFxyXG4gICAgICAnUmVxdWlyZWQgZGF0YSBtaXNzaW5nIGZyb20gU2VyaWFsaXplZFZpZXdlclN0YXRlOiAnICsgbWlzc2luZ1BhdGhcclxuICAgIClcclxuICB9XHJcblxyXG4gIGNvbnN0IG1lYXN1cmVtZW50T3B0aW9ucyA9IHtcclxuICAgIC4uLmRlZmF1bHRNZWFzdXJlbWVudE9wdGlvbnMsXHJcbiAgICAuLi5zdGF0ZS51aT8ubWVhc3VyZW1lbnQ/Lm9wdGlvbnNcclxuICB9XHJcblxyXG4gIGNvbnN0IHNlbGVjdGVkT2JqZWN0QXBwbGljYXRpb25JZHMgPSB7XHJcbiAgICAvLyBQYXJzZSBsZWdhY3kgb2JqZWN0IGlkcyBhcnJheSBhcyBvYmplY3RcclxuICAgIC4uLihzdGF0ZS51aT8uZmlsdGVycz8uc2VsZWN0ZWRPYmplY3RJZHM/LnJlZHVjZSgocmV0LCBpZCkgPT4ge1xyXG4gICAgICByZXRbaWRdID0gbnVsbFxyXG4gICAgICByZXR1cm4gcmV0XHJcbiAgICB9LCB7fSBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBudWxsPikgPz8ge30pLFxyXG4gICAgLy8gU2FuaXRpemUgaW5jb21pbmcgb2JqZWN0XHJcbiAgICAuLi5jb2VyY2VVbmRlZmluZWRWYWx1ZXNUb051bGwoXHJcbiAgICAgIHN0YXRlLnVpPy5maWx0ZXJzPy5zZWxlY3RlZE9iamVjdEFwcGxpY2F0aW9uSWRzIHx8IHt9XHJcbiAgICApXHJcbiAgfVxyXG5cclxuICBjb25zdCB2aWV3TW9kZVR5cGUgPSBpc051bWJlcihzdGF0ZS51aT8udmlld01vZGUpXHJcbiAgICA/IHN0YXRlLnVpLnZpZXdNb2RlXHJcbiAgICA6IHN0YXRlLnVpPy52aWV3TW9kZT8ubW9kZVxyXG5cclxuICBjb25zdCB2aWV3TW9kZVNldHRpbmdzID0gaXNOdW1iZXIoc3RhdGUudWk/LnZpZXdNb2RlKSA/IHt9IDogc3RhdGUudWk/LnZpZXdNb2RlXHJcblxyXG4gIHJldHVybiB7XHJcbiAgICBwcm9qZWN0SWQ6IHN0YXRlLnByb2plY3RJZCB8fCB0aHJvd0ludmFsaWRFcnJvcigncHJvamVjdElkJyksXHJcbiAgICBzZXNzaW9uSWQ6IHN0YXRlLnNlc3Npb25JZCB8fCBgbnVsbFNlc3Npb25JZC0ke01hdGgucmFuZG9tKCkgKiAxMDAwfWAsXHJcbiAgICB2aWV3ZXI6IHtcclxuICAgICAgLi4uKHN0YXRlLnZpZXdlciB8fCB7fSksXHJcbiAgICAgIG1ldGFkYXRhOiB7XHJcbiAgICAgICAgLi4uKHN0YXRlLnZpZXdlcj8ubWV0YWRhdGEgfHwge30pLFxyXG4gICAgICAgIGZpbHRlcmluZ1N0YXRlOiBzdGF0ZS52aWV3ZXI/Lm1ldGFkYXRhPy5maWx0ZXJpbmdTdGF0ZSB8fCBudWxsXHJcbiAgICAgIH1cclxuICAgIH0sXHJcbiAgICByZXNvdXJjZXM6IHtcclxuICAgICAgLi4uKHN0YXRlLnJlc291cmNlcyB8fCB7fSksXHJcbiAgICAgIHJlcXVlc3Q6IHtcclxuICAgICAgICAuLi4oc3RhdGUucmVzb3VyY2VzPy5yZXF1ZXN0IHx8IHt9KSxcclxuICAgICAgICByZXNvdXJjZUlkU3RyaW5nOlxyXG4gICAgICAgICAgc3RhdGUucmVzb3VyY2VzPy5yZXF1ZXN0Py5yZXNvdXJjZUlkU3RyaW5nIHx8XHJcbiAgICAgICAgICB0aHJvd0ludmFsaWRFcnJvcigncmVzb3VyY2VzLnJlcXVlc3QucmVzb3VyY2VJZFN0cmluZycpLFxyXG4gICAgICAgIHRocmVhZEZpbHRlcnM6IHtcclxuICAgICAgICAgIC4uLihzdGF0ZS5yZXNvdXJjZXM/LnJlcXVlc3Q/LnRocmVhZEZpbHRlcnMgfHwge30pLFxyXG4gICAgICAgICAgaW5jbHVkZUFyY2hpdmVkOlxyXG4gICAgICAgICAgICBzdGF0ZS5yZXNvdXJjZXM/LnJlcXVlc3Q/LnRocmVhZEZpbHRlcnM/LmluY2x1ZGVBcmNoaXZlZCB8fCBmYWxzZSxcclxuICAgICAgICAgIGxvYWRlZFZlcnNpb25zT25seTpcclxuICAgICAgICAgICAgc3RhdGUucmVzb3VyY2VzPy5yZXF1ZXN0Py50aHJlYWRGaWx0ZXJzPy5sb2FkZWRWZXJzaW9uc09ubHkgfHwgZmFsc2VcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0sXHJcbiAgICB1aToge1xyXG4gICAgICAuLi4oc3RhdGUudWkgfHwge30pLFxyXG4gICAgICB0aHJlYWRzOiB7XHJcbiAgICAgICAgLi4uKHN0YXRlLnVpPy50aHJlYWRzIHx8IHt9KSxcclxuICAgICAgICBvcGVuVGhyZWFkOiB7XHJcbiAgICAgICAgICAuLi4oc3RhdGUudWk/LnRocmVhZHM/Lm9wZW5UaHJlYWQgfHwge30pLFxyXG4gICAgICAgICAgdGhyZWFkSWQ6IHN0YXRlLnVpPy50aHJlYWRzPy5vcGVuVGhyZWFkPy50aHJlYWRJZCB8fCBudWxsLFxyXG4gICAgICAgICAgaXNUeXBpbmc6IHN0YXRlLnVpPy50aHJlYWRzPy5vcGVuVGhyZWFkPy5pc1R5cGluZyB8fCBmYWxzZSxcclxuICAgICAgICAgIG5ld1RocmVhZEVkaXRvcjogc3RhdGUudWk/LnRocmVhZHM/Lm9wZW5UaHJlYWQ/Lm5ld1RocmVhZEVkaXRvciB8fCBmYWxzZVxyXG4gICAgICAgIH1cclxuICAgICAgfSxcclxuICAgICAgZGlmZjoge1xyXG4gICAgICAgIC4uLihzdGF0ZS51aT8uZGlmZiB8fCB7fSksXHJcbiAgICAgICAgY29tbWFuZDogc3RhdGUudWk/LmRpZmY/LmNvbW1hbmQgfHwgbnVsbCxcclxuICAgICAgICB0aW1lOiBzdGF0ZS51aT8uZGlmZj8udGltZSB8fCAwLjUsXHJcbiAgICAgICAgbW9kZTogc3RhdGUudWk/LmRpZmY/Lm1vZGUgfHwgMVxyXG4gICAgICB9LFxyXG4gICAgICBzcG90bGlnaHRVc2VyU2Vzc2lvbklkOiBzdGF0ZS51aT8uc3BvdGxpZ2h0VXNlclNlc3Npb25JZCB8fCBudWxsLFxyXG4gICAgICBmaWx0ZXJzOiAoKCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGJhc2VGaWx0ZXJzID0ge1xyXG4gICAgICAgICAgLi4uKHN0YXRlLnVpPy5maWx0ZXJzIHx8IHt9KSxcclxuICAgICAgICAgIGlzb2xhdGVkT2JqZWN0SWRzOiBzdGF0ZS51aT8uZmlsdGVycz8uaXNvbGF0ZWRPYmplY3RJZHMgfHwgW10sXHJcbiAgICAgICAgICBoaWRkZW5PYmplY3RJZHM6IHN0YXRlLnVpPy5maWx0ZXJzPy5oaWRkZW5PYmplY3RJZHMgfHwgW10sXHJcbiAgICAgICAgICBzZWxlY3RlZE9iamVjdEFwcGxpY2F0aW9uSWRzLFxyXG4gICAgICAgICAgYWN0aXZlQ29sb3JGaWx0ZXJJZDogc3RhdGUudWk/LmZpbHRlcnM/LmFjdGl2ZUNvbG9yRmlsdGVySWQgfHwgbnVsbFxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gTWlncmF0aW9uIGxvZ2ljOiBoYW5kbGUgbGVnYWN5IHByb3BlcnR5RmlsdGVyIGFuZCBuZXcgcHJvcGVydHlGaWx0ZXJzXHJcbiAgICAgICAgbGV0IHByb3BlcnR5RmlsdGVyczogQXJyYXk8e1xyXG4gICAgICAgICAga2V5OiBOdWxsYWJsZTxzdHJpbmc+XHJcbiAgICAgICAgICBpc0FwcGxpZWQ6IGJvb2xlYW5cclxuICAgICAgICAgIHNlbGVjdGVkVmFsdWVzOiBzdHJpbmdbXVxyXG4gICAgICAgICAgaWQ6IHN0cmluZ1xyXG4gICAgICAgICAgY29uZGl0aW9uOiBzdHJpbmdcclxuICAgICAgICAgIG51bWVyaWNSYW5nZT86IHsgbWluOiBudW1iZXI7IG1heDogbnVtYmVyIH1cclxuICAgICAgICB9PiA9IFtdXHJcblxyXG4gICAgICAgIC8vIElmIG5ldyBwcm9wZXJ0eUZpbHRlcnMgZXhpc3QgYW5kIGFyZSBub3QgZW1wdHksIHVzZSB0aGVtXHJcbiAgICAgICAgaWYgKFxyXG4gICAgICAgICAgc3RhdGUudWk/LmZpbHRlcnM/LnByb3BlcnR5RmlsdGVycyAmJlxyXG4gICAgICAgICAgQXJyYXkuaXNBcnJheShzdGF0ZS51aS5maWx0ZXJzLnByb3BlcnR5RmlsdGVycykgJiZcclxuICAgICAgICAgIHN0YXRlLnVpLmZpbHRlcnMucHJvcGVydHlGaWx0ZXJzLmxlbmd0aCA+IDBcclxuICAgICAgICApIHtcclxuICAgICAgICAgIC8vIE1hcCBsZWdhY3kgY29uZGl0aW9uIHZhbHVlcyB0byBuZXcgZm9ybWF0XHJcbiAgICAgICAgICBwcm9wZXJ0eUZpbHRlcnMgPSBzdGF0ZS51aS5maWx0ZXJzLnByb3BlcnR5RmlsdGVycy5tYXAoKGZpbHRlcikgPT4gKHtcclxuICAgICAgICAgICAgLi4uZmlsdGVyLFxyXG4gICAgICAgICAgICBjb25kaXRpb246XHJcbiAgICAgICAgICAgICAgZmlsdGVyLmNvbmRpdGlvbiA9PT0gJ0FORCdcclxuICAgICAgICAgICAgICAgID8gJ2lzJ1xyXG4gICAgICAgICAgICAgICAgOiBmaWx0ZXIuY29uZGl0aW9uID09PSAnT1InXHJcbiAgICAgICAgICAgICAgICA/ICdpcydcclxuICAgICAgICAgICAgICAgIDogZmlsdGVyLmNvbmRpdGlvblxyXG4gICAgICAgICAgfSkpXHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIElmIGxlZ2FjeSBwcm9wZXJ0eUZpbHRlciBleGlzdHMgYnV0IG5vIHByb3BlcnR5RmlsdGVycyAob3IgZW1wdHkgcHJvcGVydHlGaWx0ZXJzKSwgbWlncmF0ZSBpdFxyXG4gICAgICAgIGVsc2UgaWYgKHN0YXRlLnVpPy5maWx0ZXJzPy5wcm9wZXJ0eUZpbHRlcj8ua2V5KSB7XHJcbiAgICAgICAgICBwcm9wZXJ0eUZpbHRlcnMgPSBbXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICBrZXk6IHN0YXRlLnVpLmZpbHRlcnMucHJvcGVydHlGaWx0ZXIua2V5LFxyXG4gICAgICAgICAgICAgIGlzQXBwbGllZDogc3RhdGUudWkuZmlsdGVycy5wcm9wZXJ0eUZpbHRlci5pc0FwcGxpZWQgfHwgZmFsc2UsXHJcbiAgICAgICAgICAgICAgc2VsZWN0ZWRWYWx1ZXM6IFtdLCAvLyBMZWdhY3kgZGlkbid0IGhhdmUgc2VsZWN0ZWRWYWx1ZXNcclxuICAgICAgICAgICAgICBpZDogJ2xlZ2FjeS1maWx0ZXInLCAvLyBHZW5lcmF0ZSBhIGNvbnNpc3RlbnQgSUQgZm9yIGxlZ2FjeSBmaWx0ZXJcclxuICAgICAgICAgICAgICBjb25kaXRpb246ICdpcydcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgXVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgIC4uLmJhc2VGaWx0ZXJzLFxyXG4gICAgICAgICAgcHJvcGVydHlGaWx0ZXJzLFxyXG4gICAgICAgICAgZmlsdGVyTG9naWM6IHN0YXRlLnVpPy5maWx0ZXJzPy5maWx0ZXJMb2dpYyB8fCAnYWxsJ1xyXG4gICAgICAgIH1cclxuICAgICAgfSkoKSxcclxuICAgICAgY2FtZXJhOiB7XHJcbiAgICAgICAgLi4uKHN0YXRlLnVpPy5jYW1lcmEgfHwge30pLFxyXG4gICAgICAgIHBvc2l0aW9uOiBzdGF0ZS51aT8uY2FtZXJhPy5wb3NpdGlvbiB8fCB0aHJvd0ludmFsaWRFcnJvcigndWkuY2FtZXJhLnBvc2l0aW9uJyksXHJcbiAgICAgICAgdGFyZ2V0OiBzdGF0ZS51aT8uY2FtZXJhPy50YXJnZXQgfHwgdGhyb3dJbnZhbGlkRXJyb3IoJ3VpLmNhbWVyYS50YXJnZXQnKSxcclxuICAgICAgICBpc09ydGhvUHJvamVjdGlvbjogc3RhdGUudWk/LmNhbWVyYT8uaXNPcnRob1Byb2plY3Rpb24gfHwgZmFsc2UsXHJcbiAgICAgICAgem9vbTogc3RhdGUudWk/LmNhbWVyYT8uem9vbSB8fCAxXHJcbiAgICAgIH0sXHJcbiAgICAgIHZpZXdNb2RlOiB7XHJcbiAgICAgICAgbW9kZTogdmlld01vZGVUeXBlID8/IDAsXHJcbiAgICAgICAgZWRnZXNFbmFibGVkOiB2aWV3TW9kZVNldHRpbmdzPy5lZGdlc0VuYWJsZWQgPz8gZmFsc2UsXHJcbiAgICAgICAgZWRnZXNXZWlnaHQ6IHZpZXdNb2RlU2V0dGluZ3M/LmVkZ2VzV2VpZ2h0ID8/IDEsXHJcbiAgICAgICAgb3V0bGluZU9wYWNpdHk6IHZpZXdNb2RlU2V0dGluZ3M/Lm91dGxpbmVPcGFjaXR5ID8/IDAuNzUsXHJcbiAgICAgICAgZWRnZXNDb2xvcjogdmlld01vZGVTZXR0aW5ncz8uZWRnZXNDb2xvciA/PyBkZWZhdWx0Vmlld01vZGVFZGdlQ29sb3JWYWx1ZVxyXG4gICAgICB9LFxyXG4gICAgICBzZWN0aW9uQm94OlxyXG4gICAgICAgIHN0YXRlLnVpPy5zZWN0aW9uQm94Py5taW4/Lmxlbmd0aCAmJiBzdGF0ZS51aT8uc2VjdGlvbkJveC5tYXg/Lmxlbmd0aFxyXG4gICAgICAgICAgPyAvLyBDb21wbGFpbnMgb3RoZXJ3aXNlXHJcbiAgICAgICAgICAgIChzdGF0ZS51aS5zZWN0aW9uQm94IGFzIFNlY3Rpb25Cb3hEYXRhKVxyXG4gICAgICAgICAgOiBudWxsLFxyXG4gICAgICBsaWdodENvbmZpZzoge1xyXG4gICAgICAgIC4uLihzdGF0ZS51aT8ubGlnaHRDb25maWcgfHwge30pLFxyXG4gICAgICAgIGludGVuc2l0eTogc3RhdGUudWk/LmxpZ2h0Q29uZmlnPy5pbnRlbnNpdHksXHJcbiAgICAgICAgaW5kaXJlY3RMaWdodEludGVuc2l0eTogc3RhdGUudWk/LmxpZ2h0Q29uZmlnPy5pbmRpcmVjdExpZ2h0SW50ZW5zaXR5LFxyXG4gICAgICAgIGVsZXZhdGlvbjogc3RhdGUudWk/LmxpZ2h0Q29uZmlnPy5lbGV2YXRpb24sXHJcbiAgICAgICAgYXppbXV0aDogc3RhdGUudWk/LmxpZ2h0Q29uZmlnPy5hemltdXRoXHJcbiAgICAgIH0sXHJcbiAgICAgIGV4cGxvZGVGYWN0b3I6IHN0YXRlLnVpPy5leHBsb2RlRmFjdG9yIHx8IDAsXHJcbiAgICAgIHNlbGVjdGlvbjogc3RhdGUudWk/LnNlbGVjdGlvbiB8fCBudWxsLFxyXG4gICAgICBtZWFzdXJlbWVudDoge1xyXG4gICAgICAgIGVuYWJsZWQ6IHN0YXRlLnVpPy5tZWFzdXJlbWVudD8uZW5hYmxlZCA/PyBmYWxzZSxcclxuICAgICAgICBvcHRpb25zOiBtZWFzdXJlbWVudE9wdGlvbnMsXHJcbiAgICAgICAgbWVhc3VyZW1lbnRzOiBzdGF0ZS51aT8ubWVhc3VyZW1lbnQ/Lm1lYXN1cmVtZW50cyB8fCBbXVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogRm9ybWF0cyBTZXJpYWxpemVkVmlld2VyU3RhdGUgYnkgYnJpbmdpbmcgaXQgdXAgdG8gZGF0ZSB3aXRoIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGxhdGVzdCB2ZXJzaW9uXHJcbiAqIGFuZCBlbnN1cmluZyBtaXNzaW5nIGtleXMgYXJlIGluaXRpYWxpemVkIHdpdGggZGVmYXVsdCB2YWx1ZXNcclxuICovXHJcbmV4cG9ydCBjb25zdCBmb3JtYXRTZXJpYWxpemVkVmlld2VyU3RhdGUgPSAoXHJcbiAgc3RhdGU6IFVuZm9ybWF0dGVkU3RhdGVcclxuKTogU2VyaWFsaXplZFZpZXdlclN0YXRlID0+IHtcclxuICBjb25zdCBmaW5hbFN0YXRlID0gaW5pdGlhbGl6ZU1pc3NpbmdEYXRhKHN0YXRlKVxyXG4gIHJldHVybiBmaW5hbFN0YXRlXHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBpbnB1dFRvVmVyc2lvbmVkU3RhdGUgPSAoXHJcbiAgaW5wdXRTZXJpYWxpemVkVmlld2VyU3RhdGU6IHVua25vd25cclxuKTogTnVsbGFibGU8VmVyc2lvbmVkU2VyaWFsaXplZFZpZXdlclN0YXRlPiA9PiB7XHJcbiAgY29uc3Qgc3RhdGUgPSBpc1NlcmlhbGl6ZWRWaWV3ZXJTdGF0ZShpbnB1dFNlcmlhbGl6ZWRWaWV3ZXJTdGF0ZSlcclxuICAgID8gZm9ybWF0U2VyaWFsaXplZFZpZXdlclN0YXRlKGlucHV0U2VyaWFsaXplZFZpZXdlclN0YXRlKVxyXG4gICAgOiBudWxsXHJcbiAgaWYgKCFzdGF0ZSkgcmV0dXJuIG51bGxcclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIHZlcnNpb246IFNFUklBTElaRURfVklFV0VSX1NUQVRFX1ZFUlNJT04sXHJcbiAgICBzdGF0ZVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IGlzVmVyc2lvbmVkU2VyaWFsaXplZFZpZXdlclN0YXRlID0gKFxyXG4gIGRhdGE6IHVua25vd25cclxuKTogZGF0YSBpcyBWZXJzaW9uZWRTZXJpYWxpemVkVmlld2VyU3RhdGUgPT4ge1xyXG4gIGlmICghZGF0YSB8fCAhaXNPYmplY3RMaWtlKGRhdGEpKSByZXR1cm4gZmFsc2VcclxuICBpZiAoIWhhcyhkYXRhLCAndmVyc2lvbicpKSByZXR1cm4gZmFsc2VcclxuICBjb25zdCBzdGF0ZVJhdyA9IChkYXRhIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5zdGF0ZVxyXG4gIHJldHVybiBpc1NlcmlhbGl6ZWRWaWV3ZXJTdGF0ZShzdGF0ZVJhdylcclxufVxyXG4iXX0= |