UNPKG

matrix-react-sdk

Version:
279 lines (273 loc) 42 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _blurhash = require("blurhash"); var _logger = require("matrix-js-sdk/src/logger"); var _languageHandler = require("../../../languageHandler"); var _SettingsStore = _interopRequireDefault(require("../../../settings/SettingsStore")); var _InlineSpinner = _interopRequireDefault(require("../elements/InlineSpinner")); var _Media = require("../../../customisations/Media"); var _imageMedia = require("../../../utils/image-media"); var _MFileBody = _interopRequireDefault(require("./MFileBody")); var _ImageSize = require("../../../settings/enums/ImageSize"); var _RoomContext = _interopRequireWildcard(require("../../../contexts/RoomContext")); var _MediaProcessingError = _interopRequireDefault(require("./shared/MediaProcessingError")); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } /* Copyright 2024 New Vector Ltd. Copyright 2015-2021 The Matrix.org Foundation C.I.C. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ class MVideoBody extends _react.default.PureComponent { constructor(...args) { super(...args); (0, _defineProperty2.default)(this, "videoRef", /*#__PURE__*/_react.default.createRef()); (0, _defineProperty2.default)(this, "sizeWatcher", void 0); (0, _defineProperty2.default)(this, "state", { fetchingData: false, decryptedUrl: null, decryptedThumbnailUrl: null, decryptedBlob: null, error: null, posterLoading: false, blurhashUrl: null }); (0, _defineProperty2.default)(this, "videoOnPlay", async () => { if (this.hasContentUrl() || this.state.fetchingData || this.state.error) { // We have the file, we are fetching the file, or there is an error. return; } this.setState({ // To stop subsequent download attempts fetchingData: true }); if (!this.props.mediaEventHelper.media.isEncrypted) { this.setState({ error: "No file given in content" }); return; } this.setState({ decryptedUrl: await this.props.mediaEventHelper.sourceUrl.value, decryptedBlob: await this.props.mediaEventHelper.sourceBlob.value, fetchingData: false }, () => { if (!this.videoRef.current) return; this.videoRef.current.play(); }); this.props.onHeightChanged?.(); }); (0, _defineProperty2.default)(this, "getFileBody", () => { if (this.props.forExport) return null; return this.showFileBody && /*#__PURE__*/_react.default.createElement(_MFileBody.default, (0, _extends2.default)({}, this.props, { showGenericPlaceholder: false })); }); } getContentUrl() { const content = this.props.mxEvent.getContent(); // During export, the content url will point to the MSC, which will later point to a local url if (this.props.forExport) return content.file?.url ?? content.url; const media = (0, _Media.mediaFromContent)(content); if (media.isEncrypted) { return this.state.decryptedUrl ?? undefined; } else { return media.srcHttp ?? undefined; } } hasContentUrl() { const url = this.getContentUrl(); return !!url && !url.startsWith("data:"); } getThumbUrl() { // there's no need of thumbnail when the content is local if (this.props.forExport) return null; const content = this.props.mxEvent.getContent(); const media = (0, _Media.mediaFromContent)(content); if (media.isEncrypted && this.state.decryptedThumbnailUrl) { return this.state.decryptedThumbnailUrl; } else if (this.state.posterLoading) { return this.state.blurhashUrl; } else if (media.hasThumbnail) { return media.thumbnailHttp; } else { return null; } } loadBlurhash() { const info = this.props.mxEvent.getContent()?.info; if (!info[_imageMedia.BLURHASH_FIELD]) return; const canvas = document.createElement("canvas"); const { w: width, h: height } = (0, _ImageSize.suggestedSize)(_SettingsStore.default.getValue("Images.size"), { w: info.w, h: info.h }); canvas.width = width; canvas.height = height; const pixels = (0, _blurhash.decode)(info[_imageMedia.BLURHASH_FIELD], width, height); const ctx = canvas.getContext("2d"); const imgData = ctx.createImageData(width, height); imgData.data.set(pixels); ctx.putImageData(imgData, 0, 0); this.setState({ blurhashUrl: canvas.toDataURL(), posterLoading: true }); const content = this.props.mxEvent.getContent(); const media = (0, _Media.mediaFromContent)(content); if (media.hasThumbnail) { const image = new Image(); image.onload = () => { this.setState({ posterLoading: false }); }; image.src = media.thumbnailHttp; } } async componentDidMount() { this.sizeWatcher = _SettingsStore.default.watchSetting("Images.size", null, () => { this.forceUpdate(); // we don't really have a reliable thing to update, so just update the whole thing }); try { this.loadBlurhash(); } catch (e) { _logger.logger.error("Failed to load blurhash", e); } if (this.props.mediaEventHelper?.media.isEncrypted && this.state.decryptedUrl === null) { try { const autoplay = _SettingsStore.default.getValue("autoplayVideo"); const thumbnailUrl = await this.props.mediaEventHelper.thumbnailUrl.value; if (autoplay) { _logger.logger.log("Preloading video"); this.setState({ decryptedUrl: await this.props.mediaEventHelper.sourceUrl.value, decryptedThumbnailUrl: thumbnailUrl, decryptedBlob: await this.props.mediaEventHelper.sourceBlob.value }); this.props.onHeightChanged?.(); } else { _logger.logger.log("NOT preloading video"); const content = this.props.mxEvent.getContent(); let mimetype = content?.info?.mimetype; // clobber quicktime muxed files to be considered MP4 so browsers // are willing to play them if (mimetype == "video/quicktime") { mimetype = "video/mp4"; } this.setState({ // For Chrome and Electron, we need to set some non-empty `src` to // enable the play button. Firefox does not seem to care either // way, so it's fine to do for all browsers. decryptedUrl: `data:${mimetype},`, decryptedThumbnailUrl: thumbnailUrl || `data:${mimetype},`, decryptedBlob: null }); } } catch (err) { _logger.logger.warn("Unable to decrypt attachment: ", err); // Set a placeholder image when we can't decrypt the image. this.setState({ error: err }); } } } componentWillUnmount() { if (this.sizeWatcher) _SettingsStore.default.unwatchSetting(this.sizeWatcher); } get showFileBody() { return this.context.timelineRenderingType !== _RoomContext.TimelineRenderingType.Room && this.context.timelineRenderingType !== _RoomContext.TimelineRenderingType.Pinned && this.context.timelineRenderingType !== _RoomContext.TimelineRenderingType.Search; } render() { const content = this.props.mxEvent.getContent(); const autoplay = !this.props.inhibitInteraction && _SettingsStore.default.getValue("autoplayVideo"); let aspectRatio; if (content.info?.w && content.info?.h) { aspectRatio = `${content.info.w}/${content.info.h}`; } const { w: maxWidth, h: maxHeight } = (0, _ImageSize.suggestedSize)(_SettingsStore.default.getValue("Images.size"), { w: content.info?.w, h: content.info?.h }); // HACK: This div fills out space while the video loads, to prevent scroll jumps const spaceFiller = /*#__PURE__*/_react.default.createElement("div", { style: { width: maxWidth, height: maxHeight } }); if (this.state.error !== null) { return /*#__PURE__*/_react.default.createElement(_MediaProcessingError.default, { className: "mx_MVideoBody" }, (0, _languageHandler._t)("timeline|m.video|error_decrypting")); } // Important: If we aren't autoplaying and we haven't decrypted it yet, show a video with a poster. if (!this.props.forExport && content.file !== undefined && this.state.decryptedUrl === null && autoplay) { // Need to decrypt the attachment // The attachment is decrypted in componentDidMount. // For now show a spinner. return /*#__PURE__*/_react.default.createElement("span", { className: "mx_MVideoBody" }, /*#__PURE__*/_react.default.createElement("div", { className: "mx_MVideoBody_container", style: { maxWidth, maxHeight, aspectRatio } }, /*#__PURE__*/_react.default.createElement(_InlineSpinner.default, null)), spaceFiller); } const contentUrl = this.getContentUrl(); const thumbUrl = this.getThumbUrl(); let poster; let preload = "metadata"; if (content.info && thumbUrl) { poster = thumbUrl; preload = "none"; } const fileBody = this.getFileBody(); return /*#__PURE__*/_react.default.createElement("span", { className: "mx_MVideoBody" }, /*#__PURE__*/_react.default.createElement("div", { className: "mx_MVideoBody_container", style: { maxWidth, maxHeight, aspectRatio } }, /*#__PURE__*/_react.default.createElement("video", { className: "mx_MVideoBody", ref: this.videoRef, src: contentUrl, title: content.body, controls: !this.props.inhibitInteraction // Disable downloading as it doesn't work with e2ee video, // users should use the dedicated Download button in the Message Action Bar , controlsList: "nodownload", preload: preload, muted: autoplay, autoPlay: autoplay, poster: poster, onPlay: this.videoOnPlay }), spaceFiller), fileBody); } } exports.default = MVideoBody; (0, _defineProperty2.default)(MVideoBody, "contextType", _RoomContext.default); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9ibHVyaGFzaCIsIl9sb2dnZXIiLCJfbGFuZ3VhZ2VIYW5kbGVyIiwiX1NldHRpbmdzU3RvcmUiLCJfSW5saW5lU3Bpbm5lciIsIl9NZWRpYSIsIl9pbWFnZU1lZGlhIiwiX01GaWxlQm9keSIsIl9JbWFnZVNpemUiLCJfUm9vbUNvbnRleHQiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsIl9NZWRpYVByb2Nlc3NpbmdFcnJvciIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIk1WaWRlb0JvZHkiLCJSZWFjdCIsIlB1cmVDb21wb25lbnQiLCJjb25zdHJ1Y3RvciIsImFyZ3MiLCJfZGVmaW5lUHJvcGVydHkyIiwiY3JlYXRlUmVmIiwiZmV0Y2hpbmdEYXRhIiwiZGVjcnlwdGVkVXJsIiwiZGVjcnlwdGVkVGh1bWJuYWlsVXJsIiwiZGVjcnlwdGVkQmxvYiIsImVycm9yIiwicG9zdGVyTG9hZGluZyIsImJsdXJoYXNoVXJsIiwiaGFzQ29udGVudFVybCIsInN0YXRlIiwic2V0U3RhdGUiLCJwcm9wcyIsIm1lZGlhRXZlbnRIZWxwZXIiLCJtZWRpYSIsImlzRW5jcnlwdGVkIiwic291cmNlVXJsIiwidmFsdWUiLCJzb3VyY2VCbG9iIiwidmlkZW9SZWYiLCJjdXJyZW50IiwicGxheSIsIm9uSGVpZ2h0Q2hhbmdlZCIsImZvckV4cG9ydCIsInNob3dGaWxlQm9keSIsImNyZWF0ZUVsZW1lbnQiLCJfZXh0ZW5kczIiLCJzaG93R2VuZXJpY1BsYWNlaG9sZGVyIiwiZ2V0Q29udGVudFVybCIsImNvbnRlbnQiLCJteEV2ZW50IiwiZ2V0Q29udGVudCIsImZpbGUiLCJ1cmwiLCJtZWRpYUZyb21Db250ZW50IiwidW5kZWZpbmVkIiwic3JjSHR0cCIsInN0YXJ0c1dpdGgiLCJnZXRUaHVtYlVybCIsImhhc1RodW1ibmFpbCIsInRodW1ibmFpbEh0dHAiLCJsb2FkQmx1cmhhc2giLCJpbmZvIiwiQkxVUkhBU0hfRklFTEQiLCJjYW52YXMiLCJkb2N1bWVudCIsInciLCJ3aWR0aCIsImgiLCJoZWlnaHQiLCJzdWdnZXN0ZWRWaWRlb1NpemUiLCJTZXR0aW5nc1N0b3JlIiwiZ2V0VmFsdWUiLCJwaXhlbHMiLCJkZWNvZGUiLCJjdHgiLCJnZXRDb250ZXh0IiwiaW1nRGF0YSIsImNyZWF0ZUltYWdlRGF0YSIsImRhdGEiLCJwdXRJbWFnZURhdGEiLCJ0b0RhdGFVUkwiLCJpbWFnZSIsIkltYWdlIiwib25sb2FkIiwic3JjIiwiY29tcG9uZW50RGlkTW91bnQiLCJzaXplV2F0Y2hlciIsIndhdGNoU2V0dGluZyIsImZvcmNlVXBkYXRlIiwibG9nZ2VyIiwiYXV0b3BsYXkiLCJ0aHVtYm5haWxVcmwiLCJsb2ciLCJtaW1ldHlwZSIsImVyciIsIndhcm4iLCJjb21wb25lbnRXaWxsVW5tb3VudCIsInVud2F0Y2hTZXR0aW5nIiwiY29udGV4dCIsInRpbWVsaW5lUmVuZGVyaW5nVHlwZSIsIlRpbWVsaW5lUmVuZGVyaW5nVHlwZSIsIlJvb20iLCJQaW5uZWQiLCJTZWFyY2giLCJyZW5kZXIiLCJpbmhpYml0SW50ZXJhY3Rpb24iLCJhc3BlY3RSYXRpbyIsIm1heFdpZHRoIiwibWF4SGVpZ2h0Iiwic3BhY2VGaWxsZXIiLCJzdHlsZSIsImNsYXNzTmFtZSIsIl90IiwiY29udGVudFVybCIsInRodW1iVXJsIiwicG9zdGVyIiwicHJlbG9hZCIsImZpbGVCb2R5IiwiZ2V0RmlsZUJvZHkiLCJyZWYiLCJ0aXRsZSIsImJvZHkiLCJjb250cm9scyIsImNvbnRyb2xzTGlzdCIsIm11dGVkIiwiYXV0b1BsYXkiLCJvblBsYXkiLCJ2aWRlb09uUGxheSIsImV4cG9ydHMiLCJSb29tQ29udGV4dCJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL21lc3NhZ2VzL01WaWRlb0JvZHkudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDE1LTIwMjEgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IFJlYWN0LCB7IFJlYWN0Tm9kZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgZGVjb2RlIH0gZnJvbSBcImJsdXJoYXNoXCI7XG5pbXBvcnQgeyBNZWRpYUV2ZW50Q29udGVudCB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy90eXBlc1wiO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL2xvZ2dlclwiO1xuXG5pbXBvcnQgeyBfdCB9IGZyb20gXCIuLi8uLi8uLi9sYW5ndWFnZUhhbmRsZXJcIjtcbmltcG9ydCBTZXR0aW5nc1N0b3JlIGZyb20gXCIuLi8uLi8uLi9zZXR0aW5ncy9TZXR0aW5nc1N0b3JlXCI7XG5pbXBvcnQgSW5saW5lU3Bpbm5lciBmcm9tIFwiLi4vZWxlbWVudHMvSW5saW5lU3Bpbm5lclwiO1xuaW1wb3J0IHsgbWVkaWFGcm9tQ29udGVudCB9IGZyb20gXCIuLi8uLi8uLi9jdXN0b21pc2F0aW9ucy9NZWRpYVwiO1xuaW1wb3J0IHsgQkxVUkhBU0hfRklFTEQgfSBmcm9tIFwiLi4vLi4vLi4vdXRpbHMvaW1hZ2UtbWVkaWFcIjtcbmltcG9ydCB7IElCb2R5UHJvcHMgfSBmcm9tIFwiLi9JQm9keVByb3BzXCI7XG5pbXBvcnQgTUZpbGVCb2R5IGZyb20gXCIuL01GaWxlQm9keVwiO1xuaW1wb3J0IHsgSW1hZ2VTaXplLCBzdWdnZXN0ZWRTaXplIGFzIHN1Z2dlc3RlZFZpZGVvU2l6ZSB9IGZyb20gXCIuLi8uLi8uLi9zZXR0aW5ncy9lbnVtcy9JbWFnZVNpemVcIjtcbmltcG9ydCBSb29tQ29udGV4dCwgeyBUaW1lbGluZVJlbmRlcmluZ1R5cGUgfSBmcm9tIFwiLi4vLi4vLi4vY29udGV4dHMvUm9vbUNvbnRleHRcIjtcbmltcG9ydCBNZWRpYVByb2Nlc3NpbmdFcnJvciBmcm9tIFwiLi9zaGFyZWQvTWVkaWFQcm9jZXNzaW5nRXJyb3JcIjtcblxuaW50ZXJmYWNlIElTdGF0ZSB7XG4gICAgZGVjcnlwdGVkVXJsOiBzdHJpbmcgfCBudWxsO1xuICAgIGRlY3J5cHRlZFRodW1ibmFpbFVybDogc3RyaW5nIHwgbnVsbDtcbiAgICBkZWNyeXB0ZWRCbG9iOiBCbG9iIHwgbnVsbDtcbiAgICBlcnJvcj86IGFueTtcbiAgICBmZXRjaGluZ0RhdGE6IGJvb2xlYW47XG4gICAgcG9zdGVyTG9hZGluZzogYm9vbGVhbjtcbiAgICBibHVyaGFzaFVybDogc3RyaW5nIHwgbnVsbDtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTVZpZGVvQm9keSBleHRlbmRzIFJlYWN0LlB1cmVDb21wb25lbnQ8SUJvZHlQcm9wcywgSVN0YXRlPiB7XG4gICAgcHVibGljIHN0YXRpYyBjb250ZXh0VHlwZSA9IFJvb21Db250ZXh0O1xuICAgIHB1YmxpYyBkZWNsYXJlIGNvbnRleHQ6IFJlYWN0LkNvbnRleHRUeXBlPHR5cGVvZiBSb29tQ29udGV4dD47XG5cbiAgICBwcml2YXRlIHZpZGVvUmVmID0gUmVhY3QuY3JlYXRlUmVmPEhUTUxWaWRlb0VsZW1lbnQ+KCk7XG4gICAgcHJpdmF0ZSBzaXplV2F0Y2hlcj86IHN0cmluZztcblxuICAgIHB1YmxpYyBzdGF0ZSA9IHtcbiAgICAgICAgZmV0Y2hpbmdEYXRhOiBmYWxzZSxcbiAgICAgICAgZGVjcnlwdGVkVXJsOiBudWxsLFxuICAgICAgICBkZWNyeXB0ZWRUaHVtYm5haWxVcmw6IG51bGwsXG4gICAgICAgIGRlY3J5cHRlZEJsb2I6IG51bGwsXG4gICAgICAgIGVycm9yOiBudWxsLFxuICAgICAgICBwb3N0ZXJMb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgYmx1cmhhc2hVcmw6IG51bGwsXG4gICAgfTtcblxuICAgIHByaXZhdGUgZ2V0Q29udGVudFVybCgpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgICAgICBjb25zdCBjb250ZW50ID0gdGhpcy5wcm9wcy5teEV2ZW50LmdldENvbnRlbnQ8TWVkaWFFdmVudENvbnRlbnQ+KCk7XG4gICAgICAgIC8vIER1cmluZyBleHBvcnQsIHRoZSBjb250ZW50IHVybCB3aWxsIHBvaW50IHRvIHRoZSBNU0MsIHdoaWNoIHdpbGwgbGF0ZXIgcG9pbnQgdG8gYSBsb2NhbCB1cmxcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuZm9yRXhwb3J0KSByZXR1cm4gY29udGVudC5maWxlPy51cmwgPz8gY29udGVudC51cmw7XG4gICAgICAgIGNvbnN0IG1lZGlhID0gbWVkaWFGcm9tQ29udGVudChjb250ZW50KTtcbiAgICAgICAgaWYgKG1lZGlhLmlzRW5jcnlwdGVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZS5kZWNyeXB0ZWRVcmwgPz8gdW5kZWZpbmVkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG1lZGlhLnNyY0h0dHAgPz8gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBoYXNDb250ZW50VXJsKCk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCB1cmwgPSB0aGlzLmdldENvbnRlbnRVcmwoKTtcbiAgICAgICAgcmV0dXJuICEhdXJsICYmICF1cmwuc3RhcnRzV2l0aChcImRhdGE6XCIpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0VGh1bWJVcmwoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICAgIC8vIHRoZXJlJ3Mgbm8gbmVlZCBvZiB0aHVtYm5haWwgd2hlbiB0aGUgY29udGVudCBpcyBsb2NhbFxuICAgICAgICBpZiAodGhpcy5wcm9wcy5mb3JFeHBvcnQpIHJldHVybiBudWxsO1xuXG4gICAgICAgIGNvbnN0IGNvbnRlbnQgPSB0aGlzLnByb3BzLm14RXZlbnQuZ2V0Q29udGVudDxNZWRpYUV2ZW50Q29udGVudD4oKTtcbiAgICAgICAgY29uc3QgbWVkaWEgPSBtZWRpYUZyb21Db250ZW50KGNvbnRlbnQpO1xuXG4gICAgICAgIGlmIChtZWRpYS5pc0VuY3J5cHRlZCAmJiB0aGlzLnN0YXRlLmRlY3J5cHRlZFRodW1ibmFpbFVybCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGUuZGVjcnlwdGVkVGh1bWJuYWlsVXJsO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUucG9zdGVyTG9hZGluZykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGUuYmx1cmhhc2hVcmw7XG4gICAgICAgIH0gZWxzZSBpZiAobWVkaWEuaGFzVGh1bWJuYWlsKSB7XG4gICAgICAgICAgICByZXR1cm4gbWVkaWEudGh1bWJuYWlsSHR0cDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBsb2FkQmx1cmhhc2goKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGluZm8gPSB0aGlzLnByb3BzLm14RXZlbnQuZ2V0Q29udGVudCgpPy5pbmZvO1xuICAgICAgICBpZiAoIWluZm9bQkxVUkhBU0hfRklFTERdKSByZXR1cm47XG5cbiAgICAgICAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcblxuICAgICAgICBjb25zdCB7IHc6IHdpZHRoLCBoOiBoZWlnaHQgfSA9IHN1Z2dlc3RlZFZpZGVvU2l6ZShTZXR0aW5nc1N0b3JlLmdldFZhbHVlKFwiSW1hZ2VzLnNpemVcIikgYXMgSW1hZ2VTaXplLCB7XG4gICAgICAgICAgICB3OiBpbmZvLncsXG4gICAgICAgICAgICBoOiBpbmZvLmgsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgICAgICBjYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuXG4gICAgICAgIGNvbnN0IHBpeGVscyA9IGRlY29kZShpbmZvW0JMVVJIQVNIX0ZJRUxEXSwgd2lkdGgsIGhlaWdodCk7XG4gICAgICAgIGNvbnN0IGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIikhO1xuICAgICAgICBjb25zdCBpbWdEYXRhID0gY3R4LmNyZWF0ZUltYWdlRGF0YSh3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgaW1nRGF0YS5kYXRhLnNldChwaXhlbHMpO1xuICAgICAgICBjdHgucHV0SW1hZ2VEYXRhKGltZ0RhdGEsIDAsIDApO1xuXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgYmx1cmhhc2hVcmw6IGNhbnZhcy50b0RhdGFVUkwoKSxcbiAgICAgICAgICAgIHBvc3RlckxvYWRpbmc6IHRydWUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGNvbnRlbnQgPSB0aGlzLnByb3BzLm14RXZlbnQuZ2V0Q29udGVudDxNZWRpYUV2ZW50Q29udGVudD4oKTtcbiAgICAgICAgY29uc3QgbWVkaWEgPSBtZWRpYUZyb21Db250ZW50KGNvbnRlbnQpO1xuICAgICAgICBpZiAobWVkaWEuaGFzVGh1bWJuYWlsKSB7XG4gICAgICAgICAgICBjb25zdCBpbWFnZSA9IG5ldyBJbWFnZSgpO1xuICAgICAgICAgICAgaW1hZ2Uub25sb2FkID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBwb3N0ZXJMb2FkaW5nOiBmYWxzZSB9KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpbWFnZS5zcmMgPSBtZWRpYS50aHVtYm5haWxIdHRwITtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBjb21wb25lbnREaWRNb3VudCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5zaXplV2F0Y2hlciA9IFNldHRpbmdzU3RvcmUud2F0Y2hTZXR0aW5nKFwiSW1hZ2VzLnNpemVcIiwgbnVsbCwgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5mb3JjZVVwZGF0ZSgpOyAvLyB3ZSBkb24ndCByZWFsbHkgaGF2ZSBhIHJlbGlhYmxlIHRoaW5nIHRvIHVwZGF0ZSwgc28ganVzdCB1cGRhdGUgdGhlIHdob2xlIHRoaW5nXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLmxvYWRCbHVyaGFzaCgpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoXCJGYWlsZWQgdG8gbG9hZCBibHVyaGFzaFwiLCBlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnByb3BzLm1lZGlhRXZlbnRIZWxwZXI/Lm1lZGlhLmlzRW5jcnlwdGVkICYmIHRoaXMuc3RhdGUuZGVjcnlwdGVkVXJsID09PSBudWxsKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGF1dG9wbGF5ID0gU2V0dGluZ3NTdG9yZS5nZXRWYWx1ZShcImF1dG9wbGF5VmlkZW9cIikgYXMgYm9vbGVhbjtcbiAgICAgICAgICAgICAgICBjb25zdCB0aHVtYm5haWxVcmwgPSBhd2FpdCB0aGlzLnByb3BzLm1lZGlhRXZlbnRIZWxwZXIudGh1bWJuYWlsVXJsLnZhbHVlO1xuICAgICAgICAgICAgICAgIGlmIChhdXRvcGxheSkge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKFwiUHJlbG9hZGluZyB2aWRlb1wiKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWNyeXB0ZWRVcmw6IGF3YWl0IHRoaXMucHJvcHMubWVkaWFFdmVudEhlbHBlci5zb3VyY2VVcmwudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWNyeXB0ZWRUaHVtYm5haWxVcmw6IHRodW1ibmFpbFVybCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlY3J5cHRlZEJsb2I6IGF3YWl0IHRoaXMucHJvcHMubWVkaWFFdmVudEhlbHBlci5zb3VyY2VCbG9iLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vbkhlaWdodENoYW5nZWQ/LigpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coXCJOT1QgcHJlbG9hZGluZyB2aWRlb1wiKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29udGVudCA9IHRoaXMucHJvcHMubXhFdmVudC5nZXRDb250ZW50PE1lZGlhRXZlbnRDb250ZW50PigpO1xuXG4gICAgICAgICAgICAgICAgICAgIGxldCBtaW1ldHlwZSA9IGNvbnRlbnQ/LmluZm8/Lm1pbWV0eXBlO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIGNsb2JiZXIgcXVpY2t0aW1lIG11eGVkIGZpbGVzIHRvIGJlIGNvbnNpZGVyZWQgTVA0IHNvIGJyb3dzZXJzXG4gICAgICAgICAgICAgICAgICAgIC8vIGFyZSB3aWxsaW5nIHRvIHBsYXkgdGhlbVxuICAgICAgICAgICAgICAgICAgICBpZiAobWltZXR5cGUgPT0gXCJ2aWRlby9xdWlja3RpbWVcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWltZXR5cGUgPSBcInZpZGVvL21wNFwiO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGb3IgQ2hyb21lIGFuZCBFbGVjdHJvbiwgd2UgbmVlZCB0byBzZXQgc29tZSBub24tZW1wdHkgYHNyY2AgdG9cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVuYWJsZSB0aGUgcGxheSBidXR0b24uIEZpcmVmb3ggZG9lcyBub3Qgc2VlbSB0byBjYXJlIGVpdGhlclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2F5LCBzbyBpdCdzIGZpbmUgdG8gZG8gZm9yIGFsbCBicm93c2Vycy5cbiAgICAgICAgICAgICAgICAgICAgICAgIGRlY3J5cHRlZFVybDogYGRhdGE6JHttaW1ldHlwZX0sYCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlY3J5cHRlZFRodW1ibmFpbFVybDogdGh1bWJuYWlsVXJsIHx8IGBkYXRhOiR7bWltZXR5cGV9LGAsXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWNyeXB0ZWRCbG9iOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIud2FybihcIlVuYWJsZSB0byBkZWNyeXB0IGF0dGFjaG1lbnQ6IFwiLCBlcnIpO1xuICAgICAgICAgICAgICAgIC8vIFNldCBhIHBsYWNlaG9sZGVyIGltYWdlIHdoZW4gd2UgY2FuJ3QgZGVjcnlwdCB0aGUgaW1hZ2UuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yOiBlcnIsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcG9uZW50V2lsbFVubW91bnQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnNpemVXYXRjaGVyKSBTZXR0aW5nc1N0b3JlLnVud2F0Y2hTZXR0aW5nKHRoaXMuc2l6ZVdhdGNoZXIpO1xuICAgIH1cblxuICAgIHByaXZhdGUgdmlkZW9PblBsYXkgPSBhc3luYyAoKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgIGlmICh0aGlzLmhhc0NvbnRlbnRVcmwoKSB8fCB0aGlzLnN0YXRlLmZldGNoaW5nRGF0YSB8fCB0aGlzLnN0YXRlLmVycm9yKSB7XG4gICAgICAgICAgICAvLyBXZSBoYXZlIHRoZSBmaWxlLCB3ZSBhcmUgZmV0Y2hpbmcgdGhlIGZpbGUsIG9yIHRoZXJlIGlzIGFuIGVycm9yLlxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgLy8gVG8gc3RvcCBzdWJzZXF1ZW50IGRvd25sb2FkIGF0dGVtcHRzXG4gICAgICAgICAgICBmZXRjaGluZ0RhdGE6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIXRoaXMucHJvcHMubWVkaWFFdmVudEhlbHBlciEubWVkaWEuaXNFbmNyeXB0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIGVycm9yOiBcIk5vIGZpbGUgZ2l2ZW4gaW4gY29udGVudFwiLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRTdGF0ZShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBkZWNyeXB0ZWRVcmw6IGF3YWl0IHRoaXMucHJvcHMubWVkaWFFdmVudEhlbHBlciEuc291cmNlVXJsLnZhbHVlLFxuICAgICAgICAgICAgICAgIGRlY3J5cHRlZEJsb2I6IGF3YWl0IHRoaXMucHJvcHMubWVkaWFFdmVudEhlbHBlciEuc291cmNlQmxvYi52YWx1ZSxcbiAgICAgICAgICAgICAgICBmZXRjaGluZ0RhdGE6IGZhbHNlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMudmlkZW9SZWYuY3VycmVudCkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWYuY3VycmVudC5wbGF5KCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnByb3BzLm9uSGVpZ2h0Q2hhbmdlZD8uKCk7XG4gICAgfTtcblxuICAgIHByb3RlY3RlZCBnZXQgc2hvd0ZpbGVCb2R5KCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRpbWVsaW5lUmVuZGVyaW5nVHlwZSAhPT0gVGltZWxpbmVSZW5kZXJpbmdUeXBlLlJvb20gJiZcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50aW1lbGluZVJlbmRlcmluZ1R5cGUgIT09IFRpbWVsaW5lUmVuZGVyaW5nVHlwZS5QaW5uZWQgJiZcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50aW1lbGluZVJlbmRlcmluZ1R5cGUgIT09IFRpbWVsaW5lUmVuZGVyaW5nVHlwZS5TZWFyY2hcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldEZpbGVCb2R5ID0gKCk6IFJlYWN0Tm9kZSA9PiB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLmZvckV4cG9ydCkgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiB0aGlzLnNob3dGaWxlQm9keSAmJiA8TUZpbGVCb2R5IHsuLi50aGlzLnByb3BzfSBzaG93R2VuZXJpY1BsYWNlaG9sZGVyPXtmYWxzZX0gLz47XG4gICAgfTtcblxuICAgIHB1YmxpYyByZW5kZXIoKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgICAgICAgY29uc3QgY29udGVudCA9IHRoaXMucHJvcHMubXhFdmVudC5nZXRDb250ZW50KCk7XG4gICAgICAgIGNvbnN0IGF1dG9wbGF5ID0gIXRoaXMucHJvcHMuaW5oaWJpdEludGVyYWN0aW9uICYmIFNldHRpbmdzU3RvcmUuZ2V0VmFsdWUoXCJhdXRvcGxheVZpZGVvXCIpO1xuXG4gICAgICAgIGxldCBhc3BlY3RSYXRpbztcbiAgICAgICAgaWYgKGNvbnRlbnQuaW5mbz8udyAmJiBjb250ZW50LmluZm8/LmgpIHtcbiAgICAgICAgICAgIGFzcGVjdFJhdGlvID0gYCR7Y29udGVudC5pbmZvLnd9LyR7Y29udGVudC5pbmZvLmh9YDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IHc6IG1heFdpZHRoLCBoOiBtYXhIZWlnaHQgfSA9IHN1Z2dlc3RlZFZpZGVvU2l6ZShTZXR0aW5nc1N0b3JlLmdldFZhbHVlKFwiSW1hZ2VzLnNpemVcIikgYXMgSW1hZ2VTaXplLCB7XG4gICAgICAgICAgICB3OiBjb250ZW50LmluZm8/LncsXG4gICAgICAgICAgICBoOiBjb250ZW50LmluZm8/LmgsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEhBQ0s6IFRoaXMgZGl2IGZpbGxzIG91dCBzcGFjZSB3aGlsZSB0aGUgdmlkZW8gbG9hZHMsIHRvIHByZXZlbnQgc2Nyb2xsIGp1bXBzXG4gICAgICAgIGNvbnN0IHNwYWNlRmlsbGVyID0gPGRpdiBzdHlsZT17eyB3aWR0aDogbWF4V2lkdGgsIGhlaWdodDogbWF4SGVpZ2h0IH19IC8+O1xuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmVycm9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxNZWRpYVByb2Nlc3NpbmdFcnJvciBjbGFzc05hbWU9XCJteF9NVmlkZW9Cb2R5XCI+XG4gICAgICAgICAgICAgICAgICAgIHtfdChcInRpbWVsaW5lfG0udmlkZW98ZXJyb3JfZGVjcnlwdGluZ1wiKX1cbiAgICAgICAgICAgICAgICA8L01lZGlhUHJvY2Vzc2luZ0Vycm9yPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEltcG9ydGFudDogSWYgd2UgYXJlbid0IGF1dG9wbGF5aW5nIGFuZCB3ZSBoYXZlbid0IGRlY3J5cHRlZCBpdCB5ZXQsIHNob3cgYSB2aWRlbyB3aXRoIGEgcG9zdGVyLlxuICAgICAgICBpZiAoIXRoaXMucHJvcHMuZm9yRXhwb3J0ICYmIGNvbnRlbnQuZmlsZSAhPT0gdW5kZWZpbmVkICYmIHRoaXMuc3RhdGUuZGVjcnlwdGVkVXJsID09PSBudWxsICYmIGF1dG9wbGF5KSB7XG4gICAgICAgICAgICAvLyBOZWVkIHRvIGRlY3J5cHQgdGhlIGF0dGFjaG1lbnRcbiAgICAgICAgICAgIC8vIFRoZSBhdHRhY2htZW50IGlzIGRlY3J5cHRlZCBpbiBjb21wb25lbnREaWRNb3VudC5cbiAgICAgICAgICAgIC8vIEZvciBub3cgc2hvdyBhIHNwaW5uZXIuXG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cIm14X01WaWRlb0JvZHlcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9NVmlkZW9Cb2R5X2NvbnRhaW5lclwiIHN0eWxlPXt7IG1heFdpZHRoLCBtYXhIZWlnaHQsIGFzcGVjdFJhdGlvIH19PlxuICAgICAgICAgICAgICAgICAgICAgICAgPElubGluZVNwaW5uZXIgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIHtzcGFjZUZpbGxlcn1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29udGVudFVybCA9IHRoaXMuZ2V0Q29udGVudFVybCgpO1xuICAgICAgICBjb25zdCB0aHVtYlVybCA9IHRoaXMuZ2V0VGh1bWJVcmwoKTtcbiAgICAgICAgbGV0IHBvc3Rlcjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgICBsZXQgcHJlbG9hZCA9IFwibWV0YWRhdGFcIjtcbiAgICAgICAgaWYgKGNvbnRlbnQuaW5mbyAmJiB0aHVtYlVybCkge1xuICAgICAgICAgICAgcG9zdGVyID0gdGh1bWJVcmw7XG4gICAgICAgICAgICBwcmVsb2FkID0gXCJub25lXCI7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmaWxlQm9keSA9IHRoaXMuZ2V0RmlsZUJvZHkoKTtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cIm14X01WaWRlb0JvZHlcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X01WaWRlb0JvZHlfY29udGFpbmVyXCIgc3R5bGU9e3sgbWF4V2lkdGgsIG1heEhlaWdodCwgYXNwZWN0UmF0aW8gfX0+XG4gICAgICAgICAgICAgICAgICAgIDx2aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfTVZpZGVvQm9keVwiXG4gICAgICAgICAgICAgICAgICAgICAgICByZWY9e3RoaXMudmlkZW9SZWZ9XG4gICAgICAgICAgICAgICAgICAgICAgICBzcmM9e2NvbnRlbnRVcmx9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT17Y29udGVudC5ib2R5fVxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbHM9eyF0aGlzLnByb3BzLmluaGliaXRJbnRlcmFjdGlvbn1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIERpc2FibGUgZG93bmxvYWRpbmcgYXMgaXQgZG9lc24ndCB3b3JrIHdpdGggZTJlZSB2aWRlbyxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHVzZXJzIHNob3VsZCB1c2UgdGhlIGRlZGljYXRlZCBEb3dubG9hZCBidXR0b24gaW4gdGhlIE1lc3NhZ2UgQWN0aW9uIEJhclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbHNMaXN0PVwibm9kb3dubG9hZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBwcmVsb2FkPXtwcmVsb2FkfVxuICAgICAgICAgICAgICAgICAgICAgICAgbXV0ZWQ9e2F1dG9wbGF5fVxuICAgICAgICAgICAgICAgICAgICAgICAgYXV0b1BsYXk9e2F1dG9wbGF5fVxuICAgICAgICAgICAgICAgICAgICAgICAgcG9zdGVyPXtwb3N0ZXJ9XG4gICAgICAgICAgICAgICAgICAgICAgICBvblBsYXk9e3RoaXMudmlkZW9PblBsYXl9XG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIHtzcGFjZUZpbGxlcn1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB7ZmlsZUJvZHl9XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICk7XG4gICAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFRQSxJQUFBQSxNQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxTQUFBLEdBQUFELE9BQUE7QUFFQSxJQUFBRSxPQUFBLEdBQUFGLE9BQUE7QUFFQSxJQUFBRyxnQkFBQSxHQUFBSCxPQUFBO0FBQ0EsSUFBQUksY0FBQSxHQUFBTCxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUssY0FBQSxHQUFBTixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQU0sTUFBQSxHQUFBTixPQUFBO0FBQ0EsSUFBQU8sV0FBQSxHQUFBUCxPQUFBO0FBRUEsSUFBQVEsVUFBQSxHQUFBVCxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQVMsVUFBQSxHQUFBVCxPQUFBO0FBQ0EsSUFBQVUsWUFBQSxHQUFBQyx1QkFBQSxDQUFBWCxPQUFBO0FBQ0EsSUFBQVkscUJBQUEsR0FBQWIsc0JBQUEsQ0FBQUMsT0FBQTtBQUFpRSxTQUFBYSx5QkFBQUMsQ0FBQSw2QkFBQUMsT0FBQSxtQkFBQUMsQ0FBQSxPQUFBRCxPQUFBLElBQUFFLENBQUEsT0FBQUYsT0FBQSxZQUFBRix3QkFBQSxZQUFBQSxDQUFBQyxDQUFBLFdBQUFBLENBQUEsR0FBQUcsQ0FBQSxHQUFBRCxDQUFBLEtBQUFGLENBQUE7QUFBQSxTQUFBSCx3QkFBQUcsQ0FBQSxFQUFBRSxDQUFBLFNBQUFBLENBQUEsSUFBQUYsQ0FBQSxJQUFBQSxDQUFBLENBQUFJLFVBQUEsU0FBQUosQ0FBQSxlQUFBQSxDQUFBLHVCQUFBQSxDQUFBLHlCQUFBQSxDQUFBLFdBQUFLLE9BQUEsRUFBQUwsQ0FBQSxRQUFBRyxDQUFBLEdBQUFKLHdCQUFBLENBQUFHLENBQUEsT0FBQUMsQ0FBQSxJQUFBQSxDQUFBLENBQUFHLEdBQUEsQ0FBQU4sQ0FBQSxVQUFBRyxDQUFBLENBQUFJLEdBQUEsQ0FBQVAsQ0FBQSxPQUFBUSxDQUFBLEtBQUFDLFNBQUEsVUFBQUMsQ0FBQSxHQUFBQyxNQUFBLENBQUFDLGNBQUEsSUFBQUQsTUFBQSxDQUFBRSx3QkFBQSxXQUFBQyxDQUFBLElBQUFkLENBQUEsb0JBQUFjLENBQUEsT0FBQUMsY0FBQSxDQUFBQyxJQUFBLENBQUFoQixDQUFBLEVBQUFjLENBQUEsU0FBQUcsQ0FBQSxHQUFBUCxDQUFBLEdBQUFDLE1BQUEsQ0FBQUUsd0JBQUEsQ0FBQWIsQ0FBQSxFQUFBYyxDQUFBLFVBQUFHLENBQUEsS0FBQUEsQ0FBQSxDQUFBVixHQUFBLElBQUFVLENBQUEsQ0FBQUMsR0FBQSxJQUFBUCxNQUFBLENBQUFDLGNBQUEsQ0FBQUosQ0FBQSxFQUFBTSxDQUFBLEVBQUFHLENBQUEsSUFBQVQsQ0FBQSxDQUFBTSxDQUFBLElBQUFkLENBQUEsQ0FBQWMsQ0FBQSxZQUFBTixDQUFBLENBQUFILE9BQUEsR0FBQUwsQ0FBQSxFQUFBRyxDQUFBLElBQUFBLENBQUEsQ0FBQWUsR0FBQSxDQUFBbEIsQ0FBQSxFQUFBUSxDQUFBLEdBQUFBLENBQUE7QUF0QmpFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQTRCZSxNQUFNVyxVQUFVLFNBQVNDLGNBQUssQ0FBQ0MsYUFBYSxDQUFxQjtFQUFBQyxZQUFBLEdBQUFDLElBQUE7SUFBQSxTQUFBQSxJQUFBO0lBQUEsSUFBQUMsZ0JBQUEsQ0FBQW5CLE9BQUEsaUNBSXpEZSxjQUFLLENBQUNLLFNBQVMsQ0FBbUIsQ0FBQztJQUFBLElBQUFELGdCQUFBLENBQUFuQixPQUFBO0lBQUEsSUFBQW1CLGdCQUFBLENBQUFuQixPQUFBLGlCQUd2QztNQUNYcUIsWUFBWSxFQUFFLEtBQUs7TUFDbkJDLFlBQVksRUFBRSxJQUFJO01BQ2xCQyxxQkFBcUIsRUFBRSxJQUFJO01BQzNCQyxhQUFhLEVBQUUsSUFBSTtNQUNuQkMsS0FBSyxFQUFFLElBQUk7TUFDWEMsYUFBYSxFQUFFLEtBQUs7TUFDcEJDLFdBQVcsRUFBRTtJQUNqQixDQUFDO0lBQUEsSUFBQVIsZ0JBQUEsQ0FBQW5CLE9BQUEsdUJBbUlxQixZQUEyQjtNQUM3QyxJQUFJLElBQUksQ0FBQzRCLGFBQWEsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDQyxLQUFLLENBQUNSLFlBQVksSUFBSSxJQUFJLENBQUNRLEtBQUssQ0FBQ0osS0FBSyxFQUFFO1FBQ3JFO1FBQ0E7TUFDSjtNQUNBLElBQUksQ0FBQ0ssUUFBUSxDQUFDO1FBQ1Y7UUFDQVQsWUFBWSxFQUFFO01BQ2xCLENBQUMsQ0FBQztNQUNGLElBQUksQ0FBQyxJQUFJLENBQUNVLEtBQUssQ0FBQ0MsZ0JBQWdCLENBQUVDLEtBQUssQ0FBQ0MsV0FBVyxFQUFFO1FBQ2pELElBQUksQ0FBQ0osUUFBUSxDQUFDO1VBQ1ZMLEtBQUssRUFBRTtRQUNYLENBQUMsQ0FBQztRQUNGO01BQ0o7TUFDQSxJQUFJLENBQUNLLFFBQVEsQ0FDVDtRQUNJUixZQUFZLEVBQUUsTUFBTSxJQUFJLENBQUNTLEtBQUssQ0FBQ0MsZ0JBQWdCLENBQUVHLFNBQVMsQ0FBQ0MsS0FBSztRQUNoRVosYUFBYSxFQUFFLE1BQU0sSUFBSSxDQUFDTyxLQUFLLENBQUNDLGdCQUFnQixDQUFFSyxVQUFVLENBQUNELEtBQUs7UUFDbEVmLFlBQVksRUFBRTtNQUNsQixDQUFDLEVBQ0QsTUFBTTtRQUNGLElBQUksQ0FBQyxJQUFJLENBQUNpQixRQUFRLENBQUNDLE9BQU8sRUFBRTtRQUM1QixJQUFJLENBQUNELFFBQVEsQ0FBQ0MsT0FBTyxDQUFDQyxJQUFJLENBQUMsQ0FBQztNQUNoQyxDQUNKLENBQUM7TUFDRCxJQUFJLENBQUNULEtBQUssQ0FBQ1UsZUFBZSxHQUFHLENBQUM7SUFDbEMsQ0FBQztJQUFBLElBQUF0QixnQkFBQSxDQUFBbkIsT0FBQSx1QkFVcUIsTUFBaUI7TUFDbkMsSUFBSSxJQUFJLENBQUMrQixLQUFLLENBQUNXLFNBQVMsRUFBRSxPQUFPLElBQUk7TUFDckMsT0FBTyxJQUFJLENBQUNDLFlBQVksaUJBQUloRSxNQUFBLENBQUFxQixPQUFBLENBQUE0QyxhQUFBLENBQUN2RCxVQUFBLENBQUFXLE9BQVMsTUFBQTZDLFNBQUEsQ0FBQTdDLE9BQUEsTUFBSyxJQUFJLENBQUMrQixLQUFLO1FBQUVlLHNCQUFzQixFQUFFO01BQU0sRUFBRSxDQUFDO0lBQzVGLENBQUM7RUFBQTtFQXpLT0MsYUFBYUEsQ0FBQSxFQUF1QjtJQUN4QyxNQUFNQyxPQUFPLEdBQUcsSUFBSSxDQUFDakIsS0FBSyxDQUFDa0IsT0FBTyxDQUFDQyxVQUFVLENBQW9CLENBQUM7SUFDbEU7SUFDQSxJQUFJLElBQUksQ0FBQ25CLEtBQUssQ0FBQ1csU0FBUyxFQUFFLE9BQU9NLE9BQU8sQ0FBQ0csSUFBSSxFQUFFQyxHQUFHLElBQUlKLE9BQU8sQ0FBQ0ksR0FBRztJQUNqRSxNQUFNbkIsS0FBSyxHQUFHLElBQUFvQix1QkFBZ0IsRUFBQ0wsT0FBTyxDQUFDO0lBQ3ZDLElBQUlmLEtBQUssQ0FBQ0MsV0FBVyxFQUFFO01BQ25CLE9BQU8sSUFBSSxDQUFDTCxLQUFLLENBQUNQLFlBQVksSUFBSWdDLFNBQVM7SUFDL0MsQ0FBQyxNQUFNO01BQ0gsT0FBT3JCLEtBQUssQ0FBQ3NCLE9BQU8sSUFBSUQsU0FBUztJQUNyQztFQUNKO0VBRVExQixhQUFhQSxDQUFBLEVBQVk7SUFDN0IsTUFBTXdCLEdBQUcsR0FBRyxJQUFJLENBQUNMLGFBQWEsQ0FBQyxDQUFDO0lBQ2hDLE9BQU8sQ0FBQyxDQUFDSyxHQUFHLElBQUksQ0FBQ0EsR0FBRyxDQUFDSSxVQUFVLENBQUMsT0FBTyxDQUFDO0VBQzVDO0VBRVFDLFdBQVdBLENBQUEsRUFBa0I7SUFDakM7SUFDQSxJQUFJLElBQUksQ0FBQzFCLEtBQUssQ0FBQ1csU0FBUyxFQUFFLE9BQU8sSUFBSTtJQUVyQyxNQUFNTSxPQUFPLEdBQUcsSUFBSSxDQUFDakIsS0FBSyxDQUFDa0IsT0FBTyxDQUFDQyxVQUFVLENBQW9CLENBQUM7SUFDbEUsTUFBTWpCLEtBQUssR0FBRyxJQUFBb0IsdUJBQWdCLEVBQUNMLE9BQU8sQ0FBQztJQUV2QyxJQUFJZixLQUFLLENBQUNDLFdBQVcsSUFBSSxJQUFJLENBQUNMLEtBQUssQ0FBQ04scUJBQXFCLEVBQUU7TUFDdkQsT0FBTyxJQUFJLENBQUNNLEtBQUssQ0FBQ04scUJBQXFCO0lBQzNDLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQ00sS0FBSyxDQUFDSCxhQUFhLEVBQUU7TUFDakMsT0FBTyxJQUFJLENBQUNHLEtBQUssQ0FBQ0YsV0FBVztJQUNqQyxDQUFDLE1BQU0sSUFBSU0sS0FBSyxDQUFDeUIsWUFBWSxFQUFFO01BQzNCLE9BQU96QixLQUFLLENBQUMwQixhQUFhO0lBQzlCLENBQUMsTUFBTTtNQUNILE9BQU8sSUFBSTtJQUNmO0VBQ0o7RUFFUUMsWUFBWUEsQ0FBQSxFQUFTO0lBQ3pCLE1BQU1DLElBQUksR0FBRyxJQUFJLENBQUM5QixLQUFLLENBQUNrQixPQUFPLENBQUNDLFVBQVUsQ0FBQyxDQUFDLEVBQUVXLElBQUk7SUFDbEQsSUFBSSxDQUFDQSxJQUFJLENBQUNDLDBCQUFjLENBQUMsRUFBRTtJQUUzQixNQUFNQyxNQUFNLEdBQUdDLFFBQVEsQ0FBQ3BCLGFBQWEsQ0FBQyxRQUFRLENBQUM7SUFFL0MsTUFBTTtNQUFFcUIsQ0FBQyxFQUFFQyxLQUFLO01BQUVDLENBQUMsRUFBRUM7SUFBTyxDQUFDLEdBQUcsSUFBQUMsd0JBQWtCLEVBQUNDLHNCQUFhLENBQUNDLFFBQVEsQ0FBQyxhQUFhLENBQUMsRUFBZTtNQUNuR04sQ0FBQyxFQUFFSixJQUFJLENBQUNJLENBQUM7TUFDVEUsQ0FBQyxFQUFFTixJQUFJLENBQUNNO0lBQ1osQ0FBQyxDQUFDO0lBRUZKLE1BQU0sQ0FBQ0csS0FBSyxHQUFHQSxLQUFLO0lBQ3BCSCxNQUFNLENBQUNLLE1BQU0sR0FBR0EsTUFBTTtJQUV0QixNQUFNSSxNQUFNLEdBQUcsSUFBQUMsZ0JBQU0sRUFBQ1osSUFBSSxDQUFDQywwQkFBYyxDQUFDLEVBQUVJLEtBQUssRUFBRUUsTUFBTSxDQUFDO0lBQzFELE1BQU1NLEdBQUcsR0FBR1gsTUFBTSxDQUFDWSxVQUFVLENBQUMsSUFBSSxDQUFFO0lBQ3BDLE1BQU1DLE9BQU8sR0FBR0YsR0FBRyxDQUFDRyxlQUFlLENBQUNYLEtBQUssRUFBRUUsTUFBTSxDQUFDO0lBQ2xEUSxPQUFPLENBQUNFLElBQUksQ0FBQ2pFLEdBQUcsQ0FBQzJELE1BQU0sQ0FBQztJQUN4QkUsR0FBRyxDQUFDSyxZQUFZLENBQUNILE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBRS9CLElBQUksQ0FBQzlDLFFBQVEsQ0FBQztNQUNWSCxXQUFXLEVBQUVvQyxNQUFNLENBQUNpQixTQUFTLENBQUMsQ0FBQztNQUMvQnRELGFBQWEsRUFBRTtJQUNuQixDQUFDLENBQUM7SUFFRixNQUFNc0IsT0FBTyxHQUFHLElBQUksQ0FBQ2pCLEtBQUssQ0FBQ2tCLE9BQU8sQ0FBQ0MsVUFBVSxDQUFvQixDQUFDO0lBQ2xFLE1BQU1qQixLQUFLLEdBQUcsSUFBQW9CLHVCQUFnQixFQUFDTCxPQUFPLENBQUM7SUFDdkMsSUFBSWYsS0FBSyxDQUFDeUIsWUFBWSxFQUFFO01BQ3BCLE1BQU11QixLQUFLLEdBQUcsSUFBSUMsS0FBSyxDQUFDLENBQUM7TUFDekJELEtBQUssQ0FBQ0UsTUFBTSxHQUFHLE1BQU07UUFDakIsSUFBSSxDQUFDckQsUUFBUSxDQUFDO1VBQUVKLGFBQWEsRUFBRTtRQUFNLENBQUMsQ0FBQztNQUMzQyxDQUFDO01BQ0R1RCxLQUFLLENBQUNHLEdBQUcsR0FBR25ELEtBQUssQ0FBQzBCLGFBQWM7SUFDcEM7RUFDSjtFQUVBLE1BQWEwQixpQkFBaUJBLENBQUEsRUFBa0I7SUFDNUMsSUFBSSxDQUFDQyxXQUFXLEdBQUdoQixzQkFBYSxDQUFDaUIsWUFBWSxDQUFDLGFBQWEsRUFBRSxJQUFJLEVBQUUsTUFBTTtNQUNyRSxJQUFJLENBQUNDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN4QixDQUFDLENBQUM7SUFFRixJQUFJO01BQ0EsSUFBSSxDQUFDNUIsWUFBWSxDQUFDLENBQUM7SUFDdkIsQ0FBQyxDQUFDLE9BQU9qRSxDQUFDLEVBQUU7TUFDUjhGLGNBQU0sQ0FBQ2hFLEtBQUssQ0FBQyx5QkFBeUIsRUFBRTlCLENBQUMsQ0FBQztJQUM5QztJQUVBLElBQUksSUFBSSxDQUFDb0MsS0FBSyxDQUFDQyxnQkFBZ0IsRUFBRUMsS0FBSyxDQUFDQyxXQUFXLElBQUksSUFBSSxDQUFDTCxLQUFLLENBQUNQLFlBQVksS0FBSyxJQUFJLEVBQUU7TUFDcEYsSUFBSTtRQUNBLE1BQU1vRSxRQUFRLEdBQUdwQixzQkFBYSxDQUFDQyxRQUFRLENBQUMsZUFBZSxDQUFZO1FBQ25FLE1BQU1vQixZQUFZLEdBQUcsTUFBTSxJQUFJLENBQUM1RCxLQUFLLENBQUNDLGdCQUFnQixDQUFDMkQsWUFBWSxDQUFDdkQsS0FBSztRQUN6RSxJQUFJc0QsUUFBUSxFQUFFO1VBQ1ZELGNBQU0sQ0FBQ0csR0FBRyxDQUFDLGtCQUFrQixDQUFDO1VBQzlCLElBQUksQ0FBQzlELFFBQVEsQ0FBQztZQUNWUixZQUFZLEVBQUUsTUFBTSxJQUFJLENBQUNTLEtBQUssQ0FBQ0MsZ0JBQWdCLENBQUNHLFNBQVMsQ0FBQ0MsS0FBSztZQUMvRGIscUJBQXFCLEVBQUVvRSxZQUFZO1lBQ25DbkUsYUFBYSxFQUFFLE1BQU0sSUFBSSxDQUFDTyxLQUFLLENBQUNDLGdCQUFnQixDQUFDSyxVQUFVLENBQUNEO1VBQ2hFLENBQUMsQ0FBQztVQUNGLElBQUksQ0FBQ0wsS0FBSyxDQUFDVSxlQUFlLEdBQUcsQ0FBQztRQUNsQyxDQUFDLE1BQU07VUFDSGdELGNBQU0sQ0FBQ0csR0FBRyxDQUFDLHNCQUFzQixDQUFDO1VBQ2xDLE1BQU01QyxPQUFPLEdBQUcsSUFBSSxDQUFDakIsS0FBSyxDQUFDa0IsT0FBTyxDQUFDQyxVQUFVLENBQW9CLENBQUM7VUFFbEUsSUFBSTJDLFFBQVEsR0FBRzdDLE9BQU8sRUFBRWEsSUFBSSxFQUFFZ0MsUUFBUTs7VUFFdEM7VUFDQTtVQUNBLElBQUlBLFFBQVEsSUFBSSxpQkFBaUIsRUFBRTtZQUMvQkEsUUFBUSxHQUFHLFdBQVc7VUFDMUI7VUFFQSxJQUFJLENBQUMvRCxRQUFRLENBQUM7WUFDVjtZQUNBO1lBQ0E7WUFDQVIsWUFBWSxFQUFFLFFBQVF1RSxRQUFRLEdBQUc7WUFDakN0RSxxQkFBcUIsRUFBRW9FLFlBQVksSUFBSSxRQUFRRSxRQUFRLEdBQUc7WUFDMURyRSxhQUFhLEVBQUU7VUFDbkIsQ0FBQyxDQUFDO1FBQ047TUFDSixDQUFDLENBQUMsT0FBT3NFLEdBQUcsRUFBRTtRQUNWTCxjQUFNLENBQUNNLElBQUksQ0FBQyxnQ0FBZ0MsRUFBRUQsR0FBRyxDQUFDO1FBQ2xEO1FBQ0EsSUFBSSxDQUFDaEUsUUFBUSxDQUFDO1VBQ1ZMLEtBQUssRUFBRXFFO1FBQ1gsQ0FBQyxDQUFDO01BQ047SUFDSjtFQUNKO0VBRU9FLG9CQUFvQkEsQ0FBQSxFQUFTO0lBQ2hDLElBQUksSUFBSSxDQUFDVixXQUFXLEVBQUVoQixzQkFBYSxDQUFDMkIsY0FBYyxDQUFDLElBQUksQ0FBQ1gsV0FBVyxDQUFDO0VBQ3hFO0VBK0JBLElBQWMzQyxZQUFZQSxDQUFBLEVBQVk7SUFDbEMsT0FDSSxJQUFJLENBQUN1RCxPQUFPLENBQUNDLHFCQUFxQixLQUFLQyxrQ0FBcUIsQ0FBQ0MsSUFBSSxJQUNqRSxJQUFJLENBQUNILE9BQU8sQ0FBQ0MscUJBQXFCLEtBQUtDLGtDQUFxQixDQUFDRSxNQUFNLElBQ25FLElBQUksQ0FBQ0osT0FBTyxDQUFDQyxxQkFBcUIsS0FBS0Msa0NBQXFCLENBQUNHLE1BQU07RUFFM0U7RUFPT0MsTUFBTUEsQ0FBQSxFQUFvQjtJQUM3QixNQUFNeEQsT0FBTyxHQUFHLElBQUksQ0FBQ2pCLEtBQUssQ0FBQ2tCLE9BQU8sQ0FBQ0MsVUFBVSxDQUFDLENBQUM7SUFDL0MsTUFBTXdDLFFBQVEsR0FBRyxDQUFDLElBQUksQ0FBQzNELEtBQUssQ0FBQzBFLGtCQUFrQixJQUFJbkMsc0JBQWEsQ0FBQ0MsUUFBUSxDQUFDLGVBQWUsQ0FBQztJQUUxRixJQUFJbUMsV0FBVztJQUNmLElBQUkxRCxPQUFPLENBQUNhLElBQUksRUFBRUksQ0FBQyxJQUFJakIsT0FBTyxDQUFDYSxJQUFJLEVBQUVNLENBQUMsRUFBRTtNQUNwQ3VDLFdBQVcsR0FBRyxHQUFHMUQsT0FBTyxDQUFDYSxJQUFJLENBQUNJLENBQUMsSUFBSWpCLE9BQU8sQ0FBQ2EsSUFBSSxDQUFDTSxDQUFDLEVBQUU7SUFDdkQ7SUFDQSxNQUFNO01BQUVGLENBQUMsRUFBRTBDLFFBQVE7TUFBRXhDLENBQUMsRUFBRXlDO0lBQVUsQ0FBQyxHQUFHLElBQUF2Qyx3QkFBa0IsRUFBQ0Msc0JBQWEsQ0FBQ0MsUUFBUSxDQUFDLGFBQWEsQ0FBQyxFQUFlO01BQ3pHTixDQUFDLEVBQUVqQixPQUFPLENBQUNhLElBQUksRUFBRUksQ0FBQztNQUNsQkUsQ0FBQyxFQUFFbkIsT0FBTyxDQUFDYSxJQUFJLEVBQUVNO0lBQ3JCLENBQUMsQ0FBQzs7SUFFRjtJQUNBLE1BQU0wQyxXQUFXLGdCQUFHbEksTUFBQSxDQUFBcUIsT0FBQSxDQUFBNEMsYUFBQTtNQUFLa0UsS0FBSyxFQUFFO1FBQUU1QyxLQUFLLEVBQUV5QyxRQUFRO1FBQUV2QyxNQUFNLEVBQUV3QztNQUFVO0lBQUUsQ0FBRSxDQUFDO0lBRTFFLElBQUksSUFBSSxDQUFDL0UsS0FBSyxDQUFDSixLQUFLLEtBQUssSUFBSSxFQUFFO01BQzNCLG9CQUNJOUMsTUFBQSxDQUFBcUIsT0FBQSxDQUFBNEMsYUFBQSxDQUFDbkQscUJBQUEsQ0FBQU8sT0FBb0I7UUFBQytHLFNBQVMsRUFBQztNQUFlLEdBQzFDLElBQUFDLG1CQUFFLEVBQUMsbUNBQW1DLENBQ3JCLENBQUM7SUFFL0I7O0lBRUE7SUFDQSxJQUFJLENBQUMsSUFBSSxDQUFDakYsS0FBSyxDQUFDVyxTQUFTLElBQUlNLE9BQU8sQ0FBQ0csSUFBSSxLQUFLRyxTQUFTLElBQUksSUFBSSxDQUFDekIsS0FBSyxDQUFDUCxZQUFZLEtBQUssSUFBSSxJQUFJb0UsUUFBUSxFQUFFO01BQ3JHO01BQ0E7TUFDQTtNQUNBLG9CQUNJL0csTUFBQSxDQUFBcUIsT0FBQSxDQUFBNEMsYUFBQTtRQUFNbUUsU0FBUyxFQUFDO01BQWUsZ0JBQzNCcEksTUFBQSxDQUFBcUIsT0FBQSxDQUFBNEMsYUFBQTtRQUFLbUUsU0FBUyxFQUFDLHlCQUF5QjtRQUFDRCxLQUFLLEVBQUU7VUFBRUgsUUFBUTtVQUFFQyxTQUFTO1VBQUVGO1FBQVk7TUFBRSxnQkFDakYvSCxNQUFBLENBQUFxQixPQUFBLENBQUE0QyxhQUFBLENBQUMxRCxjQUFBLENBQUFjLE9BQWEsTUFBRSxDQUNmLENBQUMsRUFDTDZHLFdBQ0MsQ0FBQztJQUVmO0lBRUEsTUFBTUksVUFBVSxHQUFHLElBQUksQ0FBQ2xFLGFBQWEsQ0FBQyxDQUFDO0lBQ3ZDLE1BQU1tRSxRQUFRLEdBQUcsSUFBSSxDQUFDekQsV0FBVyxDQUFDLENBQUM7SUFDbkMsSUFBSTBELE1BQTBCO0lBQzlCLElBQUlDLE9BQU8sR0FBRyxVQUFVO0lBQ3hCLElBQUlwRSxPQUFPLENBQUNhLElBQUksSUFBSXFELFFBQVEsRUFBRTtNQUMxQkMsTUFBTSxHQUFHRCxRQUFRO01BQ2pCRSxPQUFPLEdBQUcsTUFBTTtJQUNwQjtJQUVBLE1BQU1DLFFBQVEsR0FBRyxJQUFJLENBQUNDLFdBQVcsQ0FBQyxDQUFDO0lBQ25DLG9CQUNJM0ksTUFBQSxDQUFBcUIsT0FBQSxDQUFBNEMsYUFBQTtNQUFNbUUsU0FBUyxFQUFDO0lBQWUsZ0JBQzNCcEksTUFBQSxDQUFBcUIsT0FBQSxDQUFBNEMsYUFBQTtNQUFLbUUsU0FBUyxFQUFDLHlCQUF5QjtNQUFDRCxLQUFLLEVBQUU7UUFBRUgsUUFBUTtRQUFFQyxTQUFTO1FBQUVGO01BQVk7SUFBRSxnQkFDakYvSCxNQUFBLENBQUFxQixPQUFBLENBQUE0QyxhQUFBO01BQ0ltRSxTQUFTLEVBQUMsZUFBZTtNQUN6QlEsR0FBRyxFQUFFLElBQUksQ0FBQ2pGLFFBQVM7TUFDbkI4QyxHQUFHLEVBQUU2QixVQUFXO01BQ2hCTyxLQUFLLEVBQUV4RSxPQUFPLENBQUN5RSxJQUFLO01BQ3BCQyxRQUFRLEVBQUUsQ0FBQyxJQUFJLENBQUMzRixLQUFLLENBQUMwRTtNQUN0QjtNQUNBO01BQUE7TUFDQWtCLFlBQVksRUFBQyxZQUFZO01BQ3pCUCxPQUFPLEVBQUVBLE9BQVE7TUFDakJRLEtBQUssRUFBRWxDLFFBQVM7TUFDaEJtQyxRQUFRLEVBQUVuQyxRQUFTO01BQ25CeUIsTUFBTSxFQUFFQSxNQUFPO01BQ2ZXLE1BQU0sRUFBRSxJQUFJLENBQUNDO0lBQVksQ0FDNUIsQ0FBQyxFQUNEbEIsV0FDQSxDQUFDLEVBQ0xRLFFBQ0MsQ0FBQztFQUVmO0FBQ0o7QUFBQ1csT0FBQSxDQUFBaEksT0FBQSxHQUFBYyxVQUFBO0FBQUEsSUFBQUssZ0JBQUEsQ0FBQW5CLE9BQUEsRUFyUW9CYyxVQUFVLGlCQUNDbUgsb0JBQVciLCJpZ25vcmVMaXN0IjpbXX0=