@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.
528 lines • 74.7 kB
JavaScript
"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("tns-core-modules/file-system");
var webview_ext_common_1 = require("./webview-ext-common");
__export(require("./webview-ext-common"));
var extToMimeType = new Map([
["html", "text/html"],
["htm", "text/html"],
["xhtml", "text/html"],
["xhtm", "text/html"],
["css", "text/css"],
["gif", "image/gif"],
["jpeg", "image/jpeg"],
["jpg", "image/jpeg"],
["js", "text/javascript"],
["otf", "application/vnd.ms-opentype"],
["png", "image/png"],
["svg", "image/svg+xml"],
["ttf", "application/x-font-ttf"],
]);
var extToBinaryEncoding = new Set(["gif", "jpeg", "jpg", "otf", "png", "ttf"]);
var cacheModeMap;
var WebViewExtClient;
var WebViewBridgeInterface;
function initializeWebViewClient() {
if (WebViewExtClient) {
return;
}
cacheModeMap = new Map([
["cache_first", android.webkit.WebSettings.LOAD_CACHE_ELSE_NETWORK],
["cache_only", android.webkit.WebSettings.LOAD_CACHE_ONLY],
["default", android.webkit.WebSettings.LOAD_DEFAULT],
["no_cache", android.webkit.WebSettings.LOAD_NO_CACHE],
]);
var WebViewExtClientImpl = (function (_super) {
__extends(WebViewExtClientImpl, _super);
function WebViewExtClientImpl(owner) {
var _this = _super.call(this) || this;
_this.owner = owner;
return global.__native(_this);
}
WebViewExtClientImpl.prototype.shouldOverrideUrlLoading = function (view, request) {
var owner = this.owner;
if (!owner) {
console.warn("WebViewExtClientImpl.shouldOverrideUrlLoading(...) - no owner");
return true;
}
var url = request;
var httpMethod = "GET";
var isRedirect = false;
var hasGesture = false;
var isForMainFrame = false;
var requestHeaders = null;
if (typeof request === "object") {
httpMethod = request.getMethod();
isRedirect = request.isRedirect();
hasGesture = request.hasGesture();
isForMainFrame = request.isForMainFrame();
requestHeaders = request.getRequestHeaders();
url = request.getUrl().toString();
}
owner.writeTrace("WebViewClientClass.shouldOverrideUrlLoading(\"" + url + "\") - method:" + httpMethod + " isRedirect:" + isRedirect + " hasGesture:" + hasGesture + " isForMainFrame:" + isForMainFrame + " headers:" + requestHeaders);
if (url.startsWith(owner.interceptScheme)) {
owner.writeTrace("WebViewClientClass.shouldOverrideUrlLoading(\"" + url + "\") - \"" + owner.interceptScheme + "\" - cancel");
return true;
}
var shouldOverrideUrlLoading = owner._onShouldOverrideUrlLoading(url, httpMethod);
if (shouldOverrideUrlLoading === true) {
owner.writeTrace("WebViewClientClass.shouldOverrideUrlLoading(\"" + url + "\") - cancel loading url");
return true;
}
return false;
};
WebViewExtClientImpl.prototype.shouldInterceptRequest = function (view, request) {
var owner = this.owner;
if (!owner) {
console.warn("WebViewExtClientImpl.shouldInterceptRequest(...) - no owner");
return _super.prototype.shouldInterceptRequest.call(this, view, request);
}
var url = request;
if (typeof request === "object") {
url = request.getUrl().toString();
}
if (typeof url !== "string") {
owner.writeTrace("WebViewClientClass.shouldInterceptRequest(\"" + url + "\") - is not a string");
return _super.prototype.shouldInterceptRequest.call(this, view, request);
}
if (!url.startsWith(owner.interceptScheme)) {
return _super.prototype.shouldInterceptRequest.call(this, view, request);
}
var filepath = owner.getRegisteredLocalResource(url);
if (!filepath) {
owner.writeTrace("WebViewClientClass.shouldInterceptRequest(\"" + url + "\") - no matching file");
return _super.prototype.shouldInterceptRequest.call(this, view, request);
}
if (!fs.File.exists(filepath)) {
owner.writeTrace("WebViewClientClass.shouldInterceptRequest(\"" + url + "\") - file: \"" + filepath + "\" doesn't exists");
return _super.prototype.shouldInterceptRequest.call(this, view, request);
}
var tnsFile = fs.File.fromPath(filepath);
var javaFile = new java.io.File(tnsFile.path);
var stream = new java.io.FileInputStream(javaFile);
var ext = tnsFile.extension.substr(1).toLowerCase();
var mimeType = extToMimeType.get(ext) || "application/octet-stream";
var encoding = extToBinaryEncoding.has(ext) || mimeType === "application/octet-stream" ? "binary" : "UTF-8";
owner.writeTrace("WebViewClientClass.shouldInterceptRequest(\"" + url + "\") - file: \"" + filepath + "\" mimeType:" + mimeType + " encoding:" + encoding);
var response = new android.webkit.WebResourceResponse(mimeType, encoding, stream);
if (webview_ext_common_1.androidSDK < 21) {
return response;
}
var r = response;
if (!r.getResponseHeaders) {
return response;
}
var responseHeaders = r.getResponseHeaders() || new java.util.HashMap();
responseHeaders.put("Access-Control-Allow-Origin", "*");
r.setResponseHeaders(responseHeaders);
return response;
};
WebViewExtClientImpl.prototype.onPageStarted = function (view, url, favicon) {
_super.prototype.onPageStarted.call(this, view, url, favicon);
var owner = this.owner;
if (!owner) {
console.warn("WebViewExtClientImpl.onPageStarted(...) - no owner");
return;
}
owner.writeTrace("WebViewClientClass.onPageStarted(\"" + url + "\", \"" + favicon + "\")");
owner._onLoadStarted(url);
};
WebViewExtClientImpl.prototype.onPageFinished = function (view, url) {
_super.prototype.onPageFinished.call(this, view, url);
var owner = this.owner;
if (!owner) {
console.warn("WebViewExtClientImpl.onPageFinished(...) - no owner");
return;
}
owner.writeTrace("WebViewClientClass.onPageFinished(\"" + url + "\")");
owner._onLoadFinished(url).catch(function () { return void 0; });
};
WebViewExtClientImpl.prototype.onReceivedError = function () {
if (arguments.length === 4) {
var _a = Array.from(arguments), view = _a[0], errorCode = _a[1], description = _a[2], failingUrl = _a[3];
this.onReceivedErrorBeforeAPI23(view, errorCode, description, failingUrl);
}
else {
var _b = Array.from(arguments), view = _b[0], request = _b[1], error = _b[2];
this.onReceivedErrorAPI23(view, request, error);
}
};
WebViewExtClientImpl.prototype.onReceivedErrorAPI23 = function (view, request, error) {
_super.prototype.onReceivedError.call(this, view, request, error);
var owner = this.owner;
if (!owner) {
console.warn("WebViewExtClientImpl.onReceivedErrorAPI23(...) - no owner");
return;
}
var url = error.getUrl && error.getUrl();
if (!url && typeof request === "object") {
url = request.getUrl().toString();
}
owner.writeTrace("WebViewClientClass.onReceivedErrorAPI23(" + error.getErrorCode() + ", " + error.getDescription() + ", " + url + ")");
owner._onLoadFinished(url, error.getDescription() + "(" + error.getErrorCode() + ")").catch(function () { return void 0; });
};
WebViewExtClientImpl.prototype.onReceivedErrorBeforeAPI23 = function (view, errorCode, description, failingUrl) {
_super.prototype.onReceivedError.call(this, view, errorCode, description, failingUrl);
var owner = this.owner;
if (!owner) {
console.warn("WebViewExtClientImpl.onReceivedErrorBeforeAPI23(...) - no owner");
return;
}
owner.writeTrace("WebViewClientClass.onReceivedErrorBeforeAPI23(" + errorCode + ", \"" + description + "\", \"" + failingUrl + "\")");
owner._onLoadFinished(failingUrl, description + "(" + errorCode + ")").catch(function () { return void 0; });
};
return WebViewExtClientImpl;
}(android.webkit.WebViewClient));
WebViewExtClient = WebViewExtClientImpl;
var WebViewBridgeInterfaceImpl = (function (_super) {
__extends(WebViewBridgeInterfaceImpl, _super);
function WebViewBridgeInterfaceImpl(owner) {
var _this = _super.call(this) || this;
_this.owner = owner;
return global.__native(_this);
}
WebViewBridgeInterfaceImpl.prototype.emitEventToNativeScript = function (eventName, data) {
var owner = this.owner;
if (!owner) {
console.warn("WebViewExtClientImpl.onReceivedErrorBeforeAPI23(...) - no owner");
return;
}
try {
owner.onWebViewEvent(eventName, JSON.parse(data));
return;
}
catch (_a) { }
owner.onWebViewEvent(eventName, data);
};
return WebViewBridgeInterfaceImpl;
}(dk.nota.webviewinterface.WebViewBridgeInterface));
WebViewBridgeInterface = WebViewBridgeInterfaceImpl;
}
var instanceNo = 0;
var WebViewExt = (function (_super) {
__extends(WebViewExt, _super);
function WebViewExt() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.localResourceMap = new Map();
_this.instance = ++instanceNo;
return _this;
}
Object.defineProperty(WebViewExt.prototype, "isUIWebView", {
get: function () {
return false;
},
enumerable: true,
configurable: true
});
Object.defineProperty(WebViewExt.prototype, "isWKWebView", {
get: function () {
return false;
},
enumerable: true,
configurable: true
});
WebViewExt.prototype.createNativeView = function () {
var nativeView = new android.webkit.WebView(this._context);
var settings = nativeView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setBuiltInZoomControls(true);
settings.setAllowUniversalAccessFromFileURLs(true);
return nativeView;
};
WebViewExt.prototype.initNativeView = function () {
_super.prototype.initNativeView.call(this);
initializeWebViewClient();
var nativeView = this.nativeViewProtected;
if (!nativeView) {
return;
}
var client = new WebViewExtClient(this);
nativeView.setWebViewClient(client);
nativeView.client = client;
var bridgeInterface = new WebViewBridgeInterface(this);
nativeView.addJavascriptInterface(bridgeInterface, "androidWebViewBridge");
nativeView.bridgeInterface = bridgeInterface;
};
WebViewExt.prototype.disposeNativeView = function () {
var nativeView = this.nativeViewProtected;
if (nativeView) {
nativeView.client.owner = null;
nativeView.bridgeInterface.owner = null;
nativeView.destroy();
}
_super.prototype.disposeNativeView.call(this);
};
WebViewExt.prototype._loadUrl = function (src) {
var nativeView = this.nativeViewProtected;
if (!nativeView) {
return;
}
this.writeTrace("WebViewExt<android>._loadUrl(\"" + src + "\")");
nativeView.loadUrl(src);
};
WebViewExt.prototype._loadData = function (src) {
var nativeView = this.nativeViewProtected;
if (!nativeView) {
return;
}
var baseUrl = "file:///" + fs.knownFolders.currentApp().path + "/";
this.writeTrace("WebViewExt<android>._loadData(\"" + src + "\") -> baseUrl: \"" + baseUrl + "\"");
nativeView.loadDataWithBaseURL(baseUrl, src, "text/html", "utf-8", null);
};
Object.defineProperty(WebViewExt.prototype, "canGoBack", {
get: function () {
var nativeView = this.nativeViewProtected;
if (nativeView) {
return nativeView.canGoBack();
}
return false;
},
enumerable: true,
configurable: true
});
WebViewExt.prototype.stopLoading = function () {
var nativeView = this.nativeViewProtected;
if (nativeView) {
nativeView.stopLoading();
}
};
Object.defineProperty(WebViewExt.prototype, "canGoForward", {
get: function () {
var nativeView = this.nativeViewProtected;
if (nativeView) {
return nativeView.canGoForward();
}
return false;
},
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.registerLocalResource = function (resourceName, path) {
resourceName = this.fixLocalResourceName(resourceName);
var filepath = this.resolveLocalResourceFilePath(path);
if (!filepath) {
this.writeTrace("WebViewExt<android>.registerLocalResource(\"" + resourceName + "\", \"" + path + "\") -> file doesn't exist", webview_ext_common_1.traceMessageType.error);
return;
}
this.writeTrace("WebViewExt<android>.registerLocalResource(\"" + resourceName + "\", \"" + path + "\") -> file: \"" + filepath + "\"");
this.localResourceMap.set(resourceName, filepath);
};
WebViewExt.prototype.unregisterLocalResource = function (resourceName) {
this.writeTrace("WebViewExt<android>.unregisterLocalResource(\"" + resourceName + "\")");
resourceName = this.fixLocalResourceName(resourceName);
this.localResourceMap.delete(resourceName);
};
WebViewExt.prototype.getRegisteredLocalResource = function (resourceName) {
resourceName = this.fixLocalResourceName(resourceName);
var result = this.localResourceMap.get(resourceName);
this.writeTrace("WebViewExt<android>.getRegisteredLocalResource(\"" + resourceName + "\") => \"" + result + "\"");
return result;
};
WebViewExt.prototype.ensureFetchSupport = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
this.writeTrace("WebViewExt<android>.ensureFetchSupport() - Override 'Fetch API' to support x-local.");
return [4, this.executeJavaScript("\n try {\n window.fetch = null;\n } catch (err) {\n console.error(\"null'ing Native Fetch API failed:\", err);\n }\n ")];
case 1:
_a.sent();
return [4, this.loadFetchPolyfill()];
case 2:
_a.sent();
return [2];
}
});
});
};
WebViewExt.prototype.executeJavaScript = function (scriptCode) {
return __awaiter(this, void 0, void 0, function () {
var result;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (webview_ext_common_1.androidSDK < 19) {
this.writeTrace("WebViewExt<android>.executeJavaScript() -> SDK:" + webview_ext_common_1.androidSDK + " not supported", webview_ext_common_1.traceMessageType.error);
return [2, Promise.reject(new webview_ext_common_1.UnsupportSDKError(19))];
}
return [4, new Promise(function (resolve, reject) {
if (!_this.nativeViewProtected) {
_this.writeTrace("WebViewExt<android>.executeJavaScript() -> no nativeview?", webview_ext_common_1.traceMessageType.error);
reject(new Error("Native Android not inited, cannot call executeJavaScript"));
return;
}
_this.nativeViewProtected.evaluateJavascript(scriptCode, new android.webkit.ValueCallback({
onReceiveValue: function (result) {
resolve(result);
},
}));
})];
case 1:
result = _a.sent();
return [4, this.parseWebViewJavascriptResult(result)];
case 2: return [2, _a.sent()];
}
});
});
};
WebViewExt.prototype.getTitle = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2, this.nativeViewProtected && this.nativeViewProtected.getTitle()];
});
});
};
WebViewExt.prototype.zoomIn = function () {
if (!this.nativeViewProtected) {
return false;
}
return this.nativeViewProtected.zoomIn();
};
WebViewExt.prototype.zoomOut = function () {
if (!this.nativeViewProtected) {
return false;
}
return this.nativeViewProtected.zoomOut();
};
WebViewExt.prototype.zoomBy = function (zoomFactor) {
if (webview_ext_common_1.androidSDK < 21) {
this.writeTrace("WebViewExt<android>.zoomBy - not supported on this SDK");
return;
}
if (!this.nativeViewProtected) {
return;
}
if (zoomFactor >= 0.01 && zoomFactor <= 100) {
return this.nativeViewProtected.zoomBy(zoomFactor);
}
throw new Error("ZoomBy only accepts values between 0.01 and 100 both inclusive");
};
WebViewExt.prototype[webview_ext_common_1.debugModeProperty.getDefault] = function () {
return false;
};
WebViewExt.prototype[webview_ext_common_1.debugModeProperty.setNative] = function (enabled) {
android.webkit.WebView.setWebContentsDebuggingEnabled(!!enabled);
};
WebViewExt.prototype[webview_ext_common_1.builtInZoomControlsProperty.getDefault] = function () {
if (!this.nativeViewProtected) {
return false;
}
var settings = this.nativeViewProtected.getSettings();
return settings.getBuiltInZoomControls();
};
WebViewExt.prototype[webview_ext_common_1.builtInZoomControlsProperty.setNative] = function (enabled) {
if (!this.nativeViewProtected) {
return;
}
var settings = this.nativeViewProtected.getSettings();
settings.setBuiltInZoomControls(!!enabled);
};
WebViewExt.prototype[webview_ext_common_1.displayZoomControlsProperty.getDefault] = function () {
if (!this.nativeViewProtected) {
return false;
}
var settings = this.nativeViewProtected.getSettings();
return settings.getDisplayZoomControls();
};
WebViewExt.prototype[webview_ext_common_1.displayZoomControlsProperty.setNative] = function (enabled) {
if (!this.nativeViewProtected) {
return;
}
var settings = this.nativeViewProtected.getSettings();
settings.setDisplayZoomControls(!!enabled);
};
WebViewExt.prototype[webview_ext_common_1.cacheModeProperty.getDefault] = function () {
if (!this.nativeViewProtected) {
return null;
}
var settings = this.nativeViewProtected.getSettings();
var cacheModeInt = settings.getCacheMode();
for (var _i = 0, _a = Array.from(cacheModeMap); _i < _a.length; _i++) {
var _b = _a[_i], key = _b[0], value = _b[1];
if (value === cacheModeInt) {
return key;
}
}
return null;
};
WebViewExt.prototype[webview_ext_common_1.cacheModeProperty.setNative] = function (cacheMode) {
if (!this.nativeViewProtected) {
return;
}
var settings = this.nativeViewProtected.getSettings();
for (var _i = 0, _a = Array.from(cacheModeMap); _i < _a.length; _i++) {
var _b = _a[_i], key = _b[0], nativeValue = _b[1];
if (key === cacheMode) {
settings.setCacheMode(nativeValue);
return;
}
}
};
WebViewExt.prototype[webview_ext_common_1.databaseStorageProperty.getDefault] = function () {
if (!this.nativeViewProtected) {
return false;
}
var settings = this.nativeViewProtected.getSettings();
return settings.getDatabaseEnabled();
};
WebViewExt.prototype[webview_ext_common_1.databaseStorageProperty.setNative] = function (enabled) {
if (!this.nativeViewProtected) {
return;
}
var settings = this.nativeViewProtected.getSettings();
settings.setDatabaseEnabled(!!enabled);
};
WebViewExt.prototype[webview_ext_common_1.domStorageProperty.getDefault] = function () {
if (!this.nativeViewProtected) {
return false;
}
var settings = this.nativeViewProtected.getSettings();
return settings.getDomStorageEnabled();
};
WebViewExt.prototype[webview_ext_common_1.domStorageProperty.setNative] = function (enabled) {
if (!this.nativeViewProtected) {
return;
}
var settings = this.nativeViewProtected.getSettings();
settings.setDomStorageEnabled(!!enabled);
};
WebViewExt.prototype[webview_ext_common_1.supportZoomProperty.getDefault] = function () {
if (!this.nativeViewProtected) {
return false;
}
var settings = this.nativeViewProtected.getSettings();
return settings.supportZoom();
};
WebViewExt.prototype[webview_ext_common_1.supportZoomProperty.setNative] = function (enabled) {
if (!this.nativeViewProtected) {
return;
}
var settings = this.nativeViewProtected.getSettings();
settings.setSupportZoom(!!enabled);
};
return WebViewExt;
}(webview_ext_common_1.WebViewExtBase));
exports.WebViewExt = WebViewExt;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vidmlldy1leHQuYW5kcm9pZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIndlYnZpZXctZXh0LmFuZHJvaWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFFQSxpREFBbUQ7QUFDbkQsMkRBWThCO0FBRTlCLDBDQUFxQztBQUVyQyxJQUFNLGFBQWEsR0FBRyxJQUFJLEdBQUcsQ0FBaUI7SUFDMUMsQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDO0lBQ3JCLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQztJQUNwQixDQUFDLE9BQU8sRUFBRSxXQUFXLENBQUM7SUFDdEIsQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDO0lBQ3JCLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQztJQUNuQixDQUFDLEtBQUssRUFBRSxXQUFXLENBQUM7SUFDcEIsQ0FBQyxNQUFNLEVBQUUsWUFBWSxDQUFDO0lBQ3RCLENBQUMsS0FBSyxFQUFFLFlBQVksQ0FBQztJQUNyQixDQUFDLElBQUksRUFBRSxpQkFBaUIsQ0FBQztJQUN6QixDQUFDLEtBQUssRUFBRSw2QkFBNkIsQ0FBQztJQUN0QyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUM7SUFDcEIsQ0FBQyxLQUFLLEVBQUUsZUFBZSxDQUFDO0lBQ3hCLENBQUMsS0FBSyxFQUFFLHdCQUF3QixDQUFDO0NBQ3BDLENBQUMsQ0FBQztBQUVILElBQU0sbUJBQW1CLEdBQUcsSUFBSSxHQUFHLENBQVMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFLekYsSUFBSSxZQUFvQyxDQUFDO0FBc0J6QyxJQUFJLGdCQUFpRSxDQUFDO0FBQ3RFLElBQUksc0JBQWtHLENBQUM7QUFFdkcsU0FBUyx1QkFBdUI7SUFDNUIsSUFBSSxnQkFBZ0IsRUFBRTtRQUNsQixPQUFPO0tBQ1Y7SUFFRCxZQUFZLEdBQUcsSUFBSSxHQUFHLENBQW9CO1FBQ3RD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LENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRCxxQkFBQyx3Q0FBbUIsQ0FBQyxVQUFVLENBQUMsR0FBaEM7UUFDSSxJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFO1lBQzNCLE9BQU8sS0FBSyxDQUFDO1NBQ2hCO1FBRUQsSUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3hELE9BQU8sUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ2xDLENBQUM7SUFFRCxxQkFBQyx3Q0FBbUIsQ0FBQyxTQUFTLENBQUMsR0FBL0IsVUFBZ0MsT0FBZ0I7UUFDNUMsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRTtZQUMzQixPQUFPO1NBQ1Y7UUFFRCxJQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDeEQsUUFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUNMLGlCQUFDO0FBQUQsQ0FBQyxBQXhXRCxDQUFnQyxtQ0FBYyxHQXdXN0M7QUF4V1ksZ0NBQVUiLCJzb3VyY2VzQ29udGVudCI6WyIvLy8gPHJlZmVyZW5jZSBwYXRoPVwiLi9wbGF0Zm9ybXMvYW5kcm9pZC93ZWJ2aWV3aW50ZXJmYWNlLmQudHNcIiAvPlxuXG5pbXBvcnQgKiBhcyBmcyBmcm9tIFwidG5zLWNvcmUtbW9kdWxlcy9maWxlLXN5c3RlbVwiO1xuaW1wb3J0IHtcbiAgICBhbmRyb2lkU0RLLFxuICAgIGJ1aWx0SW5ab29tQ29udHJvbHNQcm9wZXJ0eSxcbiAgICBjYWNoZU1vZGVQcm9wZXJ0eSxcbiAgICBkYXRhYmFzZVN0b3JhZ2VQcm9wZXJ0eSxcbiAgICBkZWJ1Z01vZGVQcm9wZXJ0eSxcbiAgICBkaXNwbGF5Wm9vbUNvbnRyb2xzUHJvcGVydHksXG4gICAgZG9tU3RvcmFnZVByb3BlcnR5LFxuICAgIHN1cHBvcnRab29tUHJvcGVydHksXG4gICAgdHJhY2VNZXNzYWdlVHlwZSxcbiAgICBVbnN1cHBvcnRTREtFcnJvcixcbiAgICBXZWJWaWV3RXh0QmFzZSxcbn0gZnJvbSBcIi4vd2Vidmlldy1leHQtY29tbW9uXCI7XG5cbmV4cG9ydCAqIGZyb20gXCIuL3dlYnZpZXctZXh0LWNvbW1vblwiO1xuXG5jb25zdCBleHRUb01pbWVUeXBlID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oW1xuICAgIFtcImh0bWxcIiwgXCJ0ZXh0L2h0bWxcIl0sXG4gICAgW1wiaHRtXCIsIFwidGV4dC9odG1sXCJdLFxuICAgIFtcInhodG1sXCIsIFwidGV4dC9odG1sXCJdLFxuICAgIFtcInhodG1cIiwgXCJ0ZXh0L2h0bWxcIl0sXG4gICAgW1wiY3NzXCIsIFwidGV4dC9jc3NcIl0sXG4gICAgW1wiZ2lmXCIsIFwiaW1hZ2UvZ2lmXCJdLFxuICAgIFtcImpwZWdcIiwgXCJpbWFnZS9qcGVnXCJdLFxuICAgIFtcImpwZ1wiLCBcImltYWdlL2pwZWdcIl0sXG4gICAgW1wianNcIiwgXCJ0ZXh0L2phdmFzY3JpcHRcIl0sXG4gICAgW1wib3RmXCIsIFwiYXBwbGljYXRpb24vdm5kLm1zLW9wZW50eXBlXCJdLFxuICAgIFtcInBuZ1wiLCBcImltYWdlL3BuZ1wiXSxcbiAgICBbXCJzdmdcIiwgXCJpbWFnZS9zdmcreG1sXCJdLFxuICAgIFtcInR0ZlwiLCBcImFwcGxpY2F0aW9uL3gtZm9udC10dGZcIl0sXG5dKTtcblxuY29uc3QgZXh0VG9CaW5hcnlFbmNvZGluZyA9IG5ldyBTZXQ8c3RyaW5nPihbXCJnaWZcIiwgXCJqcGVnXCIsIFwianBnXCIsIFwib3RmXCIsIFwicG5nXCIsIFwidHRmXCJdKTtcblxudHlwZSBDYWNoZU1vZGUgPSBcImRlZmF1bHRcIiB8IFwiY2FjaGVfZmlyc3RcIiB8IFwibm9fY2FjaGVcIiB8IFwiY2FjaGVfb25seVwiO1xuXG4vLyNyZWdpb24gYW5kcm9pZF9uYXRpdmVfY2xhc3Nlc1xubGV0IGNhY2hlTW9kZU1hcDogTWFwPENhY2hlTW9kZSwgbnVtYmVyPjtcblxuLy8gTWlub3IgZXh0ZW50aW9uIG9mIHRoZSBOYXRpdmUgaW50ZXJmYWNlIHRvIGFsbG93IGZvciBvd25lclxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIGRrIHtcbiAgICBuYW1lc3BhY2Ugbm90YSB7XG4gICAgICAgIG5hbWVzcGFjZSB3ZWJ2aWV3aW50ZXJmYWNlIHtcbiAgICAgICAgICAgIGNsYXNzIFdlYlZpZXdCcmlkZ2VJbnRlcmZhY2UgZXh0ZW5kcyBqYXZhLmxhbmcuT2JqZWN0IHtcbiAgICAgICAgICAgICAgICBwdWJsaWMgb3duZXI/OiBXZWJWaWV3RXh0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFuZHJvaWRXZWJWaWV3Q2xpZW50IGV4dGVuZHMgYW5kcm9pZC53ZWJraXQuV2ViVmlld0NsaWVudCB7XG4gICAgb3duZXI6IFdlYlZpZXdFeHQgfCBudWxsO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFuZHJvaWRXZWJWaWV3IGV4dGVuZHMgYW5kcm9pZC53ZWJraXQuV2ViVmlldyB7XG4gICAgY2xpZW50OiBBbmRyb2lkV2ViVmlld0NsaWVudCB8IG51bGw7XG4gICAgYnJpZGdlSW50ZXJmYWNlPzogZGsubm90YS53ZWJ2aWV3aW50ZXJmYWNlLldlYlZpZXdCcmlkZ2VJbnRlcmZhY2U7XG59XG5cbmxldCBXZWJWaWV3RXh0Q2xpZW50OiBuZXcgKG93bmVyOiBXZWJWaWV3RXh0KSA9PiBBbmRyb2lkV2ViVmlld0NsaWVudDtcbmxldCBXZWJWaWV3QnJpZGdlSW50ZXJmYWNlOiBuZXcgKG93bmVyOiBXZWJWaWV3RXh0KSA9PiBkay5ub3RhLndlYnZpZXdpbnRlcmZhY2UuV2ViVmlld0JyaWRnZUludGVyZmFjZTtcblxuZnVuY3Rpb24gaW5pdGlhbGl6ZVdlYlZpZXdDbGllbnQoKTogdm9pZCB7XG4gICAgaWYgKFdlYlZpZXdFeHRDbGllbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNhY2hlTW9kZU1hcCA9IG5ldyBNYXA8Q2FjaGVNb2RlLCBudW1iZXI+KFtcbiAgICAgICAgW1wiY2FjaGVfZmlyc3RcIiwgYW5kcm9pZC53ZWJraXQuV2ViU2V0dGluZ3MuTE9BRF9DQUNIRV9FTFNFX05FVFdPUktdLFxuICAgICAgICBbXCJjYWNoZV9vbmx5XCIsIGFuZHJvaWQud2Via2l0LldlYlNldHRpbmdzLkxPQURfQ0FDSEVfT05MWV0sXG4gICAgICAgIFtcImRlZmF1bHRcIiwgYW5kcm9pZC53ZWJraXQuV2ViU2V0dGluZ3MuTE9BRF9ERUZBVUxUXSxcbiAgICAgICAgW1wibm9fY2FjaGVcIiwgYW5kcm9pZC53ZWJraXQuV2ViU2V0dGluZ3MuTE9BRF9OT19DQUNIRV0sXG4gICAgXSk7XG5cbiAgICBjbGFzcyBXZWJWaWV3RXh0Q2xpZW50SW1wbCBleHRlbmRzIGFuZHJvaWQud2Via2l0LldlYlZpZXdDbGllbnQge1xuICAgICAgICBjb25zdHJ1Y3RvcihwdWJsaWMgb3duZXI6IFdlYlZpZXdFeHQpIHtcbiAgICAgICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgICAgIHJldHVybiBnbG9iYWwuX19uYXRpdmUodGhpcyk7XG4gICAgICAgIH1cblxuICAgICAgICBwdWJsaWMgc2hvdWxkT3ZlcnJpZGVVcmxMb2FkaW5nKHZpZXc6IGFuZHJvaWQud2Via2l0LldlYlZpZXcsIHJlcXVlc3Q6IGFueSkge1xuICAgICAgICAgICAgY29uc3Qgb3duZXIgPSB0aGlzLm93bmVyO1xuICAgICAgICAgICAgaWYgKCFvd25lcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcIldlYlZpZXdFeHRDbGllbnRJbXBsLnNob3VsZE92ZXJyaWRlVXJsTG9hZGluZyguLi4pIC0gbm8gb3duZXJcIik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCB1cmwgPSByZXF1ZXN0IGFzIHN0cmluZztcbiAgICAgICAgICAgIGxldCBodHRwTWV0aG9kID0gXCJHRVRcIjtcbiAgICAgICAgICAgIGxldCBpc1JlZGlyZWN0ID0gZmFsc2U7XG4gICAgICAgICAgICBsZXQgaGFzR2VzdHVyZSA9IGZhbHNlO1xuICAgICAgICAgICAgbGV0IGlzRm9yTWFpbkZyYW1lID0gZmFsc2U7XG4gICAgICAgICAgICBsZXQgcmVxdWVzdEhlYWRlcnM6IGphdmEudXRpbC5NYXA8c3RyaW5nLCBzdHJpbmc+IHwgbnVsbCA9IG51bGw7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHJlcXVlc3QgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgICAgICBodHRwTWV0aG9kID0gcmVxdWVzdC5nZXRNZXRob2QoKTtcbiAgICAgICAgICAgICAgICBpc1JlZGlyZWN0ID0gcmVxdWVzdC5pc1JlZGlyZWN0KCk7XG4gICAgICAgICAgICAgICAgaGFzR2VzdHVyZSA9IHJlcXVlc3QuaGFzR2VzdHVyZSgpO1xuICAgICAgICAgICAgICAgIGlzRm9yTWFpbkZyYW1lID0gcmVxdWVzdC5pc0Zvck1haW5GcmFtZSgpO1xuICAgICAgICAgICAgICAgIHJlcXVlc3RIZWFkZXJzID0gcmVxdWVzdC5nZXRSZXF1ZXN0SGVhZGVycygpO1xuXG4gICAgICAgICAgICAgICAgdXJsID0gcmVxdWVzdC5nZXRVcmwoKS50b1N0cmluZygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBvd25lci53cml0ZVRyYWNlKFxuICAgICAgICAgICAgICAgIGBXZWJWaWV3