UNPKG

matrix-react-sdk

Version:
126 lines (122 loc) 19.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.fixupColorFonts = fixupColorFonts; var _logger = require("matrix-js-sdk/src/logger"); /* Copyright 2024 New Vector Ltd. Copyright 2019-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. */ /* * Based on... * ChromaCheck 1.16 * author Roel Nieskens, https://pixelambacht.nl * MIT license */ function safariVersionCheck(ua) { _logger.logger.log("Browser is Safari - checking version for COLR support"); try { const safariVersionMatch = ua.match(/Mac OS X ([\d|_]+).*Version\/([\d|.]+).*Safari/); if (safariVersionMatch) { const macOSVersionStr = safariVersionMatch[1]; const safariVersionStr = safariVersionMatch[2]; const macOSVersion = macOSVersionStr.split("_").map(n => parseInt(n, 10)); const safariVersion = safariVersionStr.split(".").map(n => parseInt(n, 10)); const colrFontSupported = macOSVersion[0] >= 10 && macOSVersion[1] >= 14 && safariVersion[0] >= 12 && safariVersion[0] < 17; // https://www.colorfonts.wtf/ states Safari supports COLR fonts from this version on but Safari 17 breaks it _logger.logger.log(`COLR support on Safari requires macOS 10.14 and Safari 12-16, ` + `detected Safari ${safariVersionStr} on macOS ${macOSVersionStr}, ` + `COLR supported: ${colrFontSupported}`); return colrFontSupported; } } catch (err) { _logger.logger.error("Error in Safari COLR version check", err); } _logger.logger.warn("Couldn't determine Safari version to check COLR font support, assuming no."); return false; } async function isColrFontSupported() { _logger.logger.log("Checking for COLR support"); const { userAgent } = navigator; // Firefox has supported COLR fonts since version 26 // but doesn't support the check below without // "Extract canvas data" permissions // when content blocking is enabled. if (userAgent.includes("Firefox")) { _logger.logger.log("Browser is Firefox - assuming COLR is supported"); return true; } // Safari doesn't wait for the font to load (if it doesn't have it in cache) // to emit the load event on the image, so there is no way to not make the check // reliable. Instead sniff the version. // Excluding "Chrome", as it's user agent unhelpfully also contains Safari... if (!userAgent.includes("Chrome") && userAgent.includes("Safari")) { return safariVersionCheck(userAgent); } try { const canvas = document.createElement("canvas"); const context = canvas.getContext("2d"); const img = new Image(); // eslint-disable-next-line const fontCOLR = "d09GRgABAAAAAAKAAAwAAAAAAowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDT0xSAAACVAAAABYAAAAYAAIAJUNQQUwAAAJsAAAAEgAAABLJAAAQT1MvMgAAAYAAAAA6AAAAYBfxJ0pjbWFwAAABxAAAACcAAAAsAAzpM2dseWYAAAH0AAAAGgAAABoNIh0kaGVhZAAAARwAAAAvAAAANgxLumdoaGVhAAABTAAAABUAAAAkCAEEAmhtdHgAAAG8AAAABgAAAAYEAAAAbG9jYQAAAewAAAAGAAAABgANAABtYXhwAAABZAAAABsAAAAgAg4AHW5hbWUAAAIQAAAAOAAAAD4C5wsecG9zdAAAAkgAAAAMAAAAIAADAAB4AWNgZGAAYQ5+qdB4fpuvDNIsDCBwaQGTAIi+VlscBaJZGMDiHAxMIAoAtjIF/QB4AWNgZGBgYQACOAkUQQWMAAGRABAAAAB4AWNgZGBgYGJgAdMMUJILJMQgAWICAAH3AC4AeAFjYGFhYJzAwMrAwDST6QwDA0M/hGZ8zWDMyMmAChgFkDgKQMBw4CXDSwYWEBdIYgAFBgYA/8sIdAAABAAAAAAAAAB4AWNgYGBkYAZiBgYeBhYGBSDNAoRA/kuG//8hpDgjWJ4BAFVMBiYAAAAAAAANAAAAAQAAAAAEAAQAAAMAABEhESEEAPwABAD8AAAAeAEtxgUNgAAAAMHHIQTShTlOAty9/4bf7AARCwlBNhBw4L/43qXjYGUmf19TMuLcj/BJL3XfBg54AWNgZsALAAB9AAR4AWNgYGAEYj4gFgGygGwICQACOwAoAAAAAAABAAEAAQAAAA4AAAAAyP8AAA=="; const svg = ` <svg xmlns="http://www.w3.org/2000/svg" width="20" height="100" style="background:#fff;fill:#000;"> <style type="text/css"> @font-face { font-family: "chromacheck-colr"; src: url(data:application/x-font-woff;base64,${fontCOLR}) format("woff"); } </style> <text x="0" y="0" font-size="20"> <tspan font-family="chromacheck-colr" x="0" dy="20">&#xe900;</tspan> </text> </svg>`; canvas.width = 20; canvas.height = 100; img.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svg); _logger.logger.log("Waiting for COLR SVG to load"); await new Promise(resolve => img.onload = resolve); _logger.logger.log("Drawing canvas to detect COLR support"); context.drawImage(img, 0, 0); const colrFontSupported = context.getImageData(10, 10, 1, 1).data[0] === 200; _logger.logger.log("Canvas check revealed COLR is supported? " + colrFontSupported); return colrFontSupported; } catch (e) { _logger.logger.error("Couldn't load COLR font", e); return false; } } let colrFontCheckStarted = false; async function fixupColorFonts() { if (colrFontCheckStarted) { return; } colrFontCheckStarted = true; if (await isColrFontSupported()) { const path = `url('${require("../../res/fonts/Twemoji_Mozilla/TwemojiMozilla-colr.woff2")}')`; document.fonts.add(new FontFace("Twemoji", path, {})); // For at least Chrome on Windows 10, we have to explictly add extra // weights for the emoji to appear in bold messages, etc. document.fonts.add(new FontFace("Twemoji", path, { weight: "600" })); document.fonts.add(new FontFace("Twemoji", path, { weight: "700" })); } else { // fall back to SBIX, generated via https://github.com/matrix-org/twemoji-colr/tree/matthew/sbix const path = `url('${require("../../res/fonts/Twemoji_Mozilla/TwemojiMozilla-sbix.woff2")}')`; document.fonts.add(new FontFace("Twemoji", path, {})); document.fonts.add(new FontFace("Twemoji", path, { weight: "600" })); document.fonts.add(new FontFace("Twemoji", path, { weight: "700" })); } // ...and if SBIX is not supported, the browser will fall back to one of the native fonts specified. } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9nZ2VyIiwicmVxdWlyZSIsInNhZmFyaVZlcnNpb25DaGVjayIsInVhIiwibG9nZ2VyIiwibG9nIiwic2FmYXJpVmVyc2lvbk1hdGNoIiwibWF0Y2giLCJtYWNPU1ZlcnNpb25TdHIiLCJzYWZhcmlWZXJzaW9uU3RyIiwibWFjT1NWZXJzaW9uIiwic3BsaXQiLCJtYXAiLCJuIiwicGFyc2VJbnQiLCJzYWZhcmlWZXJzaW9uIiwiY29sckZvbnRTdXBwb3J0ZWQiLCJlcnIiLCJlcnJvciIsIndhcm4iLCJpc0NvbHJGb250U3VwcG9ydGVkIiwidXNlckFnZW50IiwibmF2aWdhdG9yIiwiaW5jbHVkZXMiLCJjYW52YXMiLCJkb2N1bWVudCIsImNyZWF0ZUVsZW1lbnQiLCJjb250ZXh0IiwiZ2V0Q29udGV4dCIsImltZyIsIkltYWdlIiwiZm9udENPTFIiLCJzdmciLCJ3aWR0aCIsImhlaWdodCIsInNyYyIsImVuY29kZVVSSUNvbXBvbmVudCIsIlByb21pc2UiLCJyZXNvbHZlIiwib25sb2FkIiwiZHJhd0ltYWdlIiwiZ2V0SW1hZ2VEYXRhIiwiZGF0YSIsImUiLCJjb2xyRm9udENoZWNrU3RhcnRlZCIsImZpeHVwQ29sb3JGb250cyIsInBhdGgiLCJmb250cyIsImFkZCIsIkZvbnRGYWNlIiwid2VpZ2h0Il0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL0ZvbnRNYW5hZ2VyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDE5LTIwMjEgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuLypcbiAqIEJhc2VkIG9uLi4uXG4gKiBDaHJvbWFDaGVjayAxLjE2XG4gKiBhdXRob3IgUm9lbCBOaWVza2VucywgaHR0cHM6Ly9waXhlbGFtYmFjaHQubmxcbiAqIE1JVCBsaWNlbnNlXG4gKi9cbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9sb2dnZXJcIjtcblxuZnVuY3Rpb24gc2FmYXJpVmVyc2lvbkNoZWNrKHVhOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBsb2dnZXIubG9nKFwiQnJvd3NlciBpcyBTYWZhcmkgLSBjaGVja2luZyB2ZXJzaW9uIGZvciBDT0xSIHN1cHBvcnRcIik7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgc2FmYXJpVmVyc2lvbk1hdGNoID0gdWEubWF0Y2goL01hYyBPUyBYIChbXFxkfF9dKykuKlZlcnNpb25cXC8oW1xcZHwuXSspLipTYWZhcmkvKTtcbiAgICAgICAgaWYgKHNhZmFyaVZlcnNpb25NYXRjaCkge1xuICAgICAgICAgICAgY29uc3QgbWFjT1NWZXJzaW9uU3RyID0gc2FmYXJpVmVyc2lvbk1hdGNoWzFdO1xuICAgICAgICAgICAgY29uc3Qgc2FmYXJpVmVyc2lvblN0ciA9IHNhZmFyaVZlcnNpb25NYXRjaFsyXTtcbiAgICAgICAgICAgIGNvbnN0IG1hY09TVmVyc2lvbiA9IG1hY09TVmVyc2lvblN0ci5zcGxpdChcIl9cIikubWFwKChuKSA9PiBwYXJzZUludChuLCAxMCkpO1xuICAgICAgICAgICAgY29uc3Qgc2FmYXJpVmVyc2lvbiA9IHNhZmFyaVZlcnNpb25TdHIuc3BsaXQoXCIuXCIpLm1hcCgobikgPT4gcGFyc2VJbnQobiwgMTApKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbHJGb250U3VwcG9ydGVkID1cbiAgICAgICAgICAgICAgICBtYWNPU1ZlcnNpb25bMF0gPj0gMTAgJiYgbWFjT1NWZXJzaW9uWzFdID49IDE0ICYmIHNhZmFyaVZlcnNpb25bMF0gPj0gMTIgJiYgc2FmYXJpVmVyc2lvblswXSA8IDE3O1xuICAgICAgICAgICAgLy8gaHR0cHM6Ly93d3cuY29sb3Jmb250cy53dGYvIHN0YXRlcyBTYWZhcmkgc3VwcG9ydHMgQ09MUiBmb250cyBmcm9tIHRoaXMgdmVyc2lvbiBvbiBidXQgU2FmYXJpIDE3IGJyZWFrcyBpdFxuICAgICAgICAgICAgbG9nZ2VyLmxvZyhcbiAgICAgICAgICAgICAgICBgQ09MUiBzdXBwb3J0IG9uIFNhZmFyaSByZXF1aXJlcyBtYWNPUyAxMC4xNCBhbmQgU2FmYXJpIDEyLTE2LCBgICtcbiAgICAgICAgICAgICAgICAgICAgYGRldGVjdGVkIFNhZmFyaSAke3NhZmFyaVZlcnNpb25TdHJ9IG9uIG1hY09TICR7bWFjT1NWZXJzaW9uU3RyfSwgYCArXG4gICAgICAgICAgICAgICAgICAgIGBDT0xSIHN1cHBvcnRlZDogJHtjb2xyRm9udFN1cHBvcnRlZH1gLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiBjb2xyRm9udFN1cHBvcnRlZDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBsb2dnZXIuZXJyb3IoXCJFcnJvciBpbiBTYWZhcmkgQ09MUiB2ZXJzaW9uIGNoZWNrXCIsIGVycik7XG4gICAgfVxuICAgIGxvZ2dlci53YXJuKFwiQ291bGRuJ3QgZGV0ZXJtaW5lIFNhZmFyaSB2ZXJzaW9uIHRvIGNoZWNrIENPTFIgZm9udCBzdXBwb3J0LCBhc3N1bWluZyBuby5cIik7XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5hc3luYyBmdW5jdGlvbiBpc0NvbHJGb250U3VwcG9ydGVkKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGxvZ2dlci5sb2coXCJDaGVja2luZyBmb3IgQ09MUiBzdXBwb3J0XCIpO1xuXG4gICAgY29uc3QgeyB1c2VyQWdlbnQgfSA9IG5hdmlnYXRvcjtcbiAgICAvLyBGaXJlZm94IGhhcyBzdXBwb3J0ZWQgQ09MUiBmb250cyBzaW5jZSB2ZXJzaW9uIDI2XG4gICAgLy8gYnV0IGRvZXNuJ3Qgc3VwcG9ydCB0aGUgY2hlY2sgYmVsb3cgd2l0aG91dFxuICAgIC8vIFwiRXh0cmFjdCBjYW52YXMgZGF0YVwiIHBlcm1pc3Npb25zXG4gICAgLy8gd2hlbiBjb250ZW50IGJsb2NraW5nIGlzIGVuYWJsZWQuXG4gICAgaWYgKHVzZXJBZ2VudC5pbmNsdWRlcyhcIkZpcmVmb3hcIikpIHtcbiAgICAgICAgbG9nZ2VyLmxvZyhcIkJyb3dzZXIgaXMgRmlyZWZveCAtIGFzc3VtaW5nIENPTFIgaXMgc3VwcG9ydGVkXCIpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLy8gU2FmYXJpIGRvZXNuJ3Qgd2FpdCBmb3IgdGhlIGZvbnQgdG8gbG9hZCAoaWYgaXQgZG9lc24ndCBoYXZlIGl0IGluIGNhY2hlKVxuICAgIC8vIHRvIGVtaXQgdGhlIGxvYWQgZXZlbnQgb24gdGhlIGltYWdlLCBzbyB0aGVyZSBpcyBubyB3YXkgdG8gbm90IG1ha2UgdGhlIGNoZWNrXG4gICAgLy8gcmVsaWFibGUuIEluc3RlYWQgc25pZmYgdGhlIHZlcnNpb24uXG4gICAgLy8gRXhjbHVkaW5nIFwiQ2hyb21lXCIsIGFzIGl0J3MgdXNlciBhZ2VudCB1bmhlbHBmdWxseSBhbHNvIGNvbnRhaW5zIFNhZmFyaS4uLlxuICAgIGlmICghdXNlckFnZW50LmluY2x1ZGVzKFwiQ2hyb21lXCIpICYmIHVzZXJBZ2VudC5pbmNsdWRlcyhcIlNhZmFyaVwiKSkge1xuICAgICAgICByZXR1cm4gc2FmYXJpVmVyc2lvbkNoZWNrKHVzZXJBZ2VudCk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIikhO1xuICAgICAgICBjb25zdCBpbWcgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgICAgIGNvbnN0IGZvbnRDT0xSID1cbiAgICAgICAgICAgIFwiZDA5R1JnQUJBQUFBQUFLQUFBd0FBQUFBQW93QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUJEVDB4U0FBQUNWQUFBQUJZQUFBQVlBQUlBSlVOUVFVd0FBQUpzQUFBQUVnQUFBQkxKQUFBUVQxTXZNZ0FBQVlBQUFBQTZBQUFBWUJmeEowcGpiV0Z3QUFBQnhBQUFBQ2NBQUFBc0FBenBNMmRzZVdZQUFBSDBBQUFBR2dBQUFCb05JaDBrYUdWaFpBQUFBUndBQUFBdkFBQUFOZ3hMdW1kb2FHVmhBQUFCVEFBQUFCVUFBQUFrQ0FFRUFtaHRkSGdBQUFHOEFBQUFCZ0FBQUFZRUFBQUFiRzlqWVFBQUFld0FBQUFHQUFBQUJnQU5BQUJ0WVhod0FBQUJaQUFBQUJzQUFBQWdBZzRBSFc1aGJXVUFBQUlRQUFBQU9BQUFBRDRDNXdzZWNHOXpkQUFBQWtnQUFBQU1BQUFBSUFBREFBQjRBV05nWkdBQVlRNStxZEI0ZnB1dkROSXNEQ0J3YVFHVEFJaStWbHNjQmFKWkdNRGlIQXhNSUFvQXRqSUYvUUI0QVdOZ1pHQmdZUUFDT0FrVVFRV01BQUdSQUJBQUFBQjRBV05nWkdCZ1lHSmdBZE1NVUpJTEpNUWdBV0lDQUFIM0FDNEFlQUZqWUdGaFlKekF3TXJBd0RTVDZRd0RBME0vaEdaOHpXRE15TW1BQ2hnRmtEZ0tRTUJ3NENYRFN3WVdFQmRJWWdBRkJnWUEvOHNJZEFBQUJBQUFBQUFBQUFCNEFXTmdZR0JrWUFaaUJnWWVCaFlHQlNETkFvUkEva3VHLy84aHBEZ2pXSjRCQUZWTUJpWUFBQUFBQUFBTkFBQUFBUUFBQUFBRUFBUUFBQU1BQUJFaEVTRUVBUHdBQkFEOEFBQUFlQUV0eGdVTmdBQUFBTUhISVFUU2hUbE9BdHk5LzRiZjdBQVJDd2xCTmhCdzRMLzQzcVhqWUdVbWYxOVRNdUxjai9CSkwzWGZCZzU0QVdOZ1pzQUxBQUI5QUFSNEFXTmdZR0FFWWo0Z0ZnR3lnR3dJQ1FBQ093QW9BQUFBQUFBQkFBRUFBUUFBQUE0QUFBQUF5UDhBQUE9PVwiO1xuICAgICAgICBjb25zdCBzdmcgPSBgXG4gICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjBcIiBoZWlnaHQ9XCIxMDBcIiBzdHlsZT1cImJhY2tncm91bmQ6I2ZmZjtmaWxsOiMwMDA7XCI+XG4gICAgICAgICAgICA8c3R5bGUgdHlwZT1cInRleHQvY3NzXCI+XG4gICAgICAgICAgICAgICAgQGZvbnQtZmFjZSB7XG4gICAgICAgICAgICAgICAgICAgIGZvbnQtZmFtaWx5OiBcImNocm9tYWNoZWNrLWNvbHJcIjtcbiAgICAgICAgICAgICAgICAgICAgc3JjOiB1cmwoZGF0YTphcHBsaWNhdGlvbi94LWZvbnQtd29mZjtiYXNlNjQsJHtmb250Q09MUn0pIGZvcm1hdChcIndvZmZcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9zdHlsZT5cbiAgICAgICAgICAgIDx0ZXh0IHg9XCIwXCIgeT1cIjBcIiBmb250LXNpemU9XCIyMFwiPlxuICAgICAgICAgICAgICAgIDx0c3BhbiBmb250LWZhbWlseT1cImNocm9tYWNoZWNrLWNvbHJcIiB4PVwiMFwiIGR5PVwiMjBcIj4mI3hlOTAwOzwvdHNwYW4+XG4gICAgICAgICAgICA8L3RleHQ+XG4gICAgICAgIDwvc3ZnPmA7XG4gICAgICAgIGNhbnZhcy53aWR0aCA9IDIwO1xuICAgICAgICBjYW52YXMuaGVpZ2h0ID0gMTAwO1xuXG4gICAgICAgIGltZy5zcmMgPSBcImRhdGE6aW1hZ2Uvc3ZnK3htbDtjaGFyc2V0PXV0Zi04LFwiICsgZW5jb2RlVVJJQ29tcG9uZW50KHN2Zyk7XG5cbiAgICAgICAgbG9nZ2VyLmxvZyhcIldhaXRpbmcgZm9yIENPTFIgU1ZHIHRvIGxvYWRcIik7XG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiAoaW1nLm9ubG9hZCA9IHJlc29sdmUpKTtcbiAgICAgICAgbG9nZ2VyLmxvZyhcIkRyYXdpbmcgY2FudmFzIHRvIGRldGVjdCBDT0xSIHN1cHBvcnRcIik7XG4gICAgICAgIGNvbnRleHQuZHJhd0ltYWdlKGltZywgMCwgMCk7XG4gICAgICAgIGNvbnN0IGNvbHJGb250U3VwcG9ydGVkID0gY29udGV4dC5nZXRJbWFnZURhdGEoMTAsIDEwLCAxLCAxKS5kYXRhWzBdID09PSAyMDA7XG4gICAgICAgIGxvZ2dlci5sb2coXCJDYW52YXMgY2hlY2sgcmV2ZWFsZWQgQ09MUiBpcyBzdXBwb3J0ZWQ/IFwiICsgY29sckZvbnRTdXBwb3J0ZWQpO1xuICAgICAgICByZXR1cm4gY29sckZvbnRTdXBwb3J0ZWQ7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoXCJDb3VsZG4ndCBsb2FkIENPTFIgZm9udFwiLCBlKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxubGV0IGNvbHJGb250Q2hlY2tTdGFydGVkID0gZmFsc2U7XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZml4dXBDb2xvckZvbnRzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmIChjb2xyRm9udENoZWNrU3RhcnRlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbHJGb250Q2hlY2tTdGFydGVkID0gdHJ1ZTtcblxuICAgIGlmIChhd2FpdCBpc0NvbHJGb250U3VwcG9ydGVkKCkpIHtcbiAgICAgICAgY29uc3QgcGF0aCA9IGB1cmwoJyR7cmVxdWlyZShcIi4uLy4uL3Jlcy9mb250cy9Ud2Vtb2ppX01vemlsbGEvVHdlbW9qaU1vemlsbGEtY29sci53b2ZmMlwiKX0nKWA7XG4gICAgICAgIGRvY3VtZW50LmZvbnRzLmFkZChuZXcgRm9udEZhY2UoXCJUd2Vtb2ppXCIsIHBhdGgsIHt9KSk7XG4gICAgICAgIC8vIEZvciBhdCBsZWFzdCBDaHJvbWUgb24gV2luZG93cyAxMCwgd2UgaGF2ZSB0byBleHBsaWN0bHkgYWRkIGV4dHJhXG4gICAgICAgIC8vIHdlaWdodHMgZm9yIHRoZSBlbW9qaSB0byBhcHBlYXIgaW4gYm9sZCBtZXNzYWdlcywgZXRjLlxuICAgICAgICBkb2N1bWVudC5mb250cy5hZGQobmV3IEZvbnRGYWNlKFwiVHdlbW9qaVwiLCBwYXRoLCB7IHdlaWdodDogXCI2MDBcIiB9KSk7XG4gICAgICAgIGRvY3VtZW50LmZvbnRzLmFkZChuZXcgRm9udEZhY2UoXCJUd2Vtb2ppXCIsIHBhdGgsIHsgd2VpZ2h0OiBcIjcwMFwiIH0pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBmYWxsIGJhY2sgdG8gU0JJWCwgZ2VuZXJhdGVkIHZpYSBodHRwczovL2dpdGh1Yi5jb20vbWF0cml4LW9yZy90d2Vtb2ppLWNvbHIvdHJlZS9tYXR0aGV3L3NiaXhcbiAgICAgICAgY29uc3QgcGF0aCA9IGB1cmwoJyR7cmVxdWlyZShcIi4uLy4uL3Jlcy9mb250cy9Ud2Vtb2ppX01vemlsbGEvVHdlbW9qaU1vemlsbGEtc2JpeC53b2ZmMlwiKX0nKWA7XG4gICAgICAgIGRvY3VtZW50LmZvbnRzLmFkZChuZXcgRm9udEZhY2UoXCJUd2Vtb2ppXCIsIHBhdGgsIHt9KSk7XG4gICAgICAgIGRvY3VtZW50LmZvbnRzLmFkZChuZXcgRm9udEZhY2UoXCJUd2Vtb2ppXCIsIHBhdGgsIHsgd2VpZ2h0OiBcIjYwMFwiIH0pKTtcbiAgICAgICAgZG9jdW1lbnQuZm9udHMuYWRkKG5ldyBGb250RmFjZShcIlR3ZW1vamlcIiwgcGF0aCwgeyB3ZWlnaHQ6IFwiNzAwXCIgfSkpO1xuICAgIH1cbiAgICAvLyAuLi5hbmQgaWYgU0JJWCBpcyBub3Qgc3VwcG9ydGVkLCB0aGUgYnJvd3NlciB3aWxsIGZhbGwgYmFjayB0byBvbmUgb2YgdGhlIG5hdGl2ZSBmb250cyBzcGVjaWZpZWQuXG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQWNBLElBQUFBLE9BQUEsR0FBQUMsT0FBQTtBQWRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFHQSxTQUFTQyxrQkFBa0JBLENBQUNDLEVBQVUsRUFBVztFQUM3Q0MsY0FBTSxDQUFDQyxHQUFHLENBQUMs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