UNPKG

@nota/nativescript-webview-ext

Version:

Extended WebView for NativeScript which adds 'x-local' scheme for local-files. events between WebView and native-layer, javascript execution, injecting CSS and JS-files.

687 lines 88.7 kB
"use strict"; function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); var fs = require("@nativescript/core/file-system"); var profiling_1 = require("@nativescript/core/profiling"); var view_1 = require("@nativescript/core/ui/core/view"); var dialogs_1 = require("@nativescript/core/ui/dialogs"); var nativescript_webview_bridge_loader_1 = require("./nativescript-webview-bridge-loader"); var webview_ext_common_1 = require("./webview-ext-common"); __export(require("./webview-ext-common")); var WebViewExt = (function (_super) { __extends(WebViewExt, _super); function WebViewExt() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.wkNamedUserScripts = []; _this.viewPortSize = { initialScale: 1.0 }; return _this; } Object.defineProperty(WebViewExt.prototype, "ios", { get: function () { return this.nativeViewProtected; }, enumerable: true, configurable: true }); Object.defineProperty(WebViewExt, "supportXLocalScheme", { get: function () { return typeof CustomUrlSchemeHandler !== "undefined"; }, enumerable: true, configurable: true }); Object.defineProperty(WebViewExt.prototype, "supportXLocalScheme", { get: function () { return typeof CustomUrlSchemeHandler !== "undefined"; }, enumerable: true, configurable: true }); WebViewExt.prototype.createNativeView = function () { var configuration = WKWebViewConfiguration.new(); configuration.dataDetectorTypes = -1; this.wkWebViewConfiguration = configuration; var messageHandler = WKScriptMessageHandlerNotaImpl.initWithOwner(new WeakRef(this)); var wkUController = (this.wkUserContentController = WKUserContentController.new()); wkUController.addScriptMessageHandlerName(messageHandler, "nsBridge"); configuration.userContentController = wkUController; configuration.preferences.setValueForKey(true, "allowFileAccessFromFileURLs"); configuration.setValueForKey(true, "allowUniversalAccessFromFileURLs"); if (this.supportXLocalScheme) { this.wkCustomUrlSchemeHandler = new CustomUrlSchemeHandler(); configuration.setURLSchemeHandlerForURLScheme(this.wkCustomUrlSchemeHandler, this.interceptScheme); } var webview = new WKWebView({ frame: CGRectZero, configuration: configuration, }); return webview; }; WebViewExt.prototype.initNativeView = function () { _super.prototype.initNativeView.call(this); this.wkNavigationDelegate = WKNavigationDelegateNotaImpl.initWithOwner(new WeakRef(this)); this.wkUIDelegate = WKUIDelegateNotaImpl.initWithOwner(new WeakRef(this)); this.loadWKUserScripts(); }; WebViewExt.prototype.disposeNativeView = function () { this.wkNavigationDelegate = null; this.wkCustomUrlSchemeHandler = null; this.wkUIDelegate = null; _super.prototype.disposeNativeView.call(this); }; WebViewExt.prototype.injectWebViewBridge = function () { return this.ensurePolyfills(); }; WebViewExt.prototype.injectViewPortMeta = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: this.resetViewPortCode(); if (this.supportXLocalScheme) { return [2]; } return [4, _super.prototype.injectViewPortMeta.call(this)]; case 1: return [2, _a.sent()]; } }); }); }; WebViewExt.prototype.executeJavaScript = function (scriptCode, stringifyResult) { if (stringifyResult === void 0) { stringifyResult = true; } return __awaiter(this, void 0, void 0, function () { var nativeView, rawResult, result, r, error; return __generator(this, function (_a) { switch (_a.label) { case 0: if (stringifyResult) { scriptCode = "\n (function(window) {\n var result = null;\n\n try {\n result = " + scriptCode.trim() + ";\n } catch (err) {\n return JSON.stringify({\n error: true,\n message: err.message,\n stack: err.stack\n });\n }\n\n try {\n return JSON.stringify(result);\n } catch (err) {\n return result;\n }\n })(window);\n "; } nativeView = this.nativeViewProtected; if (!nativeView) { return [2, Promise.reject(new Error("WebView is missing"))]; } return [4, new Promise(function (resolve, reject) { nativeView.evaluateJavaScriptCompletionHandler(scriptCode.trim(), function (result, error) { if (error) { reject(error); return; } resolve(result); }); })]; case 1: rawResult = _a.sent(); return [4, this.parseWebViewJavascriptResult(rawResult)]; case 2: result = _a.sent(); r = result; if (r && typeof r === "object" && r.error) { error = new Error(r.message); error.webStack = r.stack; throw error; } return [2, result]; } }); }); }; WebViewExt.prototype.onLoaded = function () { _super.prototype.onLoaded.call(this); var nativeView = this.nativeViewProtected; if (nativeView) { nativeView.navigationDelegate = this.wkNavigationDelegate; nativeView.UIDelegate = this.wkUIDelegate; } }; WebViewExt.prototype.onUnloaded = function () { var nativeView = this.nativeViewProtected; if (nativeView) { nativeView.navigationDelegate = null; nativeView.UIDelegate = null; } _super.prototype.onUnloaded.call(this); }; WebViewExt.prototype.stopLoading = function () { var nativeView = this.nativeViewProtected; if (!nativeView) { return; } nativeView.stopLoading(); }; WebViewExt.prototype._loadUrl = function (src) { var nativeView = this.nativeViewProtected; if (!nativeView) { return; } var nsURL = NSURL.URLWithString(src); if (src.startsWith("file:///")) { var cachePath = src.substring(0, src.lastIndexOf("/")); var nsReadAccessUrl = NSURL.URLWithString(cachePath); this.writeTrace("WKWebViewWrapper.loadUrl(\"" + src + "\") -> ios.loadFileURLAllowingReadAccessToURL(\"" + nsURL + "\", \"" + nsReadAccessUrl + "\""); nativeView.loadFileURLAllowingReadAccessToURL(nsURL, nsReadAccessUrl); } else { var nsRequestWithUrl = NSURLRequest.requestWithURL(nsURL); this.writeTrace("WKWebViewWrapper.loadUrl(\"" + src + "\") -> ios.loadRequest(\"" + nsRequestWithUrl + "\""); nativeView.loadRequest(nsRequestWithUrl); } }; WebViewExt.prototype._loadData = function (content) { var nativeView = this.nativeViewProtected; if (!nativeView) { return; } var baseUrl = "file:///" + fs.knownFolders.currentApp().path + "/"; var nsBaseUrl = NSURL.URLWithString(baseUrl); this.writeTrace("WKWebViewWrapper.loadUrl(content) -> this.ios.loadHTMLStringBaseURL(\"" + nsBaseUrl + "\")"); nativeView.loadHTMLStringBaseURL(content, nsBaseUrl); }; Object.defineProperty(WebViewExt.prototype, "canGoBack", { get: function () { var nativeView = this.nativeViewProtected; return nativeView && !!nativeView.canGoBack; }, enumerable: true, configurable: true }); Object.defineProperty(WebViewExt.prototype, "canGoForward", { get: function () { var nativeView = this.nativeViewProtected; return nativeView && !!nativeView.canGoForward; }, enumerable: true, configurable: true }); WebViewExt.prototype.goBack = function () { var nativeView = this.nativeViewProtected; if (!nativeView) { return; } nativeView.goBack(); }; WebViewExt.prototype.goForward = function () { var nativeView = this.nativeViewProtected; if (!nativeView) { return; } nativeView.goForward(); }; WebViewExt.prototype.reload = function () { var nativeView = this.nativeViewProtected; if (!nativeView) { return; } nativeView.reload(); }; WebViewExt.prototype._webAlert = function (message, callback) { if (!_super.prototype._webAlert.call(this, message, callback)) { dialogs_1.alert(message) .then(function () { return callback(); }) .catch(function () { return callback(); }); } return true; }; WebViewExt.prototype._webConfirm = function (message, callback) { if (!_super.prototype._webConfirm.call(this, message, callback)) { dialogs_1.confirm(message) .then(function (res) { return callback(res); }) .catch(function () { return callback(null); }); } return true; }; WebViewExt.prototype._webPrompt = function (message, defaultText, callback) { if (!_super.prototype._webPrompt.call(this, message, defaultText, callback)) { dialogs_1.prompt(message, defaultText) .then(function (res) { if (res.result) { callback(res.text); } else { callback(null); } }) .catch(function () { return callback(null); }); } return true; }; WebViewExt.prototype.registerLocalResource = function (resourceName, path) { var cls = "WebViewExt<" + this + ".ios>.registerLocalResource(\"" + resourceName + "\", \"" + path + "\")"; if (!this.supportXLocalScheme) { this.writeTrace(cls + " -> custom schema isn't support on iOS <11", view_1.traceMessageType.error); return; } resourceName = this.fixLocalResourceName(resourceName); var filepath = this.resolveLocalResourceFilePath(path); if (!filepath) { this.writeTrace(cls + " -> file doesn't exist", view_1.traceMessageType.error); return; } this.writeTrace(cls + " -> file: \"" + filepath + "\""); this.registerLocalResourceForNative(resourceName, filepath); }; WebViewExt.prototype.unregisterLocalResource = function (resourceName) { var cls = "WebViewExt<" + this + ".ios>.unregisterLocalResource(\"" + resourceName + "\")"; if (!this.supportXLocalScheme) { this.writeTrace(cls + " -> custom schema isn't support on iOS <11", view_1.traceMessageType.error); return; } this.writeTrace(cls); resourceName = this.fixLocalResourceName(resourceName); this.unregisterLocalResourceForNative(resourceName); }; WebViewExt.prototype.getRegisteredLocalResource = function (resourceName) { resourceName = this.fixLocalResourceName(resourceName); var cls = "WebViewExt<" + this + ".ios>.getRegisteredLocalResource(\"" + resourceName + "\")"; if (!this.supportXLocalScheme) { this.writeTrace(cls + " -> custom schema isn't support on iOS <11", view_1.traceMessageType.error); return; } var result = this.getRegisteredLocalResourceFromNative(resourceName); this.writeTrace(cls + " -> \"" + result + "\""); return result; }; WebViewExt.prototype.getTitle = function () { return this.executeJavaScript("document.title"); }; WebViewExt.prototype.autoLoadStyleSheetFile = function (resourceName, path, insertBefore) { return __awaiter(this, void 0, void 0, function () { var filepath, scriptCode; return __generator(this, function (_a) { switch (_a.label) { case 0: filepath = this.resolveLocalResourceFilePath(path); if (!filepath) { this.writeTrace("WKWebViewWrapper.autoLoadStyleSheetFile(\"" + resourceName + "\", \"" + path + "\") - couldn't resolve filepath"); return [2]; } resourceName = this.fixLocalResourceName(resourceName); return [4, this.generateLoadCSSFileScriptCode(resourceName, filepath, insertBefore)]; case 1: scriptCode = _a.sent(); if (scriptCode) { this.addNamedWKUserScript("auto-load-css-" + resourceName, scriptCode); } return [2]; } }); }); }; WebViewExt.prototype.removeAutoLoadStyleSheetFile = function (resourceName) { resourceName = this.fixLocalResourceName(resourceName); this.removeNamedWKUserScript("auto-load-css-" + resourceName); }; WebViewExt.prototype.autoLoadJavaScriptFile = function (resourceName, path) { return __awaiter(this, void 0, void 0, function () { var filepath, scriptCode; return __generator(this, function (_a) { switch (_a.label) { case 0: filepath = this.resolveLocalResourceFilePath(path); if (!filepath) { this.writeTrace("WKWebViewWrapper.autoLoadJavaScriptFile(\"" + resourceName + "\", \"" + path + "\") - couldn't resolve filepath"); return [2]; } return [4, fs.File.fromPath(filepath).readText()]; case 1: scriptCode = _a.sent(); this.addNamedWKUserScript(resourceName, scriptCode); return [2]; } }); }); }; WebViewExt.prototype.removeAutoLoadJavaScriptFile = function (resourceName) { var fixedResourceName = this.fixLocalResourceName(resourceName); var href = this.interceptScheme + "://" + fixedResourceName; this.removeNamedWKUserScript(href); }; WebViewExt.prototype[webview_ext_common_1.autoInjectJSBridgeProperty.setNative] = function (enabled) { this.loadWKUserScripts(enabled); }; WebViewExt.prototype[webview_ext_common_1.scrollBounceProperty.getDefault] = function () { var nativeView = this.nativeViewProtected; if (!nativeView) { return false; } return nativeView.scrollView.bounces; }; WebViewExt.prototype[webview_ext_common_1.scrollBounceProperty.setNative] = function (enabled) { var nativeView = this.nativeViewProtected; if (!nativeView) { return; } nativeView.scrollView.bounces = !!enabled; }; WebViewExt.prototype[webview_ext_common_1.isEnabledProperty.setNative] = function (enabled) { var nativeView = this.nativeViewProtected; if (!nativeView) { return; } nativeView.userInteractionEnabled = !!enabled; nativeView.scrollView.userInteractionEnabled = !!enabled; }; WebViewExt.prototype.loadWKUserScripts = function (autoInjectJSBridge) { var e_1, _a; if (autoInjectJSBridge === void 0) { autoInjectJSBridge = this.autoInjectJSBridge; } if (!this.wkUserScriptViewPortCode) { this.wkUserScriptViewPortCode = this.makeWKUserScriptPromise(this.generateViewPortCode()); } this.wkUserContentController.removeAllUserScripts(); this.addUserScriptFromPromise(this.wkUserScriptViewPortCode); if (!autoInjectJSBridge) { return; } if (!this.wkUserScriptInjectWebViewBridge) { this.wkUserScriptInjectWebViewBridge = this.createWkUserScript(nativescript_webview_bridge_loader_1.webViewBridge); } this.addUserScript(this.wkUserScriptInjectWebViewBridge); try { for (var _b = __values(this.wkNamedUserScripts), _c = _b.next(); !_c.done; _c = _b.next()) { var wkUserScript = _c.value.wkUserScript; this.addUserScript(wkUserScript); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } }; WebViewExt.prototype.removeNamedWKUserScript = function (resourceName) { var idx = this.wkNamedUserScripts.findIndex(function (val) { return val.resourceName === resourceName; }); if (idx === -1) { return; } this.wkNamedUserScripts.splice(idx, 1); this.loadWKUserScripts(); }; WebViewExt.prototype.resetViewPortCode = function () { return __awaiter(this, void 0, void 0, function () { var viewPortScriptCode; return __generator(this, function (_a) { switch (_a.label) { case 0: this.wkUserScriptViewPortCode = null; return [4, this.generateViewPortCode()]; case 1: viewPortScriptCode = _a.sent(); if (viewPortScriptCode) { this.executeJavaScript(viewPortScriptCode); this.loadWKUserScripts(); } return [2]; } }); }); }; WebViewExt.prototype.registerLocalResourceForNative = function (resourceName, filepath) { if (!this.wkCustomUrlSchemeHandler) { return; } this.wkCustomUrlSchemeHandler.registerLocalResourceForKeyFilepath(resourceName, filepath); }; WebViewExt.prototype.unregisterLocalResourceForNative = function (resourceName) { if (!this.wkCustomUrlSchemeHandler) { return; } this.wkCustomUrlSchemeHandler.unregisterLocalResourceForKey(resourceName); }; WebViewExt.prototype.getRegisteredLocalResourceFromNative = function (resourceName) { if (!this.wkCustomUrlSchemeHandler) { return; } return this.wkCustomUrlSchemeHandler.getRegisteredLocalResourceForKey(resourceName); }; WebViewExt.prototype.makeWKUserScriptPromise = function (scriptCodePromise) { return __awaiter(this, void 0, void 0, function () { var scriptCode; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4, scriptCodePromise]; case 1: scriptCode = _a.sent(); if (!scriptCode) { return [2, null]; } return [2, this.createWkUserScript(scriptCode)]; } }); }); }; WebViewExt.prototype.addUserScriptFromPromise = function (userScriptPromise) { return __awaiter(this, void 0, void 0, function () { var userScript; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4, userScriptPromise]; case 1: userScript = _a.sent(); if (!userScript) { return [2]; } return [2, this.addUserScript(userScript)]; } }); }); }; WebViewExt.prototype.addUserScript = function (userScript) { if (!userScript) { return; } this.wkUserContentController.addUserScript(userScript); }; WebViewExt.prototype.addNamedWKUserScript = function (resourceName, scriptCode) { if (!scriptCode) { return; } this.removeNamedWKUserScript(resourceName); var wkUserScript = this.createWkUserScript(scriptCode); this.wkNamedUserScripts.push({ resourceName: resourceName, wkUserScript: wkUserScript }); this.addUserScript(wkUserScript); }; WebViewExt.prototype.createWkUserScript = function (source) { return WKUserScript.alloc().initWithSourceInjectionTimeForMainFrameOnly(source, 1, true); }; __decorate([ profiling_1.profile, __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], WebViewExt.prototype, "onLoaded", null); return WebViewExt; }(webview_ext_common_1.WebViewExtBase)); exports.WebViewExt = WebViewExt; var WKNavigationDelegateNotaImpl = (function (_super) { __extends(WKNavigationDelegateNotaImpl, _super); function WKNavigationDelegateNotaImpl() { return _super !== null && _super.apply(this, arguments) || this; } WKNavigationDelegateNotaImpl.initWithOwner = function (owner) { var handler = WKNavigationDelegateNotaImpl.new(); handler.owner = owner; return handler; }; WKNavigationDelegateNotaImpl.prototype.webViewDecidePolicyForNavigationActionDecisionHandler = function (webView, navigationAction, decisionHandler) { var owner = this.owner.get(); if (!owner) { decisionHandler(0); return; } var request = navigationAction.request; var httpMethod = request.HTTPMethod; var url = request.URL && request.URL.absoluteString; owner.writeTrace("webViewDecidePolicyForNavigationActionDecisionHandler: \"" + url + "\""); if (!url) { return; } var navType = "other"; switch (navigationAction.navigationType) { case 0: { navType = "linkClicked"; break; } case 1: { navType = "formSubmitted"; break; } case 2: { navType = "backForward"; break; } case 3: { navType = "reload"; break; } case 4: { navType = "formResubmitted"; break; } default: { navType = "other"; break; } } var shouldOverrideUrlLoading = owner._onShouldOverrideUrlLoading(url, httpMethod, navType); if (shouldOverrideUrlLoading === true) { owner.writeTrace("WKNavigationDelegateClass.webViewDecidePolicyForNavigationActionDecisionHandler(\"" + url + "\", \"" + navigationAction.navigationType + "\") -> method:" + httpMethod + " \"" + navType + "\" -> cancel"); decisionHandler(0); return; } decisionHandler(1); owner.writeTrace("WKNavigationDelegateClass.webViewDecidePolicyForNavigationActionDecisionHandler(\"" + url + "\", \"" + navigationAction.navigationType + "\") -> method:" + httpMethod + " \"" + navType + "\""); owner._onLoadStarted(url, navType); }; WKNavigationDelegateNotaImpl.prototype.webViewDidStartProvisionalNavigation = function (webView, navigation) { var owner = this.owner.get(); if (!owner) { return; } owner.writeTrace("WKNavigationDelegateClass.webViewDidStartProvisionalNavigation(\"" + webView.URL + "\")"); }; WKNavigationDelegateNotaImpl.prototype.webViewDidFinishNavigation = function (webView, navigation) { var owner = this.owner.get(); if (!owner) { return; } owner.writeTrace("WKNavigationDelegateClass.webViewDidFinishNavigation(\"" + webView.URL + "\")"); var src = owner.src; if (webView.URL) { src = webView.URL.absoluteString; } owner._onLoadFinished(src).catch(function () { return void 0; }); }; WKNavigationDelegateNotaImpl.prototype.webViewDidFailNavigationWithError = function (webView, navigation, error) { var owner = this.owner.get(); if (!owner) { return; } var src = owner.src; if (webView.URL) { src = webView.URL.absoluteString; } owner.writeTrace("WKNavigationDelegateClass.webViewDidFailNavigationWithError(\"" + error.localizedDescription + "\")"); owner._onLoadFinished(src, error.localizedDescription).catch(function () { return void 0; }); }; WKNavigationDelegateNotaImpl.prototype.webViewDidFailProvisionalNavigationWithError = function (webView, navigation, error) { var owner = this.owner.get(); if (!owner) { return; } var src = owner.src; if (webView.URL && webView.URL.absoluteString) { src = webView.URL.absoluteString; } owner.writeTrace("WKNavigationDelegateClass.webViewDidFailProvisionalNavigationWithError(" + error.localizedDescription); owner._onLoadFinished(src, error.localizedDescription); }; WKNavigationDelegateNotaImpl.ObjCProtocols = [WKNavigationDelegate]; return WKNavigationDelegateNotaImpl; }(NSObject)); exports.WKNavigationDelegateNotaImpl = WKNavigationDelegateNotaImpl; var WKScriptMessageHandlerNotaImpl = (function (_super) { __extends(WKScriptMessageHandlerNotaImpl, _super); function WKScriptMessageHandlerNotaImpl() { return _super !== null && _super.apply(this, arguments) || this; } WKScriptMessageHandlerNotaImpl.initWithOwner = function (owner) { var delegate = WKScriptMessageHandlerNotaImpl.new(); delegate.owner = owner; return delegate; }; WKScriptMessageHandlerNotaImpl.prototype.userContentControllerDidReceiveScriptMessage = function (userContentController, webViewMessage) { var owner = this.owner.get(); if (!owner) { return; } try { var message = JSON.parse(webViewMessage.body); owner.onWebViewEvent(message.eventName, message.data); } catch (err) { owner.writeTrace("userContentControllerDidReceiveScriptMessage(" + userContentController + ", " + webViewMessage + ") - bad message: " + webViewMessage.body, view_1.traceMessageType.error); } }; WKScriptMessageHandlerNotaImpl.ObjCProtocols = [WKScriptMessageHandler]; return WKScriptMessageHandlerNotaImpl; }(NSObject)); exports.WKScriptMessageHandlerNotaImpl = WKScriptMessageHandlerNotaImpl; var WKUIDelegateNotaImpl = (function (_super) { __extends(WKUIDelegateNotaImpl, _super); function WKUIDelegateNotaImpl() { return _super !== null && _super.apply(this, arguments) || this; } WKUIDelegateNotaImpl.initWithOwner = function (owner) { var delegate = WKUIDelegateNotaImpl.new(); delegate.owner = owner; console.log(delegate); return delegate; }; WKUIDelegateNotaImpl.prototype.webViewRunJavaScriptAlertPanelWithMessageInitiatedByFrameCompletionHandler = function (webView, message, frame, completionHandler) { var owner = this.owner.get(); if (!owner) { return; } var gotResponse = false; owner._webAlert(message, function () { if (!gotResponse) { completionHandler(); } gotResponse = true; }); }; WKUIDelegateNotaImpl.prototype.webViewRunJavaScriptConfirmPanelWithMessageInitiatedByFrameCompletionHandler = function (webView, message, frame, completionHandler) { var owner = this.owner.get(); if (!owner) { return; } var gotResponse = false; owner._webConfirm(message, function (confirmed) { if (!gotResponse) { completionHandler(confirmed); } gotResponse = true; }); }; WKUIDelegateNotaImpl.prototype.webViewRunJavaScriptTextInputPanelWithPromptDefaultTextInitiatedByFrameCompletionHandler = function (webView, message, defaultText, frame, completionHandler) { var owner = this.owner.get(); if (!owner) { return; } var gotResponse = false; owner._webPrompt(message, defaultText, function (response) { if (!gotResponse) { completionHandler(response); } gotResponse = true; }); }; WKUIDelegateNotaImpl.ObjCProtocols = [WKUIDelegate]; return WKUIDelegateNotaImpl; }(NSObject)); exports.WKUIDelegateNotaImpl = WKUIDelegateNotaImpl; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vidmlldy1leHQuaW9zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsid2Vidmlldy1leHQuaW9zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBR0EsbURBQXFEO0FBQ3JELDBEQUF1RDtBQUN2RCx3REFBbUU7QUFDbkUseURBQXVFO0FBQ3ZFLDJGQUFxRTtBQUNyRSwyREFBMkk7QUFFM0ksMENBQXFDO0FBRXJDO0lBQWdDLDhCQUFjO0lBQTlDO1FBQUEscUVBd2hCQztRQXhnQmEsd0JBQWtCLEdBQUcsRUFHN0IsQ0FBQztRQU1JLGtCQUFZLEdBQUcsRUFBRSxZQUFZLEVBQUUsR0FBRyxFQUFFLENBQUM7O0lBK2ZoRCxDQUFDO0lBdmhCRyxzQkFBVywyQkFBRzthQUFkO1lBQ0ksT0FBTyxJQUFJLENBQUMsbUJBQWdDLENBQUM7UUFDakQsQ0FBQzs7O09BQUE7SUFFRCxzQkFBa0IsaUNBQW1CO2FBQXJDO1lBQ0ksT0FBTyxPQUFPLHNCQUFzQixLQUFLLFdBQVcsQ0FBQztRQUN6RCxDQUFDOzs7T0FBQTtJQWNELHNCQUFXLDJDQUFtQjthQUE5QjtZQUNJLE9BQU8sT0FBTyxzQkFBc0IsS0FBSyxXQUFXLENBQUM7UUFDekQsQ0FBQzs7O09BQUE7SUFJTSxxQ0FBZ0IsR0FBdkI7UUFDSSxJQUFNLGFBQWEsR0FBRyxzQkFBc0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNuRCxhQUFhLENBQUMsaUJBQWlCLEtBQTBCLENBQUM7UUFDMUQsSUFBSSxDQUFDLHNCQUFzQixHQUFHLGFBQWEsQ0FBQztRQUU1QyxJQUFNLGNBQWMsR0FBRyw4QkFBOEIsQ0FBQyxhQUFhLENBQUMsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN2RixJQUFNLGFBQWEsR0FBRyxDQUFDLElBQUksQ0FBQyx1QkFBdUIsR0FBRyx1QkFBdUIsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ3JGLGFBQWEsQ0FBQywyQkFBMkIsQ0FBQyxjQUFjLEVBQUUs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