summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrLi2023-01-08 00:42:12 +0800
committerBrLi2023-01-08 00:42:12 +0800
commitac604f42d0c12865aa5aef0d08f28394aadb1d2b (patch)
tree76da8ebc4d3fd0a1eaeba621a76fe1381a653170
parent3e212e864fe9e223a44f301dc6dae614854beae7 (diff)
downloadaur-ac604f42d0c12865aa5aef0d08f28394aadb1d2b.tar.gz
update patch and pkgver
-rw-r--r--.SRCINFO18
-rw-r--r--0001-do-not-download-electron.patch59
-rw-r--r--PKGBUILD27
-rw-r--r--fix-package-json.patch45
-rw-r--r--upstream.patch5539
5 files changed, 80 insertions, 5608 deletions
diff --git a/.SRCINFO b/.SRCINFO
index beaddf613818..aa491d6b3fca 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,20 +1,18 @@
pkgbase = pencil
pkgdesc = Sketching and GUI prototyping/wireframing tool
- pkgver = 3.1.0
- pkgrel = 7
+ pkgver = 3.1.1
+ pkgrel = 1
url = https://github.com/evolus/pencil
arch = any
license = GPL2
makedepends = yarn
- depends = electron
+ depends = electron21
conflicts = evolus-pencil-bin
conflicts = pencil-v2
- source = https://github.com/evolus/pencil/archive/v3.1.0.tar.gz
- source = fix-package-json.patch
- source = upstream.patch
- sha256sums = e14eddd0aad28919cfdf8d47b726f9c75a3a0d2042605e8da96309c23a995f44
- sha256sums = 7094d33707a1fa27b79f296b3083584643150935ac4e464ebd44a82ed04ad036
- sha256sums = 78c28950a497495f3efef0b915283c10fd834c83996471291ae6ac18e3256997
+ options = !strip
+ source = https://github.com/evolus/pencil/archive/v3.1.1.tar.gz
+ source = 0001-do-not-download-electron.patch
+ sha256sums = 84675567281ccdd0d5e273e628cf99a9b76d15245794ef4d38c5bfb2d64c0468
+ sha256sums = 273aa85290169ac313d0990c41d9d697a1266dbca885fc389d9ef8f415d37720
pkgname = pencil
-
diff --git a/0001-do-not-download-electron.patch b/0001-do-not-download-electron.patch
new file mode 100644
index 000000000000..89abc780e3f8
--- /dev/null
+++ b/0001-do-not-download-electron.patch
@@ -0,0 +1,59 @@
+From cc00ba3113081561a4bd2938badc8f05d4729bf9 Mon Sep 17 00:00:00 2001
+From: BrLi <brli@chakralinux.org>
+Date: Sun, 8 Jan 2023 00:24:57 +0800
+Subject: [PATCH] do not download electron
+
+---
+ app/package.json | 2 --
+ package.json | 8 --------
+ 2 files changed, 10 deletions(-)
+
+diff --git a/app/package.json b/app/package.json
+index a0555af..c4099d2 100644
+--- a/app/package.json
++++ b/app/package.json
+@@ -129,8 +129,6 @@
+ }
+ },
+ "scripts": {
+- "postinstall": "install-app-deps",
+- "install-app-deps": "node ./node_modules/electron-builder/out/install-app-deps.js",
+ "start": "./node_modules/.bin/electron .",
+ "start:dev": "./node_modules/.bin/electron . --enable-dev --enable-transparent-visuals",
+ "start:mac": "./node_modules/.bin/electron . --enable-dev",
+diff --git a/package.json b/package.json
+index b3ce0fa..f525c86 100644
+--- a/package.json
++++ b/package.json
+@@ -1,9 +1,6 @@
+ {
+ "name": "Pencil",
+ "devDependencies": {
+- "electron": "16.0.0",
+- "electron-builder": "23.3.3",
+- "electron-rebuild": "^1.8.5",
+ "rimraf": "^2.5.4"
+ },
+ "build": {
+@@ -59,9 +56,6 @@
+ "perMachine": true,
+ "allowToChangeInstallationDirectory": true
+ },
+- "electronDownload": {
+- "cache": ".electron-cache"
+- },
+ "fileAssociations": {
+ "ext": [
+ "ep",
+@@ -72,8 +66,6 @@
+ }
+ },
+ "scripts": {
+- "postinstall": "install-app-deps",
+- "install-app-deps": "node ./node_modules/electron-builder/out/install-app-deps.js",
+ "start": "./node_modules/.bin/electron ./app",
+ "start:dev": "./node_modules/.bin/electron ./app --enable-dev --enable-transparent-visuals",
+ "start:mac": "./node_modules/.bin/electron ./app --enable-dev",
+--
+2.39.0
+
diff --git a/PKGBUILD b/PKGBUILD
index 9b457d168092..825e7374bbd3 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -2,30 +2,29 @@
# Maintainer: BrLi <brli at chakralinux dot org>
pkgname=pencil
-pkgver=3.1.0
-pkgrel=7
+pkgver=3.1.1
+pkgrel=1
pkgdesc="Sketching and GUI prototyping/wireframing tool"
arch=('any')
license=('GPL2')
url="https://github.com/evolus/pencil"
-depends=(electron)
+_electron=electron21
+depends=($_electron)
makedepends=(yarn)
+options=('!strip')
source=("https://github.com/evolus/pencil/archive/v$pkgver.tar.gz"
- 'fix-package-json.patch'
- 'upstream.patch')
-sha256sums=('e14eddd0aad28919cfdf8d47b726f9c75a3a0d2042605e8da96309c23a995f44'
- '7094d33707a1fa27b79f296b3083584643150935ac4e464ebd44a82ed04ad036'
- '78c28950a497495f3efef0b915283c10fd834c83996471291ae6ac18e3256997')
+ '0001-do-not-download-electron.patch')
+sha256sums=('84675567281ccdd0d5e273e628cf99a9b76d15245794ef4d38c5bfb2d64c0468'
+ '273aa85290169ac313d0990c41d9d697a1266dbca885fc389d9ef8f415d37720')
conflicts=('evolus-pencil-bin' 'pencil-v2')
prepare() {
cd "${srcdir}/${pkgname}-${pkgver}"
-
- patch -Np1 -i "${srcdir}/upstream.patch"
# We don't build electron and friends, and don't depends on postinstall script
- patch -Np1 -i "${srcdir}/fix-package-json.patch"
- sed '/^\s*\"electron.*$/d;/postinstall/d' -i app/package.json
+ patch -Np1 -i "${srcdir}/0001-do-not-download-electron.patch"
+
+ rm -rfv {./,app/}{yarn.lock,package-lock.json}
}
build() {
@@ -61,7 +60,7 @@ package() {
install -Dm755 /dev/stdin "${pkgdir}/usr/bin/${pkgname}" <<END
#!/bin/sh
-exec electron /${_destdir} "\$@"
+exec $_electron /${_destdir} "\$@"
END
cd "${srcdir}/${pkgname}-${pkgver}"
@@ -70,7 +69,7 @@ END
# install icons of vary sizes to hi-color theme
for px in 16 24 32 48 64 96 128 256; do
- install -Dm644 "build/icons/${px}x${px}.png" \
+ install -Dm644 "app/build/icons/${px}x${px}.png" \
"${pkgdir}/usr/share/icons/hicolor/${px}x${px}/apps/${pkgname}.png"
done
diff --git a/fix-package-json.patch b/fix-package-json.patch
deleted file mode 100644
index a7e61c18207a..000000000000
--- a/fix-package-json.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From f6b62008495253f0c68ea1a03eb6815e3bd60e97 Mon Sep 17 00:00:00 2001
-From: BrLi <brli@chakralinux.org>
-Date: Mon, 7 Dec 2020 15:58:13 +0800
-Subject: [PATCH] fix package.json
-
----
- package.json | 8 --------
- 1 file changed, 8 deletions(-)
-
-diff --git a/package.json b/package.json
-index 9c2d20c..4ad8321 100644
---- a/package.json
-+++ b/package.json
-@@ -1,9 +1,6 @@
- {
- "name": "Pencil",
- "devDependencies": {
-- "electron": "10.1.5",
-- "electron-builder": "20.28.4",
-- "electron-rebuild": "^1.8.5",
- "rimraf": "^2.5.4"
- },
- "build": {
-@@ -55,9 +52,6 @@
- "perMachine": true,
- "allowToChangeInstallationDirectory": true
- },
-- "electronDownload": {
-- "cache": ".electron-cache"
-- },
- "fileAssociations": {
- "ext": [
- "ep",
-@@ -68,8 +62,6 @@
- }
- },
- "scripts": {
-- "postinstall": "install-app-deps",
-- "install-app-deps": "node ./node_modules/electron-builder/out/install-app-deps.js",
- "start": "./node_modules/.bin/electron ./app",
- "start:dev": "./node_modules/.bin/electron ./app --enable-dev --enable-transparent-visuals",
- "start:mac": "./node_modules/.bin/electron ./app --enable-dev",
---
-2.29.2
-
diff --git a/upstream.patch b/upstream.patch
deleted file mode 100644
index c71cb18b9d73..000000000000
--- a/upstream.patch
+++ /dev/null
@@ -1,5539 +0,0 @@
-diff --git a/app/app.xhtml b/app/app.xhtml
-index fa1f556..869a5f6 100644
---- a/app/app.xhtml
-+++ b/app/app.xhtml
-@@ -4,7 +4,7 @@
- <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://evolus.vn/Namespaces/WebUI/1.0">
- <head>
- <title>Pencil</title>
--
-+ <meta name="viewport" content="width=device-width, initial-scale=1" />
- <link rel="stylesheet" href="css/material-icons.css" />
-
- <link rel="stylesheet" href="css/pencil.css"/>
-@@ -15,6 +15,7 @@
- <script type="text/javascript" src="lib/codemirror/codemirror.js"></script>
- <link rel="stylesheet" href="lib/codemirror/codemirror.css"/>
- <script type="text/javascript" src="lib/codemirror/javascript.js"></script>
-+ <script type="text/javascript" src="lib/codemirror/xml.js"></script>
-
- <!-- Pencil Core -->
- <script type="text/javascript" src="pencil-core/common/pencilNamespaces.js"></script>
-@@ -46,6 +47,7 @@
- <script type="text/javascript" src="pencil-core/canvasHelper/canvasMemento.js"></script>
- <script type="text/javascript" src="pencil-core/canvasHelper/canvasImpl.js"></script>
- <script type="text/javascript" src="pencil-core/canvasHelper/snappingHelper.js"></script>
-+ <script type="text/javascript" src="pencil-core/canvasHelper/GestureHelper.js"></script>
-
- <script type="text/javascript" src="pencil-core/privateCollection/privateCollection.js"></script>
- <script type="text/javascript" src="pencil-core/privateCollection/privateShapeDef.js"></script>
-@@ -147,7 +149,7 @@
-
- <script type="text/javascript" src="pencil-core/clipartBrowser/webUtil.js"></script>
- <script type="text/javascript" src="pencil-core/clipartBrowser/searchEngine.js"></script>
-- <script type="text/javascript" src="pencil-core/clipartBrowser/openClipartSearch.js"></script>
-+ <script type="text/javascript" src="pencil-core/clipartBrowser/newOpenClipartSearch.js"></script>
-
- <!--<script type="text/javascript" src="pencil-core/mainWindow.js"></script>-->
-
-diff --git a/app/css/theme.css b/app/css/theme.css
-index 8db875f..bccd7c3 100644
---- a/app/css/theme.css
-+++ b/app/css/theme.css
-@@ -18,7 +18,7 @@ button {
- white-space: nowrap;
- vertical-align: middle;
- cursor: pointer;
-- border: 1px solid #CCC;
-+ border: none;
- border-radius: 4px;
-
- line-height: 2.4em;
-@@ -27,11 +27,11 @@ button {
-
- border-radius: 0.3ex;
-
-- background: #FFF;
-+ background: #FEFEFE;
-+ color: #000000DD;
- outline: none;
-
- text-shadow: 0px 1px 0px #FFF;
-- background-image: linear-gradient(to bottom, #FFF 0px, #E0E0E0 100%);
- background-repeat: repeat-x;
- display: inline-flex;
- align-items: center;
-diff --git a/app/index.js b/app/index.js
-index 4e0ac9e..79fec6a 100644
---- a/app/index.js
-+++ b/app/index.js
-@@ -4,23 +4,36 @@ const {app, protocol, shell, BrowserWindow} = require("electron");
- const pkg = require("./package.json");
- const fs = require("fs");
- const path = require("path");
-+const os = require("os");
-
--app.commandLine.appendSwitch("allow-file-access-from-files");
--app.commandLine.appendSwitch("allow-file-access");
-+app.commandLine.appendSwitch("no-sandbox");
-+app.commandLine.appendSwitch("allow-file-access-from-files", "1");
-+app.commandLine.appendSwitch("allow-file-access", "1");
- app.commandLine.appendSwitch("disable-smooth-scrolling");
- app.commandLine.appendSwitch("disable-site-isolation-trials");
-
- // Disable hardware acceleration by default for Linux
- // TODO: implement a setting for this one and requires a restart after changing that value
- if (process.platform.trim().toLowerCase() == "linux" && app.disableHardwareAcceleration) {
-- if (process.argv.indexOf("--with-hwa") < 0) {
-+ var useHWAConfig = getAppConfig("core.useHardwareAcceleration");
-+ console.log("useHWAConfig: ", useHWAConfig);
-+ if (process.argv.indexOf("--with-hwa") < 0 && !useHWAConfig) {
- console.log("Hardware acceleration disabled for Linux.");
- app.disableHardwareAcceleration();
- } else {
- console.log("Hardware acceleration forcibly enabled.");
- }
- }
--
-+function getAppConfig(name) {
-+ var p = path.join(path.join(os.homedir(), ".pencil"), "config.json");
-+ try {
-+ var json = fs.readFileSync(p, "utf8");
-+ var data = JSON.parse(json);
-+ return data[name];
-+ } catch (e) {
-+ return undefined;
-+ }
-+}
- global.sharedObject = { appArguments: process.argv };
-
- var handleRedirect = (e, url) => {
-@@ -38,7 +51,8 @@ function createWindow() {
- allowRunningInsecureContent: true,
- allowDisplayingInsecureContent: true,
- defaultEncoding: "UTF-8",
-- nodeIntegration: true
-+ nodeIntegration: true,
-+ enableRemoteModule: true
- },
- };
-
-@@ -60,7 +74,7 @@ function createWindow() {
- mainWindow.maximize();
-
- if (devEnable) {
-- mainWindow.webContents.openDevTools();
-+ //mainWindow.webContents.openDevTools();
- } else {
- mainWindow.setMenu(null);
- }
-@@ -106,9 +120,9 @@ app.on('ready', function() {
-
- fs.readFile(path, function (err, data) {
- if (err) {
-- callback({mimeType: "text/html", data: new Buffer("Not found")});
-+ callback({mimeType: "text/html", data: Buffer.from("Not found")});
- } else {
-- callback({mimeType: "image/jpeg", data: new Buffer(data)});
-+ callback({mimeType: "image/jpeg", data: Buffer.from(data)});
- }
- });
-
-diff --git a/app/lib/codemirror/xml.js b/app/lib/codemirror/xml.js
-new file mode 100644
-index 0000000..73c6e0e
---- /dev/null
-+++ b/app/lib/codemirror/xml.js
-@@ -0,0 +1,413 @@
-+// CodeMirror, copyright (c) by Marijn Haverbeke and others
-+// Distributed under an MIT license: https://codemirror.net/LICENSE
-+
-+(function(mod) {
-+ if (typeof exports == "object" && typeof module == "object") // CommonJS
-+ mod(require("../../lib/codemirror"));
-+ else if (typeof define == "function" && define.amd) // AMD
-+ define(["../../lib/codemirror"], mod);
-+ else // Plain browser env
-+ mod(CodeMirror);
-+})(function(CodeMirror) {
-+"use strict";
-+
-+var htmlConfig = {
-+ autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
-+ 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
-+ 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
-+ 'track': true, 'wbr': true, 'menuitem': true},
-+ implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
-+ 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
-+ 'th': true, 'tr': true},
-+ contextGrabbers: {
-+ 'dd': {'dd': true, 'dt': true},
-+ 'dt': {'dd': true, 'dt': true},
-+ 'li': {'li': true},
-+ 'option': {'option': true, 'optgroup': true},
-+ 'optgroup': {'optgroup': true},
-+ 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
-+ 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
-+ 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
-+ 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
-+ 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
-+ 'rp': {'rp': true, 'rt': true},
-+ 'rt': {'rp': true, 'rt': true},
-+ 'tbody': {'tbody': true, 'tfoot': true},
-+ 'td': {'td': true, 'th': true},
-+ 'tfoot': {'tbody': true},
-+ 'th': {'td': true, 'th': true},
-+ 'thead': {'tbody': true, 'tfoot': true},
-+ 'tr': {'tr': true}
-+ },
-+ doNotIndent: {"pre": true},
-+ allowUnquoted: true,
-+ allowMissing: true,
-+ caseFold: true
-+}
-+
-+var xmlConfig = {
-+ autoSelfClosers: {},
-+ implicitlyClosed: {},
-+ contextGrabbers: {},
-+ doNotIndent: {},
-+ allowUnquoted: false,
-+ allowMissing: false,
-+ allowMissingTagName: false,
-+ caseFold: false
-+}
-+
-+CodeMirror.defineMode("xml", function(editorConf, config_) {
-+ var indentUnit = editorConf.indentUnit
-+ var config = {}
-+ var defaults = config_.htmlMode ? htmlConfig : xmlConfig
-+ for (var prop in defaults) config[prop] = defaults[prop]
-+ for (var prop in config_) config[prop] = config_[prop]
-+
-+ // Return variables for tokenizers
-+ var type, setStyle;
-+
-+ function inText(stream, state) {
-+ function chain(parser) {
-+ state.tokenize = parser;
-+ return parser(stream, state);
-+ }
-+
-+ var ch = stream.next();
-+ if (ch == "<") {
-+ if (stream.eat("!")) {
-+ if (stream.eat("[")) {
-+ if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
-+ else return null;
-+ } else if (stream.match("--")) {
-+ return chain(inBlock("comment", "-->"));
-+ } else if (stream.match("DOCTYPE", true, true)) {
-+ stream.eatWhile(/[\w\._\-]/);
-+ return chain(doctype(1));
-+ } else {
-+ return null;
-+ }
-+ } else if (stream.eat("?")) {
-+ stream.eatWhile(/[\w\._\-]/);
-+ state.tokenize = inBlock("meta", "?>");
-+ return "meta";
-+ } else {
-+ type = stream.eat("/") ? "closeTag" : "openTag";
-+ state.tokenize = inTag;
-+ return "tag bracket";
-+ }
-+ } else if (ch == "&") {
-+ var ok;
-+ if (stream.eat("#")) {
-+ if (stream.eat("x")) {
-+ ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
-+ } else {
-+ ok = stream.eatWhile(/[\d]/) && stream.eat(";");
-+ }
-+ } else {
-+ ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
-+ }
-+ return ok ? "atom" : "error";
-+ } else {
-+ stream.eatWhile(/[^&<]/);
-+ return null;
-+ }
-+ }
-+ inText.isInText = true;
-+
-+ function inTag(stream, state) {
-+ var ch = stream.next();
-+ if (ch == ">" || (ch == "/" && stream.eat(">"))) {
-+ state.tokenize = inText;
-+ type = ch == ">" ? "endTag" : "selfcloseTag";
-+ return "tag bracket";
-+ } else if (ch == "=") {
-+ type = "equals";
-+ return null;
-+ } else if (ch == "<") {
-+ state.tokenize = inText;
-+ state.state = baseState;
-+ state.tagName = state.tagStart = null;
-+ var next = state.tokenize(stream, state);
-+ return next ? next + " tag error" : "tag error";
-+ } else if (/[\'\"]/.test(ch)) {
-+ state.tokenize = inAttribute(ch);
-+ state.stringStartCol = stream.column();
-+ return state.tokenize(stream, state);
-+ } else {
-+ stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
-+ return "word";
-+ }
-+ }
-+
-+ function inAttribute(quote) {
-+ var closure = function(stream, state) {
-+ while (!stream.eol()) {
-+ if (stream.next() == quote) {
-+ state.tokenize = inTag;
-+ break;
-+ }
-+ }
-+ return "string";
-+ };
-+ closure.isInAttribute = true;
-+ return closure;
-+ }
-+
-+ function inBlock(style, terminator) {
-+ return function(stream, state) {
-+ while (!stream.eol()) {
-+ if (stream.match(terminator)) {
-+ state.tokenize = inText;
-+ break;
-+ }
-+ stream.next();
-+ }
-+ return style;
-+ }
-+ }
-+
-+ function doctype(depth) {
-+ return function(stream, state) {
-+ var ch;
-+ while ((ch = stream.next()) != null) {
-+ if (ch == "<") {
-+ state.tokenize = doctype(depth + 1);
-+ return state.tokenize(stream, state);
-+ } else if (ch == ">") {
-+ if (depth == 1) {
-+ state.tokenize = inText;
-+ break;
-+ } else {
-+ state.tokenize = doctype(depth - 1);
-+ return state.tokenize(stream, state);
-+ }
-+ }
-+ }
-+ return "meta";
-+ };
-+ }
-+
-+ function Context(state, tagName, startOfLine) {
-+ this.prev = state.context;
-+ this.tagName = tagName;
-+ this.indent = state.indented;
-+ this.startOfLine = startOfLine;
-+ if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
-+ this.noIndent = true;
-+ }
-+ function popContext(state) {
-+ if (state.context) state.context = state.context.prev;
-+ }
-+ function maybePopContext(state, nextTagName) {
-+ var parentTagName;
-+ while (true) {
-+ if (!state.context) {
-+ return;
-+ }
-+ parentTagName = state.context.tagName;
-+ if (!config.contextGrabbers.hasOwnProperty(parentTagName) ||
-+ !config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
-+ return;
-+ }
-+ popContext(state);
-+ }
-+ }
-+
-+ function baseState(type, stream, state) {
-+ if (type == "openTag") {
-+ state.tagStart = stream.column();
-+ return tagNameState;
-+ } else if (type == "closeTag") {
-+ return closeTagNameState;
-+ } else {
-+ return baseState;
-+ }
-+ }
-+ function tagNameState(type, stream, state) {
-+ if (type == "word") {
-+ state.tagName = stream.current();
-+ setStyle = "tag";
-+ return attrState;
-+ } else if (config.allowMissingTagName && type == "endTag") {
-+ setStyle = "tag bracket";
-+ return attrState(type, stream, state);
-+ } else {
-+ setStyle = "error";
-+ return tagNameState;
-+ }
-+ }
-+ function closeTagNameState(type, stream, state) {
-+ if (type == "word") {
-+ var tagName = stream.current();
-+ if (state.context && state.context.tagName != tagName &&
-+ config.implicitlyClosed.hasOwnProperty(state.context.tagName))
-+ popContext(state);
-+ if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
-+ setStyle = "tag";
-+ return closeState;
-+ } else {
-+ setStyle = "tag error";
-+ return closeStateErr;
-+ }
-+ } else if (config.allowMissingTagName && type == "endTag") {
-+ setStyle = "tag bracket";
-+ return closeState(type, stream, state);
-+ } else {
-+ setStyle = "error";
-+ return closeStateErr;
-+ }
-+ }
-+
-+ function closeState(type, _stream, state) {
-+ if (type != "endTag") {
-+ setStyle = "error";
-+ return closeState;
-+ }
-+ popContext(state);
-+ return baseState;
-+ }
-+ function closeStateErr(type, stream, state) {
-+ setStyle = "error";
-+ return closeState(type, stream, state);
-+ }
-+
-+ function attrState(type, _stream, state) {
-+ if (type == "word") {
-+ setStyle = "attribute";
-+ return attrEqState;
-+ } else if (type == "endTag" || type == "selfcloseTag") {
-+ var tagName = state.tagName, tagStart = state.tagStart;
-+ state.tagName = state.tagStart = null;
-+ if (type == "selfcloseTag" ||
-+ config.autoSelfClosers.hasOwnProperty(tagName)) {
-+ maybePopContext(state, tagName);
-+ } else {
-+ maybePopContext(state, tagName);
-+ state.context = new Context(state, tagName, tagStart == state.indented);
-+ }
-+ return baseState;
-+ }
-+ setStyle = "error";
-+ return attrState;
-+ }
-+ function attrEqState(type, stream, state) {
-+ if (type == "equals") return attrValueState;
-+ if (!config.allowMissing) setStyle = "error";
-+ return attrState(type, stream, state);
-+ }
-+ function attrValueState(type, stream, state) {
-+ if (type == "string") return attrContinuedState;
-+ if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;}
-+ setStyle = "error";
-+ return attrState(type, stream, state);
-+ }
-+ function attrContinuedState(type, stream, state) {
-+ if (type == "string") return attrContinuedState;
-+ return attrState(type, stream, state);
-+ }
-+
-+ return {
-+ startState: function(baseIndent) {
-+ var state = {tokenize: inText,
-+ state: baseState,
-+ indented: baseIndent || 0,
-+ tagName: null, tagStart: null,
-+ context: null}
-+ if (baseIndent != null) state.baseIndent = baseIndent
-+ return state
-+ },
-+
-+ token: function(stream, state) {
-+ if (!state.tagName && stream.sol())
-+ state.indented = stream.indentation();
-+
-+ if (stream.eatSpace()) return null;
-+ type = null;
-+ var style = state.tokenize(stream, state);
-+ if ((style || type) && style != "comment") {
-+ setStyle = null;
-+ state.state = state.state(type || style, stream, state);
-+ if (setStyle)
-+ style = setStyle == "error" ? style + " error" : setStyle;
-+ }
-+ return style;
-+ },
-+
-+ indent: function(state, textAfter, fullLine) {
-+ var context = state.context;
-+ // Indent multi-line strings (e.g. css).
-+ if (state.tokenize.isInAttribute) {
-+ if (state.tagStart == state.indented)
-+ return state.stringStartCol + 1;
-+ else
-+ return state.indented + indentUnit;
-+ }
-+ if (context && context.noIndent) return CodeMirror.Pass;
-+ if (state.tokenize != inTag && state.tokenize != inText)
-+ return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
-+ // Indent the starts of attribute names.
-+ if (state.tagName) {
-+ if (config.multilineTagIndentPastTag !== false)
-+ return state.tagStart + state.tagName.length + 2;
-+ else
-+ return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1);
-+ }
-+ if (config.alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
-+ var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
-+ if (tagAfter && tagAfter[1]) { // Closing tag spotted
-+ while (context) {
-+ if (context.tagName == tagAfter[2]) {
-+ context = context.prev;
-+ break;
-+ } else if (config.implicitlyClosed.hasOwnProperty(context.tagName)) {
-+ context = context.prev;
-+ } else {
-+ break;
-+ }
-+ }
-+ } else if (tagAfter) { // Opening tag spotted
-+ while (context) {
-+ var grabbers = config.contextGrabbers[context.tagName];
-+ if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
-+ context = context.prev;
-+ else
-+ break;
-+ }
-+ }
-+ while (context && context.prev && !context.startOfLine)
-+ context = context.prev;
-+ if (context) return context.indent + indentUnit;
-+ else return state.baseIndent || 0;
-+ },
-+
-+ electricInput: /<\/[\s\w:]+>$/,
-+ blockCommentStart: "<!--",
-+ blockCommentEnd: "-->",
-+
-+ configuration: config.htmlMode ? "html" : "xml",
-+ helperType: config.htmlMode ? "html" : "xml",
-+
-+ skipAttribute: function(state) {
-+ if (state.state == attrValueState)
-+ state.state = attrState
-+ },
-+
-+ xmlCurrentTag: function(state) {
-+ return state.tagName ? {name: state.tagName, close: state.type == "closeTag"} : null
-+ },
-+
-+ xmlCurrentContext: function(state) {
-+ var context = []
-+ for (var cx = state.context; cx; cx = cx.prev)
-+ if (cx.tagName) context.push(cx.tagName)
-+ return context.reverse()
-+ }
-+ };
-+});
-+
-+CodeMirror.defineMIME("text/xml", "xml");
-+CodeMirror.defineMIME("application/xml", "xml");
-+if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
-+ CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
-+
-+});
-diff --git a/app/lib/widget/Common.js b/app/lib/widget/Common.js
-index c8b208c..4b322f0 100644
---- a/app/lib/widget/Common.js
-+++ b/app/lib/widget/Common.js
-@@ -597,6 +597,13 @@ widget.reloadDesktopFont = function() {
- }
- document.body.style.fontSize = size;
- }
-+
-+ var family = Config.get(Config.UI_CUSTOM_FONT_FAMILY);
-+ if (family) document.body.style.fontFamily = family;
-+
-+ var size = Config.get(Config.UI_CUSTOM_FONT_SIZE);
-+ if (size) document.body.style.fontSize = size;
-+
- resolve(config);
- });
- });
-diff --git a/app/lib/widget/Tree.js b/app/lib/widget/Tree.js
-index 266bf36..f1658d7 100644
---- a/app/lib/widget/Tree.js
-+++ b/app/lib/widget/Tree.js
-@@ -90,6 +90,8 @@ widget.Tree = function() {
- if (!target || !Dom.hasClass(target, "Checkbox") || target.nodeName.toLowerCase() != "input") return;
- if (target.disabled) return;
-
-+ if (event.which == 2) target.checked = !target.checked;
-+
- var treeContainer = Dom.findUpward(target, {
- eval: function(n) {
- return n._tree;
-@@ -102,7 +104,7 @@ widget.Tree = function() {
- if ((target.checked && tree.options.propagateCheckActionDownwards)
- || (!target.checked && tree.options.propagateUncheckActionDownwards)) {
- var itemNode = target.parentNode.parentNode;
-- setItemsCheckedRecursivelyFromNodes(getChildrenContainerFromItemNode(itemNode).childNodes, target.checked);
-+ if (event.which != 2) setItemsCheckedRecursivelyFromNodes(getChildrenContainerFromItemNode(itemNode).childNodes, target.checked);
- }
-
- Dom.emitEvent("blur", treeContainer, {});
-@@ -189,13 +191,13 @@ widget.Tree = function() {
- this.ensureNodeExpanded(itemNode);
- }
- };
--
-+
- /*
- Tree.prototype.sort = function(item) {
- if (item.sort) return;
- if (item.children && item.children.length > 0) {
- item.children.sort(sortNameByAsc);
--
-+
- for (var i = 0; i < item.children.length; i++) {
- if (item.children[i].children && item.children[i].children.length > 0) {
- this.sort(item.children[i]);
-@@ -204,11 +206,11 @@ widget.Tree = function() {
- }
- };
- */
--
-+
- Tree.prototype.loadChildren = function(parentItem, childrenContainer, callback) {
- Dom.addClass(childrenContainer, "Loading");
- var thiz = this;
--
-+
- this.source(parentItem, function(children) {
- childrenContainer.innerHTML = "";
- if (!children) children = [];
-@@ -456,7 +458,7 @@ widget.Tree = function() {
- this.listener = listener;
- return this;
- };
--
-+
- Tree.prototype.findParentItem = function (contextNode) {
- var thiz = this;
- var node = Dom.findUpward(contextNode, {
-@@ -464,15 +466,15 @@ widget.Tree = function() {
- return n._item || n == thiz.container;
- }
- });
--
-+
- if (!node || !node._item) return null;
--
-+
- node = Dom.findUpward(node.parentNode, {
- eval: function (n) {
- return n._item || n == thiz.container;
- }
- });
--
-+
- if (node && node._item) return node._item;
- return null;
- };
-diff --git a/app/package-lock.json b/app/package-lock.json
-index f002744..d5c1306 100644
---- a/app/package-lock.json
-+++ b/app/package-lock.json
-@@ -1,6 +1,6 @@
- {
- "name": "Pencil",
-- "version": "3.0.5",
-+ "version": "3.1.0",
- "lockfileVersion": 1,
- "requires": true,
- "dependencies": {
-@@ -3235,6 +3235,29 @@
- "version": "2.11.0",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
- "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE="
-+ },
-+ "tar": {
-+ "version": "2.2.2",
-+ "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
-+ "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
-+ "requires": {
-+ "block-stream": "*",
-+ "fstream": "^1.0.12",
-+ "inherits": "2"
-+ },
-+ "dependencies": {
-+ "fstream": {
-+ "version": "1.0.12",
-+ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
-+ "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
-+ "requires": {
-+ "graceful-fs": "^4.1.2",
-+ "inherits": "~2.0.0",
-+ "mkdirp": ">=0.5 0",
-+ "rimraf": "2"
-+ }
-+ }
-+ }
- }
- }
- },
-diff --git a/app/pencil-core/canvasHelper/GestureHelper.js b/app/pencil-core/canvasHelper/GestureHelper.js
-new file mode 100644
-index 0000000..cba1dd0
---- /dev/null
-+++ b/app/pencil-core/canvasHelper/GestureHelper.js
-@@ -0,0 +1,86 @@
-+function GestureHelper(canvas) {
-+ this.canvas = canvas;
-+ this.canvas.gestureHelper = this;
-+
-+ this.init();
-+}
-+
-+GestureHelper.prototype.init = function () {
-+ var thiz = this;
-+ this.heldKeyCodes = [];
-+
-+ this.canvas.focusableBox.addEventListener("keydown", function (event) {
-+ if (thiz.heldKeyCodes.indexOf(event.keyCode) >= 0) return;
-+
-+ thiz.heldKeyCodes.push(event.keyCode);
-+ thiz.updateKeyCodes();
-+ }, false);
-+
-+ this.canvas.focusableBox.addEventListener("keyup", function (event) {
-+ var index = thiz.heldKeyCodes.indexOf(event.keyCode);
-+ if (index < 0) return;
-+
-+ thiz.heldKeyCodes.splice(index, 1);
-+ thiz.updateKeyCodes();
-+ }, false);
-+
-+ this.canvas.focusableBox.addEventListener("blur", function (event) {
-+ thiz.heldKeyCodes.length = 0;
-+ thiz.updateKeyCodes();
-+ }, false);
-+
-+ // sample registry
-+ this.gestureRegistry = {
-+ keys: {
-+ "R": {
-+ type: "Shape",
-+ defId: "dgthanhan.MaterialDesktopMockup:rectangle"
-+ }
-+ }
-+ };
-+};
-+
-+GestureHelper.prototype.handleMouseDown = function (event) {
-+ if (!this.activeGestureDef) return false;
-+ if (this.activeGestureDef.type == "Shape") {
-+ var def = CollectionManager.shapeDefinition.locateDefinition(this.activeGestureDef.defId);
-+ if (!def) return;
-+
-+ var loc = this.canvas.getEventLocation(event);
-+ this.canvas.insertShape(def);
-+
-+ var controller = this.canvas.currentController;
-+ var bbox = controller.getBoundingRect();
-+ controller.moveBy(loc.x, loc.y, true);
-+ controller.setProperty("box", new Dimension(0, 0));
-+
-+ this.canvas.selectShape(controller.svg);
-+ window.setTimeout(function () {
-+ this.canvas.geometryEditor.handleMouseDown(event);
-+ this.canvas.geometryEditor.currentAnchor = this.canvas.geometryEditor.anchor4;
-+ }.bind(this), 10);
-+
-+ return true;
-+ }
-+
-+ return false;
-+};
-+GestureHelper.prototype.handleMouseUp = function (event) {
-+ return false;
-+};
-+GestureHelper.prototype.updateKeyCodes = function () {
-+ if (!GestureHelper._output) {
-+ GestureHelper._output = document.createElement("div");
-+ ApplicationPane._instance.contentHeader.appendChild(GestureHelper._output);
-+ }
-+
-+ this.activeGestureDef = null;
-+
-+ for (var code of this.heldKeyCodes) {
-+ var c = String.fromCharCode(code);
-+ this.activeGestureDef = this.gestureRegistry.keys[c];
-+ if (this.activeGestureDef) break;
-+ }
-+
-+ GestureHelper._output.innerHTML = this.heldKeyCodes.join(", ");
-+};
-diff --git a/app/pencil-core/canvasHelper/snappingHelper.js b/app/pencil-core/canvasHelper/snappingHelper.js
-index 5d2f2f8..fff47ad 100644
---- a/app/pencil-core/canvasHelper/snappingHelper.js
-+++ b/app/pencil-core/canvasHelper/snappingHelper.js
-@@ -4,8 +4,6 @@ function SnappingHelper(canvas) {
- Config.set("object.snapping.enabled", true);
- }
- this.init();
--
-- //var this = new SnappingHelper
- };
- SnappingHelper.prototype.isGridSnappingEnabled = function () {
- return Config.get("edit.snap.grid") == true;
-@@ -113,20 +111,20 @@ SnappingHelper.prototype.rebuildSnappingGuide = function () {
- }
-
- var margin = (Pencil.controller && !this.canvas.options.ignorePageMarging) ? Pencil.controller.getDocumentPageMargin() : 0;
-- if (margin) {
-- var uid = Util.newUUID();
-- this.snappingGuide[uid] = {
-- vertical: [
-- new SnappingData("MarginSnap", margin, "Left", true, uid),
-- new SnappingData("MarginSnap", this.canvas.width - margin, "Right", true, uid)
-- ],
-- horizontal: [
-- new SnappingData("MarginSnap", margin, "Top", false, uid),
-- new SnappingData("MarginSnap", this.canvas.height - margin, "Bottom", false, uid)
-- ]
-- };
--
-- }
-+ margin = parseInt(margin, 10);
-+ if (isNaN(margin) || margin < 0) margin = 0;
-+ var uid = Util.newUUID();
-+ var snap = {
-+ vertical: [
-+ new SnappingData("MarginSnap", margin, "Left", true, uid),
-+ new SnappingData("MarginSnap", this.canvas.width - margin, "Right", true, uid)
-+ ],
-+ horizontal: [
-+ new SnappingData("MarginSnap", margin, "Top", false, uid),
-+ new SnappingData("MarginSnap", this.canvas.height - margin, "Bottom", false, uid)
-+ ]
-+ };
-+ this.snappingGuide[uid] = snap;
-
- this.sortData();
- };
-@@ -148,6 +146,9 @@ SnappingHelper.prototype.updateSnappingGuide = function (controller, remove) {
- this.sortData();
- }
- };
-+SnappingHelper.prototype.onControllerSnapshot = function (controller) {
-+ this.lastSnappingGuideSnapshot = (controller && controller.getSnappingGuide) ? controller.getSnappingGuide() : null;
-+};
- SnappingHelper.prototype.sortData = function () {
- var x = [];
- var y = [];
-@@ -162,106 +163,103 @@ SnappingHelper.prototype.sortData = function () {
- this.snappedX = false;
- this.snappedY = false;
- };
--SnappingHelper.prototype.findSnapping = function (drawX, drawY, ghost, snap, shift, grid) {
-- if (!this.isSnappingEnabled()) return;
-- try {
-- if (drawX && !grid) {
-- this.clearSnappingGuideX();
-- }
-- if (drawY && !grid) {
-- this.clearSnappingGuideY();
-- }
--
-- //debug("start ***");
-- if (!ghost && (!this.canvas.controllerHeld || !this.canvas.currentController || !this.canvas.currentController.getSnappingGuide)) return null;
--
-- var _snap = snap ? snap : Pencil.SNAP;
-- if (shift) {
-- _snap = 1;
-- }
--
-- var b = !ghost ? this.canvas.currentController.getSnappingGuide() : ghost;
-+SnappingHelper.prototype.applySnapping = function (dx, dy, controller) {
-+ if (!this.isSnappingEnabled()) return null;
-+ if (!this.lastSnappingGuideSnapshot) return null;
-+ var currentControllerId = controller.id;
-
-- var snappingData = this.findSnappingImpl(this.canvas.currentController, b, _snap, grid);
-- var currentDx = Pencil.SNAP + 10;
-- var currentDy = Pencil.SNAP + 10;
-- if (grid) {
-- currentDx = Pencil.getGridSize().w;
-- currentDy = Pencil.getGridSize().h;
-- }
-+ var xsnap = this.applySnappingValue(dx, this.lastSnappingGuideSnapshot.vertical, this.lastXData, controller);
-+ var ysnap = this.applySnappingValue(dy, this.lastSnappingGuideSnapshot.horizontal, this.lastYData, controller);
-
-- var snapDelta = {
-- dx: 0, dy: 0
-- };
-+ this.drawSnaps(xsnap, ysnap);
-
-- if (snappingData.bestVertical) {
-- if (Math.abs(snappingData.bestVertical.dx) < Math.abs(currentDx)) {
-- currentDx = snappingData.bestVertical.dx;
-- }
-+ return {
-+ xsnap: xsnap,
-+ ysnap: ysnap
-+ };
-+};
-+SnappingHelper.prototype.drawSnaps = function (xsnap, ysnap) {
-+ var thiz = this;
-
-- if (Math.abs(currentDx) < _snap) {
-- if (drawX && !grid) {
-- for (var l = 0; l < snappingData.verticals.length; l++) {
-- var verticalGuide = document.createElementNS(PencilNamespaces.svg, "line");
-+ this.clearSnappingGuideX();
-+ if (xsnap && xsnap.matchingGuides) {
-+ xsnap.matchingGuides.forEach(function (guide) {
-+ var verticalGuide = document.createElementNS(PencilNamespaces.svg, "line");
-
-- verticalGuide.setAttribute("class", snappingData.verticals[l].x.type);
-- verticalGuide.setAttribute("x1", Math.round(snappingData.verticals[l].x.pos) * this.canvas.zoom);
-- verticalGuide.setAttribute("y1", 0);
-- verticalGuide.setAttribute("x2", Math.round(snappingData.verticals[l].x.pos) * this.canvas.zoom);
-- verticalGuide.setAttribute("y2", this.canvas.height * this.canvas.zoom);
-+ verticalGuide.setAttribute("class", guide.type);
-+ verticalGuide.setAttribute("x1", Math.round(guide.pos * thiz.canvas.zoom));
-+ verticalGuide.setAttribute("y1", 0);
-+ verticalGuide.setAttribute("x2", Math.round(guide.pos * thiz.canvas.zoom));
-+ verticalGuide.setAttribute("y2", Math.round(thiz.canvas.height * thiz.canvas.zoom));
-
-- this.snappingGuideContainerX.appendChild(verticalGuide);
-+ thiz.snappingGuideContainerX.appendChild(verticalGuide);
-
-- this._snappingGuideContainerXEmpty = false;
-- }
-- }
-- if (grid) {
-- this.unsnapX = (Pencil.getGridSize().w / 2) + 3;
-- } else {
-- this.unsnapX = Pencil.UNSNAP;
-- }
-- snapDelta.dx = currentDx;
-- }
-- }
-+ thiz._snappingGuideContainerXEmpty = false;
-+ });
-+ }
-
-- if (snappingData.bestHorizontal) {
-- if (Math.abs(snappingData.bestHorizontal.dy) < Math.abs(currentDy)) {
-- currentDy = snappingData.bestHorizontal.dy;
-- }
-- if (Math.abs(currentDy) < _snap) {
-- if (drawY && !grid) {
-- for (var l = 0; l < snappingData.horizontals.length; l++) {
-- var horizontalGuide = document.createElementNS(PencilNamespaces.svg, "line");
-+ this.clearSnappingGuideY();
-+ if (ysnap && ysnap.matchingGuides) {
-+ ysnap.matchingGuides.forEach(function (guide) {
-+ var horizontalGuide = document.createElementNS(PencilNamespaces.svg, "line");
-
-- horizontalGuide.setAttribute("class", snappingData.horizontals[l].y.type);
-- horizontalGuide.setAttribute("x1", 0 * this.canvas.zoom);
-- horizontalGuide.setAttribute("y1", Math.round(snappingData.horizontals[l].y.pos) * this.canvas.zoom);
-- horizontalGuide.setAttribute("x2", this.canvas.width * this.canvas.zoom);
-- horizontalGuide.setAttribute("y2", Math.round(snappingData.horizontals[l].y.pos) * this.canvas.zoom);
-+ horizontalGuide.setAttribute("class", guide.type);
-+ horizontalGuide.setAttribute("x1", 0);
-+ horizontalGuide.setAttribute("y1", Math.round(guide.pos * thiz.canvas.zoom));
-+ horizontalGuide.setAttribute("x2", Math.round(thiz.canvas.width * thiz.canvas.zoom));
-+ horizontalGuide.setAttribute("y2", Math.round(guide.pos * thiz.canvas.zoom));
-
-- this.snappingGuideContainerY.appendChild(horizontalGuide);
-+ thiz.snappingGuideContainerY.appendChild(horizontalGuide);
-
-- this._snappingGuideContainerYEmpty = false;
-- }
-- }
-- if (grid) {
-- this.unsnapY = (Pencil.getGridSize().h / 2) + 3;
-- } else {
-- this.unsnapY = Pencil.UNSNAP;
-- }
-- snapDelta.dy = currentDy;
-+ thiz._snappingGuideContainerYEmpty = false;
-+ });
-+ }
-+};
-+SnappingHelper.prototype.applySnappingValue = function (d, controllerPositions, canvasPositions, controller) {
-+ var currentControllerId = controller.id;
-+ var closestDistance = Number.MAX_VALUE;
-+ var closestDelta = undefined;
-+ var closestGuide = undefined;
-+ var matchingGuides = [];
-+ canvasPositions.forEach(function (canvasGuide) {
-+ if (!canvasGuide || canvasGuide.id == currentControllerId || canvasGuide.disabled) return;
-+ if (controller.containsControllerId && controller.containsControllerId(canvasGuide.id)) return;
-+
-+ controllerPositions.forEach(function (controllerGuide) {
-+ if (!controllerGuide || controllerGuide.disabled) return;
-+
-+ var delta = canvasGuide.pos - (controllerGuide.pos + d);
-+ var distance = Math.abs(delta);
-+ if (distance < closestDistance) {
-+ closestDistance = distance;
-+ closestDelta = delta;
-+ closestGuide = canvasGuide;
-+ matchingGuides = [canvasGuide];
-+ } else if (delta == closestDelta) {
-+ matchingGuides.push(canvasGuide);
- }
-- }
-+ });
-+ });
-
-- //debug("end ***");
-- return snapDelta;
-- } catch(e) {
-- error(e);
-+ if (closestDistance <= Pencil.SNAP) {
-+ return {
-+ d: d + closestDelta,
-+ matchingGuides: matchingGuides
-+ }
-+ } else {
-+ return null;
- }
--
-- return null;
- };
-+
- SnappingHelper.prototype.sort = function(d) {
-+ // var d2 = [];
-+ // var positions = [];
-+ // d.forEach(function (v) {
-+ // if (positions.indexOf(v.pos) >= 0) return;
-+ // d2.push(v);
-+ // positions.push(v.pos);
-+ // });
-+ // d = d2;
- for (var i = 0; i < d.length - 1; i++) {
- for (var j = i + 1; j < d.length; j++) {
- if (d[j].pos < d[i].pos) {
-@@ -284,106 +282,3 @@ SnappingHelper.prototype.allowSnapping = function (v, x) {
-
- return false;
- };
--SnappingHelper.prototype.findSnappingImpl = function(controller, ghost, snap, grid) {
--
-- try {
-- var c = !ghost ? controller.getSnappingGuide() : ghost;
-- var currentControllerId = controller.id;
--
-- var verticals = [];
-- var horizontals = [];
--
-- var x = this.lastXData;
-- var y = this.lastYData;
--
-- var _minsnap = snap ? snap : Pencil.SNAP;
--
-- var bestV = null;
-- for (var v = 0; v < c.vertical.length; v++) {
-- var vertical = { };
-- for (var i = 0; i < x.length; i++) {
-- if (!x[i].disabled
-- && !c.vertical[v].disabled
-- && x[i].id != currentControllerId
-- && (!controller.containsControllerId || !controller.containsControllerId(x[i].id))
-- && this.allowSnapping(c.vertical[v], x[i])) {
-- if ((grid && x[i].type == "GridSnap" && Math.abs(x[i].pos - c.vertical[v].pos) <= _minsnap)
-- || (!grid && x[i].type != "GridSnap" && Math.abs(x[i].pos - c.vertical[v].pos) <= _minsnap)) {
--
-- _minsnap = Math.abs(x[i].pos - c.vertical[v].pos);
-- vertical.x = x[i];
-- vertical.dx = x[i].pos - c.vertical[v].pos;
--
-- if (!bestV || Math.abs(bestV.dx > vertical.dx)) {
-- bestV = vertical;
-- }
-- }
-- }
-- }
-- if (vertical.x) {
-- verticals.push(vertical);
-- }
-- }
--
-- //debug("found: " + verticals.length);
-- //for (var v = 0; v < verticals.length; v++) {
-- // debug(verticals[v].toSource());
-- //}
--
-- // if (verticals.length > 0) {
-- // while (Math.abs(verticals[0].dx) != Math.abs(verticals[verticals.length - 1].dx)) {
-- // //debug("delete");
-- // verticals.splice(0, 1);
-- // }
-- // }
--
-- var _minsnap = snap ? snap : Pencil.SNAP;
--
-- var bestH = null;
-- for (var v = 0; v < c.horizontal.length; v++) {
-- var horizontal = { };
-- for (var i = 0; i < y.length; i++) {
-- if (!y[i].disabled
-- && !c.horizontal[v].disabled
-- && y[i].id != currentControllerId
-- && (!controller.containsControllerId || !controller.containsControllerId(y[i].id))
-- && this.allowSnapping(c.horizontal[v], y[i])) {
-- if ((grid && y[i].type == "GridSnap" && Math.abs(y[i].pos - c.horizontal[v].pos) <= _minsnap)
-- || (!grid && y[i].type != "GridSnap" && Math.abs(y[i].pos - c.horizontal[v].pos) <= _minsnap)) {
--
-- _minsnap = Math.abs(y[i].pos - c.horizontal[v].pos);
-- horizontal.y = y[i];
-- horizontal.dy = y[i].pos - c.horizontal[v].pos;
--
-- if (!bestH || Math.abs(bestH.dy > horizontal.dy)) {
-- bestH = horizontal;
-- }
-- }
-- }
-- }
-- if (horizontal.y) {
-- horizontals.push(horizontal);
-- }
-- }
--
-- //debug("found: " + horizontals.length);
-- //for (var v = 0; v < horizontals.length; v++) {
-- // debug(horizontals[v].toSource());
-- //}
--
-- // if (horizontals.length > 0) {
-- // while (Math.abs(horizontals[0].dy) != Math.abs(horizontals[horizontals.length - 1].dy)) {
-- // horizontals.splice(0, 1);
-- // }
-- // }
--
-- return {
-- verticals: verticals.sort(function (a, b) { return Math.abs(a.dx) - Math.abs(b.dx)}),
-- horizontals: horizontals.sort(function (a, b) { return Math.abs(a.dy) - Math.abs(b.dy)}),
-- bestVertical: bestV,
-- bestHorizontal: bestH
-- };
-- } catch(e) {
-- Console.dumpError(e);
-- }
--};
-diff --git a/app/pencil-core/clipartBrowser/newOpenClipartSearch.js b/app/pencil-core/clipartBrowser/newOpenClipartSearch.js
-index 57f317c..7f5fe1b 100644
---- a/app/pencil-core/clipartBrowser/newOpenClipartSearch.js
-+++ b/app/pencil-core/clipartBrowser/newOpenClipartSearch.js
-@@ -1,275 +1,80 @@
-
- function OpenClipartSearch2() {
-- this.title = "OpenClipart.org (API)";
-- this.name = "OpenClipart.org (API)";
-+ this.title = "OpenClipart.org (cchost)";
-+ this.name = "OpenClipart.org (cchost)";
- this.uri = "http://openclipart.org/";
-
- this.icon = "data:image/png;base64," +
-- "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" +
-- "OcJp9XCvYoAsH/B//9k=";
--
--
-- this.baseUri = "http://openclipart.org/api/search/";
-+ "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" +
-+ "/xX/BwSxr+GgTUkRAAAAAElFTkSuQmCC";
-+
-+
-+ this.baseUri = "http://www.openclipart.org/cchost/media/api/search";
-
- this.options = {
-- page: 1
-+ offset: this.offset,
-+ limit: this.limit,
-+ f: "js"
- };
-
- this.req = [];
-@@ -313,7 +118,7 @@ OpenClipartSearch2.prototype.searchImpl = function(query, options, callback) {
-
- var thiz = this;
- debug("OpenClipart: searching '" + query + "'");
-- debug("url: " + url);
-+ //debug("url: " + url);
- WebUtil.get(url, function(response) {
- var r = thiz.parseSearchResult(response);
- if (callback) {
-@@ -321,114 +126,25 @@ OpenClipartSearch2.prototype.searchImpl = function(query, options, callback) {
- }
- }, this.req);
- };
-+
- OpenClipartSearch2.prototype.parseSearchResult = function (response) {
- var r = {result: [], resultCount: 0};
- if (!response) return r;
- try {
-- var dom = Dom.parseDocument(response);
--
-- Dom.workOn("//*/item", dom, function (itemNode) {
-- var item = {
-- name: Dom.getSingleValue("./title/text()", itemNode),
-- des: Dom.getSingleValue("./description/text()", itemNode),
-- src: Dom.getSingleValue("./enclosure/@url", itemNode),
-- type: Dom.getSingleValue("./enclosure/@type", itemNode),
-- length: Dom.getSingleValue("./enclosure/@length", itemNode),
-- thumb: Dom.getSingleValue("./media:thumbnail/@url", itemNode),
-- creator: Dom.getSingleValue("./dc:creator/text()", itemNode),
-- license: Dom.getSingleValue("./rcc:license/text()", itemNode),
-- pubDate: Dom.getSingleValue("./pubDate/text()", itemNode),
-- link: Dom.getSingleValue("./link/text()", itemNode)
-- };
-+ // FIXME: should use JSON parser
-+ response = JSON.parse(response);
-+ r.resultCount = response.length;
-+ for (var i = 0; i < response.length; i++) {
-+ var item = {name: response[i].upload_name, author: response[i].user_real_name, desc: response[i].upload_description, images: []};
-+ for (var j = 0; j < response[i].files.length; j++) {
-+ item.images.push({src: response[i].files[j].download_url, type: response[i].files[j].file_format_info.mime_type, typeName: this.formatType(response[i].files[j].file_format_info.mime_type), size: response[i].files[j].file_rawsize});
-+ }
- r.result.push(item);
-- });
-+ }
- } catch (e) {
-- error("error: " + e);
-+ Console.dumpError(e);
- }
- return r;
- };
-
--function OpenClipartHandler() {
-- this.items = [];
-- this.currentItem = null;
-- this.currentState = OpenClipartHandler.STATE_CHANNEL;
--}
--
--OpenClipartHandler.prototype.startDocument = function() {
--}
--
--OpenClipartHandler.prototype.endDocument = function() {
--}
--
--OpenClipartHandler.prototype.startElement = function(name, attribs) {
-- if (!name || name === "") return;
-- if (name === "item") {
-- this.currentState = OpenClipartHandler.STATE_ITEM;
-- this.currentItem = {images: [{type: "image/svg+xml", typeName: "SVG"}]};
-- } else if (name === "title") {
-- if (this.currentState >= OpenClipartHandler.STATE_ITEM) {
-- this.currentState = OpenClipartHandler.STATE_TITLE;
-- }
-- } else if (name === "dc:creator") {
-- if (this.currentState >= OpenClipartHandler.STATE_ITEM) {
-- this.currentState = OpenClipartHandler.STATE_AUTHOR;
-- }
-- } else if (name === "description") {
-- if (this.currentState >= OpenClipartHandler.STATE_ITEM) {
-- this.currentState = OpenClipartHandler.STATE_DESC;
-- }
-- } else if (name === "enclosure") {
-- if (this.currentState >= OpenClipartHandler.STATE_ITEM) {
-- this.currentItem.images[0].src = attribs["url"];
-- this.currentState = OpenClipartHandler.STATE_URL;
-- }
-- } else if (name === "media:thumbnail") {
-- if (this.currentState >= OpenClipartHandler.STATE_ITEM) {
-- this.currentItem.images[0].thumbnail = attribs["url"];
-- this.currentState = OpenClipartHandler.STATE_THUMBNAIL;
-- }
-- }
--}
--OpenClipartHandler.prototype.endElement = function(name) {
-- if (!name || name === "") return;
-- if (name === "item") {
-- this.currentState = OpenClipartHandler.STATE_CHANNEL;
-- this.items.push(this.currentItem);
-- } else if (name === "title") {
-- if (this.currentState == OpenClipartHandler.STATE_TITLE) {
-- this.currentItem.name = this.currentText;
-- this.currentState = OpenClipartHandler.STATE_ITEM;
-- }
-- } else if (name === "dc:creator") {
-- if (this.currentState == OpenClipartHandler.STATE_AUTHOR) {
-- this.currentItem.author = this.currentText;
-- this.currentState = OpenClipartHandler.STATE_ITEM;
-- }
-- } else if (name === "description") {
-- if (this.currentState == OpenClipartHandler.STATE_DESC) {
-- this.currentItem.desc = this.currentText;
-- this.currentState = OpenClipartHandler.STATE_ITEM;
-- }
-- } else if (name === "enclosure ") {
-- if (this.currentState == OpenClipartHandler.STATE_URL) {
-- this.currentState = OpenClipartHandler.STATE_ITEM;
-- }
-- } else if (name === "media:thumbnail ") {
-- if (this.currentState == OpenClipartHandler.STATE_THUMBNAIL) {
-- this.currentState = OpenClipartHandler.STATE_ITEM;
-- }
-- }
--}
--OpenClipartHandler.prototype.characters = function(data) {
-- this.currentText = data;
--}
--
--OpenClipartHandler.STATE_CHANNEL = 0;
--OpenClipartHandler.STATE_ITEM = 2;
--OpenClipartHandler.STATE_TITLE = 21;
--OpenClipartHandler.STATE_DESC = 22;
--OpenClipartHandler.STATE_AUTHOR = 23;
--OpenClipartHandler.STATE_URL = 24;
--OpenClipartHandler.STATE_THUMBNAIL = 25;
--
--// SearchManager.registerSearchEngine(OpenClipartSearch2, true);
-+SearchManager.registerSearchEngine(OpenClipartSearch2, true);
-diff --git a/app/pencil-core/common/Canvas.js b/app/pencil-core/common/Canvas.js
-index 95f85bd..12f2995 100644
---- a/app/pencil-core/common/Canvas.js
-+++ b/app/pencil-core/common/Canvas.js
-@@ -171,6 +171,7 @@ function Canvas(element, options, containerScrollPane) {
- "RangeBound");
-
- this.snappingHelper = new SnappingHelper(this);
-+ new GestureHelper(this);
-
- this.idSeed = 1;
-
-@@ -960,6 +961,8 @@ Canvas.prototype.handleScrollPane = function(event) {
- }
-
- Canvas.prototype.handleMouseUp = function (event) {
-+ if (this.gestureHelper && this.gestureHelper.handleMouseUp(event)) return;
-+
- if (this.resizing) {
- this.commitResize(event);
- this.isSelectingRange = false;
-@@ -981,7 +984,7 @@ Canvas.prototype.handleMouseUp = function (event) {
- setter : null
- });
- }
--
-+
- Connector.prepareInvalidation(this);
-
- if (this.currentController.invalidateOutboundConnections) {
-@@ -990,7 +993,7 @@ Canvas.prototype.handleMouseUp = function (event) {
- if (this.currentController.invalidateInboundConnections) {
- this.currentController.invalidateInboundConnections();
- }
--
-+
- Connector.finishInvalidation();
- }
- if (this.controllerHeld && this.hasMoved) {
-@@ -1005,7 +1008,7 @@ Canvas.prototype.handleMouseUp = function (event) {
- this.hasMoved = true;
-
- this.controllerHeld = false;
--
-+
- if (this.isSelectingRange) {
- this.setRangeBoundVisibility(false);
- this.isSelectingRange = false;
-@@ -1156,7 +1159,7 @@ Canvas.prototype.handleResizeMouseMove = function (event) {
-
- var dw = Math.round((event.clientX - this.resizeInfo.ox) / this.zoom);
- var dh = Math.round((event.clientY - this.resizeInfo.oy) / this.zoom);
--
-+
- if (event.shiftKey) dw = 0;
-
- var newW = this.resizeInfo.ow + dw;
-@@ -1277,7 +1280,7 @@ Canvas.prototype.handleMouseMove = function (event, fake) {
-
- var dx = newX - this.oX;
- var dy = newY - this.oY;
--
-+
- //direction ratios
- var hdr = event.ctrlKey && Math.abs(dx) < Math.abs(dy) ? 0 : 1;
- var vdr = event.ctrlKey && Math.abs(dx) >= Math.abs(dy) ? 0 : 1;
-@@ -1297,92 +1300,17 @@ Canvas.prototype.handleMouseMove = function (event, fake) {
-
- this.hasMoved = true;
-
-- var gridSize = Pencil.getGridSize();
-- var snap = null;
-- if (Config.get("object.snapping.enabled", true) == true) {
-- snap = this.snappingHelper.findSnapping(accX
-- && !this.snappingHelper.snappedX, accY
-- && !this.snappingHelper.snappedY, null, null,
-- event.shiftKey);
-- }
-- if (Config.get("edit.snap.grid", false) == true) {
-- var snapGrid = this.snappingHelper.findSnapping(accX
-- && !this.snappingHelper.snappedX, accY
-- && !this.snappingHelper.snappedY, null, gridSize.w / 2,
-- event.shiftKey, true);
-- if (snap && snapGrid) {
-- if (snap.dx == 0) {
-- snap.dx = snapGrid.dx;
-- }
-- if (snap.dy == 0) {
-- snap.dy = snapGrid.dy;
-- }
-- } else {
-- snap = snapGrid;
-- }
-- // debug("snap grid: " + [snapGrid.dx, snapGrid.dy]);
-- }
-- // debug("snap: " + [snap.dx, snap.dy, this.snappedX,
-- // this.snappedY]);
-- if (!event.shiftKey
-- && snap
-- && ((snap.dx != 0 && !this.snappingHelper.snappedX && accX)
-- || (snap.dy != 0 && !this.snappingHelper.snappedY && accY)
-- )) {
-- if (snap.dx != 0 && !this.snappingHelper.snappedX) {
-- this.snappingHelper.snappedX = true;
-- this.snappingHelper.snapX = newX;
-- this.currentController._pSnapshot.lastDX += snap.dx;
-- // debug("snapX");
-- }
-- if (snap.dy != 0 && !this.snappingHelper.snappedY) {
-- this.snappingHelper.snappedY = true;
-- this.snappingHelper.snapY = newY;
-- this.currentController._pSnapshot.lastDY += snap.dy;
-- // debug("snapY");
-- }
-- this.currentController.moveBy(snap.dx * hdr, snap.dy * vdr);
-- } else {
-- var unsnapX = event.shiftKey
-- || (this.snappingHelper.snapX != 0 && (Math
-- .abs(this.snappingHelper.snapX - newX) > this.snappingHelper.unsnapX));
-- var unsnapY = event.shiftKey
-- || (this.snappingHelper.snapY != 0 && (Math
-- .abs(this.snappingHelper.snapY - newY) > this.snappingHelper.unsnapY));
-- // debug("unsnap: " + [unsnapX, unsnapY]);
--
-- if (!this.snappingHelper.snappedX
-- && !this.snappingHelper.snappedY) {
-- this.currentController.moveFromSnapshot(dx * hdr, dy * vdr);
-- } else {
-- if (unsnapX || !this.snappingHelper.snappedX) {
-- this.currentController
-- .moveFromSnapshot(
-- dx * hdr,
-- this.snappingHelper.snappedY ? this.currentController._pSnapshot.lastDY * vdr
-- : dy * vdr);
-- }
-- if (unsnapY || !this.snappingHelper.snappedY) {
-- this.currentController
-- .moveFromSnapshot(
-- this.snappingHelper.snappedX ? this.currentController._pSnapshot.lastDX * hdr
-- : dx * hdr, dy * vdr);
-- this.snappingHelper.snapY = 0;
-- this.snappingHelper.snappedY = false;
-- }
-- if (unsnapX || !this.snappingHelper.snappedX) {
-- this.snappingHelper.snapX = 0;
-- this.snappingHelper.snappedX = false;
-- }
--
-- if (unsnapX) {
-- this.snappingHelper.clearSnappingGuideX();
-- }
-- if (unsnapY) {
-- this.snappingHelper.clearSnappingGuideY();
-- }
-- }
-+ dx = dx * hdr;
-+ dy = dy * vdr;
-+
-+ if (!event.shiftKey) {
-+ var snapResult = this.snappingHelper.applySnapping(dx, dy, this.currentController);
-+ if (snapResult && snapResult.xsnap) dx = snapResult.xsnap.d;
-+ if (snapResult && snapResult.ysnap) dy = snapResult.ysnap.d;
- }
-+
-+ this.currentController.moveFromSnapshot(dx, dy);
-+
- if (this.currentController.dockingManager) {
- this.currentController.dockingManager.altKey = event.altKey;
- }
-@@ -1474,7 +1402,7 @@ Canvas.prototype.handleKeyPress = function (event) {
- this.run(function () {
- // this.currentController.moveBy(dx, dy);
- this.currentController.moveBy(dx, dy, false, true);
--
-+
- Connector.prepareInvalidation(this);
- if (this.currentController.invalidateOutboundConnections) {
- this.currentController.invalidateOutboundConnections();
-@@ -1925,7 +1853,7 @@ Canvas.prototype.invalidateEditors = function (source) {
- e.invalidate();
- }
-
-- // Pencil.invalidateSharedEditor();
-+ Pencil.invalidateSharedEditor();
- // invalidates all selections
- for (var i = 0; i < this.selectionContainer.childNodes.length; i++) {
- var rect = this.selectionContainer.childNodes[i];
-@@ -2115,7 +2043,7 @@ Canvas.prototype.doPaste = function (withAlternative) {
- if (image) {
- var id = Pencil.controller.nativeImageToRefSync(image);
- var size = image.getSize();
--
-+
- contents.push({
- type: PNGImageXferHelper.MIME_TYPE,
- data: new ImageData(size.width, size.height, ImageData.idToRefString(id))
-@@ -2154,6 +2082,8 @@ Canvas.prototype.handleMouseDown = function (event) {
- tick("begin");
- Dom.emitEvent("p:CanvasMouseDown", this.element, {});
-
-+ if (this.gestureHelper && this.gestureHelper.handleMouseDown(event)) return;
-+
- var canvasList = Pencil.getCanvasList();
- for (var i = 0; i < canvasList.length; i++) {
- if (canvasList[i] != this) {
-@@ -2175,9 +2105,9 @@ Canvas.prototype.handleMouseDown = function (event) {
- return node.hasAttributeNS
- && node.hasAttributeNS(PencilNamespaces.p, "type");
- });
--
-+
- if (top && this.isShapeLocked(top)) top = null;
--
-+
- if (!top) {
- this.lastTop = null;
- // this.clearSelection();
-@@ -2196,7 +2126,7 @@ Canvas.prototype.handleMouseDown = function (event) {
- width : 0,
- height : 0
- };
--
-+
- this._sayTargetChanged();
- this.endFormatPainter();
-
-@@ -2289,6 +2219,7 @@ Canvas.prototype.handleMouseDown = function (event) {
-
- tick("before setPositionSnapshot");
- thiz.currentController.setPositionSnapshot();
-+ thiz.snappingHelper.onControllerSnapshot(this.currentController);
- tick("after setPositionSnapshot");
-
- thiz.duplicateFunc = null;
-@@ -2332,6 +2263,7 @@ Canvas.prototype.handleMouseDown = function (event) {
-
- tick("before setPositionSnapshot");
- this.currentController.setPositionSnapshot();
-+ this.snappingHelper.onControllerSnapshot(this.currentController);
- tick("after setPositionSnapshot");
-
- if (event.button == 0)
-@@ -2923,6 +2855,7 @@ Canvas.prototype.startFakeMove = function (event) {
- this.oldPos = this.currentController.getGeometry();
-
- this.currentController.setPositionSnapshot();
-+ this.snappingHelper.onControllerSnapshot(this.currentController);
-
- // OnScreenTextEditor._hide();
-
-@@ -2979,6 +2912,9 @@ Canvas.prototype.__dragenter = function (event) {
- };
- Canvas.prototype.__dragleave = function (event) {
- // this.element.removeAttribute("p:selection");
-+ this.element.removeAttribute("is-dragover");
-+ this.element.removeAttribute("p:holding");
-+
- if (!this.currentDragObserver)
- return;
- try {
-@@ -2986,8 +2922,6 @@ Canvas.prototype.__dragleave = function (event) {
- } catch (e) {
- Console.dumpError(e);
- }
-- this.element.removeAttribute("is-dragover");
-- this.element.removeAttribute("p:holding");
- };
- Canvas.prototype.__dragend = function (event) {
- this.element.removeAttribute("is-dragover");
-diff --git a/app/pencil-core/common/DocumentHandler.js b/app/pencil-core/common/DocumentHandler.js
-index 747206b..8cb7b9c 100644
---- a/app/pencil-core/common/DocumentHandler.js
-+++ b/app/pencil-core/common/DocumentHandler.js
-@@ -46,11 +46,11 @@ DocumentHandler.prototype.openDocument = function (callback) {
- filters: [
- { name: "Pencil Documents", extensions: thiz.getAllSupportedExtensions(false) }
- ]
-- }, function (filenames) {
-- if (!filenames || filenames.length <= 0) return;
-- Config.set("document.open.recentlyDirPath", path.dirname(filenames[0]));
-+ }).then(function (res) {
-+ if (!res || !res.filePaths || res.filePaths.length <= 0) return;
-+ Config.set("document.open.recentlyDirPath", path.dirname(res.filePaths[0]));
-
-- thiz.loadDocument(filenames[0], callback);
-+ thiz.loadDocument(res.filePaths[0], callback);
-
- });
- };
-@@ -146,8 +146,9 @@ DocumentHandler.prototype.pickupTargetFileToSave = function (callback) {
- title: "Save as",
- defaultPath: defaultPath,
- filters: filters
-- }, function (filePath) {
-- if (filePath) {
-+ }).then(function (res) {
-+ if (res && res.filePath) {
-+ var filePath = res.filePath;
- var ext = path.extname(filePath);
- if (ext != defaultFileType && fs.existsSync(filePath)) {
- Dialog.confirm("Are you sure you want to overwrite the existing file?", filePath,
-@@ -166,7 +167,7 @@ DocumentHandler.prototype.pickupTargetFileToSave = function (callback) {
- Config.set("document.save.recentlyDirPath", path.dirname(filePath));
- }
- if (callback) {
-- callback(filePath);
-+ callback(res.filePath);
- }
- });
- };
-diff --git a/app/pencil-core/common/FontLoader.js b/app/pencil-core/common/FontLoader.js
-index 11efd5d..0d566fa 100644
---- a/app/pencil-core/common/FontLoader.js
-+++ b/app/pencil-core/common/FontLoader.js
-@@ -151,7 +151,7 @@ FontLoader.prototype.embedToDocumentRepo = function (faces) {
- var font = this.userRepo.getFont(f);
- var userFont = this.documentRepo.getFont(f);
- if (userFont) {
-- if (!font.autoEmbed) {
-+ if (font && !font.autoEmbed) {
- this.documentRepo.removeFont(userFont);
- }
- return;
-diff --git a/app/pencil-core/common/canvas-external-renderer.js b/app/pencil-core/common/canvas-external-renderer.js
-index 2f5f6de..86439f1 100644
---- a/app/pencil-core/common/canvas-external-renderer.js
-+++ b/app/pencil-core/common/canvas-external-renderer.js
-@@ -94,7 +94,7 @@ function init() {
- if (ext == ".png") mine = "image/png";
-
- fs.readFile(sourcePath, function (error, bitmap) {
-- var url = "data:" + mime + ";base64," + new Buffer(bitmap).toString("base64");
-+ var url = "data:" + mime + ";base64," + Buffer.from(bitmap).toString("base64");
-
- image.setAttributeNS(xlink, "href", url);
- totalImageLength += url.length;
-diff --git a/app/pencil-core/common/config.js b/app/pencil-core/common/config.js
-index 5e14de7..ca91c8c 100644
---- a/app/pencil-core/common/config.js
-+++ b/app/pencil-core/common/config.js
-@@ -73,3 +73,4 @@ Config.DEVICE_ADB_PATH = Config.define("device.adb_path", "adb");
- Config.EXPORT_CROP_FOR_CLIPBOARD = Config.define("export.crop_for_clipboard", false);
- Config.EXPORT_DEFAULT_SCALE = Config.define("export.default_scale", 1);
- Config.EXPORT_DEFAULT_BACKGROUND_COLOR = Config.define("export.default_background_color", "");
-+Config.CORE_USE_HWA = Config.define("core.useHardwareAcceleration", false);
-diff --git a/app/pencil-core/common/controller.js b/app/pencil-core/common/controller.js
-index 8a6e2c2..7f92fdb 100644
---- a/app/pencil-core/common/controller.js
-+++ b/app/pencil-core/common/controller.js
-@@ -1158,12 +1158,13 @@ Controller.prototype.rasterizeCurrentPage = function (targetPage) {
- filters: [
- { name: "PNG Image (*.png)", extensions: ["png"] }
- ]
-- }, function (filePath) {
-- if (!filePath) return;
-+ }).then(function (res) {
-+ if (!res || !res.filePath) return;
-+ var filePath = res.filePath;
- this.applicationPane.rasterizer.rasterizePageToFile(page, filePath, function (p, error) {
- if (!error) {
- NotificationPopup.show("Page exprted as '" + path.basename(filePath) + "'.", "View", function () {
-- shell.openItem(filePath);
-+ shell.openPath(filePath);
- });
- }
- }, undefined, false, options);
-@@ -1204,7 +1205,8 @@ Controller.prototype.copyPageBitmap = function (targetPage) {
- var filePath = tmp.tmpNameSync();
- thiz.applicationPane.rasterizer.rasterizePageToFile(page, filePath, function (p, error) {
- if (!error) {
-- clipboard.writeImage(filePath);
-+ var image = nativeImage.createFromPath(filePath);
-+ var result = clipboard.writeImage(image);
- fs.unlinkSync(filePath);
- NotificationPopup.show("Page bitmap copied into clipboard.");
- }
-@@ -1232,7 +1234,8 @@ Controller.prototype.rasterizeSelection = function (options) {
-
- this.applicationPane.rasterizer.rasterizeSelectionToFile(target, filePath, function (p, error) {
- if (!error) {
-- clipboard.writeImage(filePath);
-+ var image = nativeImage.createFromPath(filePath);
-+ clipboard.writeImage(image);
- fs.unlinkSync(filePath);
- NotificationPopup.show("Page bitmap copied into clipboard.");
- }
-@@ -1244,12 +1247,13 @@ Controller.prototype.rasterizeSelection = function (options) {
- filters: [
- { name: "PNG Image (*.png)", extensions: ["png"] }
- ]
-- }, function (filePath) {
-- if (!filePath) return;
-+ }).then(function (res) {
-+ if (!res || !res.filePath) return;
-+ var filePath = res.filePath;
- this.applicationPane.rasterizer.rasterizeSelectionToFile(target, filePath, function (p, error) {
- if (!error) {
- NotificationPopup.show("Selection exprted as '" + path.basename(filePath) + "'.", "View", function () {
-- shell.openItem(filePath);
-+ shell.openPath(filePath);
- });
- }
- }, undefined, options);
-@@ -1684,14 +1688,14 @@ Controller.prototype.exportAsLayout = function () {
- title: "Export Layout",
- defaultPath: defaultPath,
- filters: [{name: 'XHTML Layout', extensions: ["xhtml"]}]
-- }, function (filePath) {
-- if (filePath) {
-- outputPath = filePath;
-- outputImage = path.join(path.dirname(outputPath), IMAGE_FILE);
-- Pencil.rasterizer.rasterizePageToFile(thiz.activePage, outputImage, function (p, error) {
-- done();
-- });
-- }
-+ }).then(function (res) {
-+ if (!res || !res.filePath) return;
-+ var filePath = res.filePath;
-+ outputPath = filePath;
-+ outputImage = path.join(path.dirname(outputPath), IMAGE_FILE);
-+ Pencil.rasterizer.rasterizePageToFile(thiz.activePage, outputImage, function (p, error) {
-+ done();
-+ });
- });
- };
-
-diff --git a/app/pencil-core/common/externalEditorSupports.js b/app/pencil-core/common/externalEditorSupports.js
-index e55d600..4e187d5 100644
---- a/app/pencil-core/common/externalEditorSupports.js
-+++ b/app/pencil-core/common/externalEditorSupports.js
-@@ -6,6 +6,15 @@ ExternalEditorSupports.getEditorPath = function (extension) {
- || extension == "gif"
- || extension == "png") return Config.get("external.editor.bitmap.path", "/usr/bin/gimp -n %f");
-
-+ var configName = "external.editor." + extension + ".path";
-+ var p = Config.get(configName, null);
-+
-+ if (p) {
-+ return p;
-+ } else if (p == null) {
-+ Config.define(configName, "");
-+ }
-+
- throw Util.getMessage("unsupported.type", extension);
- };
- ExternalEditorSupports.queue = [];
-@@ -39,14 +48,22 @@ ExternalEditorSupports.handleEditRequest = function (contentProvider, contentRec
- params.push(tmpFile.name);
- }
-
-+ var startedAt = new Date().getTime();
- var process = spawn(executablePath, params);
-
- var timeOutId = null;
- process.on("close", function () {
-+ var closedAt = new Date().getTime();
-+ console.log("Closed: ", closedAt - startedAt);
-+ if (closedAt - startedAt < 2000) {
-+ Dialog.alert("Editor exited almost immediately", "The external edit has exited almost immediately after be launched. This is usually caused by the case where an existing instance of the editor software is running. Please make sure that is not the case.");
-+ }
- try {
- contentReceiver.update(tmpFile.name);
- if (timeOutId) window.clearTimeout(timeOutId);
-- tmpFile.removeCallback();
-+ window.setTimeout(function () {
-+ tmpFile.removeCallback();
-+ }, 3000);
- } catch (e) {
- console.error(e);
- }
-diff --git a/app/pencil-core/common/renderer.js b/app/pencil-core/common/renderer.js
-index 7cbc182..5e13b2e 100644
---- a/app/pencil-core/common/renderer.js
-+++ b/app/pencil-core/common/renderer.js
-@@ -78,7 +78,7 @@ module.exports = function () {
- if (err) throw err;
-
- var svg = data.svg;
-- var delay = 10;
-+ var delay = 500;
- console.log("data.scale", data.scale);
- var scale = typeof(data.scale) == "number" ? data.scale : 1;
-
-@@ -112,8 +112,10 @@ module.exports = function () {
- + ' window.setTimeout(function () {\n'
- + ' window.requestAnimationFrame(function () {\n'
- + ' window.requestAnimationFrame(function () {\n'
-- + ' ipcRenderer.send("render-rendered", {objectsWithLinking: window.objectsWithLinking});\n'
-- + ' console.log("Rendered signaled");\n'
-+ + ' window.setTimeout(function () {\n'
-+ + ' ipcRenderer.send("render-rendered", {objectsWithLinking: window.objectsWithLinking});\n'
-+ + ' console.log("Rendered signaled");\n'
-+ + ' }, 500);\n'
- + ' });\n'
- + ' });\n'
- + ' }, ' + delay + ');\n'
-@@ -141,7 +143,7 @@ module.exports = function () {
- event.sender.send(data.id, {url: "", objectsWithLinking: renderedData.objectsWithLinking});
- __callback();
- } else {
-- rendererWindow.capturePage(function (nativeImage) {
-+ rendererWindow.capturePage().then(function (nativeImage) {
- var dataURL = nativeImage.toDataURL();
-
- cleanupCallback();
-diff --git a/app/pencil-core/common/shared-util.js b/app/pencil-core/common/shared-util.js
-index 3e8864a..3bae7f0 100644
---- a/app/pencil-core/common/shared-util.js
-+++ b/app/pencil-core/common/shared-util.js
-@@ -51,7 +51,7 @@ module.exports = function () {
- var format = FORMAT_MAP[ext];
- if (!format) format = "truetype";
-
-- var url = "data:" + mime + ";base64," + new Buffer(bytes).toString("base64");
-+ var url = "data:" + mime + ";base64," + Buffer.from(bytes).toString("base64");
-
- combinedCSS += "@font-face {\n"
- + " font-family: '" + installedFace.name + "';\n"
-diff --git a/app/pencil-core/common/svgRasterizer.js b/app/pencil-core/common/svgRasterizer.js
-index 977c8c7..398d1f2 100644
---- a/app/pencil-core/common/svgRasterizer.js
-+++ b/app/pencil-core/common/svgRasterizer.js
-@@ -44,7 +44,7 @@ Rasterizer.ipcBasedBackend = {
- // if (scale != 1) {
- // svgNode.setAttribute("width", w + "px");
- // svgNode.setAttribute("height", h + "px");
-- //
-+ //
- // svgNode.setAttribute("viewBox", "0 0 " + width + " " + height);
- // }
-
-@@ -125,7 +125,7 @@ Rasterizer.inProcessCanvasBasedBackend = {
- if (ext == ".png") mine = "image/png";
-
- fs.readFile(sourcePath, function (error, bitmap) {
-- var url = "data:" + mime + ";base64," + new Buffer(bitmap).toString("base64");
-+ var url = "data:" + mime + ";base64," + Buffer.from(bitmap).toString("base64");
-
- image.setAttributeNS(PencilNamespaces.xlink, "href", url);
- totalImageLength += url.length;
-@@ -167,9 +167,67 @@ Rasterizer.inProcessCanvasBasedBackend = {
- convertNext();
- }
- };
-+Rasterizer.inProcessFileCanvasBasedBackend = {
-+ init: function () {
-+ //the in-process rasterize requires basicly nothing to init :)
-+ },
-+ rasterize: function (svgNode, width, height, s, callback, parseLinks, options) {
-+ console.log("rasterize() called", [svgNode, width, height, s, callback, parseLinks, options]);
-+ var images = svgNode.querySelectorAll("image");
-+ var totalImageLength = 0;
-+
-+ for (var i = 0; i < images.length; i ++) {
-+ var image = images[i];
-+ var href = image.getAttributeNS(PencilNamespaces.xlink, "href");
-+ if (href && href.match("^file://(.+)$")) {
-+ var sourcePath = decodeURI(RegExp.$1);
-+ try {
-+ fs.accessSync(sourcePath, fs.R_OK);
-+ image.setAttribute("crossorigin", "anonymous");
-+ } catch (e) {
-+ image.setAttributeNS(PencilNamespaces.xlink, "href", "");
-+ }
-+ }
-+ }
-+
-+ var tempFile = tmp.fileSync({postfix: ".svg" });
-+ fs.writeFileSync(tempFile.name, Controller.serializer.serializeToString(svgNode), XMLDocumentPersister.CHARSET);
-+
-+ var delay = 500;
-+
-+ var canvas = document.createElement("canvas");
-+ canvas.setAttribute("style", "display: none;");
-+ canvas.setAttribute("width", width * s);
-+ canvas.setAttribute("height", height * s);
-+ document.body.appendChild(canvas);
-+ var ctx = canvas.getContext("2d");
-+
-+ var img = document.createElement("img");
-
-+ img.onload = function () {
-+ ctx.save();
-+ ctx.scale(s, s);
-+ ctx.drawImage(img, 0, 0);
-+ ctx.setTransform(1, 0, 0, 1, 0, 0);
-+
-+ setTimeout(function () {
-+ callback(canvas.toDataURL());
-+ ctx.restore();
-+ img.onload = null;
-+ img.src = "";
-+ }, delay);
-+ };
-+
-+ img.setAttribute("crossorigin", "anonymous");
-+ img.setAttribute("style", "display: none;");
-+ document.body.appendChild(img);
-+
-+ img.setAttribute("src", "file://" + tempFile.name);
-+ }
-+};
- Rasterizer.prototype.getBackend = function () {
- //TODO: options or condition?
-+ // return Rasterizer.inProcessFileCanvasBasedBackend;
- return Rasterizer.ipcBasedBackend;
- // return Rasterizer.outProcessCanvasBasedBackend;
- };
-@@ -194,7 +252,7 @@ Rasterizer.prototype.rasterizePageToUrl = function (page, callback, scale, parse
- g.appendChild(svg.removeChild(svg.firstChild));
- }
- svg.appendChild(g);
--
-+
- w -= 2 * m;
- h -= 2 * m;
- svg.setAttribute("width", w);
-@@ -281,7 +339,7 @@ Rasterizer.prototype.rasterizePageToFile = function (page, filePath, callback, s
- var base64Data = dataURI;
- if (base64Data.startsWith(prefix)) base64Data = base64Data.substring(prefix.length);
-
-- var buffer = new Buffer(base64Data, "base64");
-+ var buffer = Buffer.from(base64Data, "base64");
- fs.writeFile(actualPath, buffer, "utf8", function (err) {
- console.log("Finish rasterizing page: ", page.name, actualPath);
- callback(parseLinks ? {actualPath: actualPath, objectsWithLinking: data.objectsWithLinking} : actualPath, err);
-@@ -290,7 +348,7 @@ Rasterizer.prototype.rasterizePageToFile = function (page, filePath, callback, s
- };
- Rasterizer.getExportScale = function (inputScale) {
- if (typeof(inputScale) == "number") return inputScale;
--
-+
- var configScale = Config.get(Config.EXPORT_DEFAULT_SCALE, 1.0);
- if (typeof(configScale) == "number") {
- return configScale;
-@@ -347,7 +405,7 @@ Rasterizer.prototype.rasterizeSelectionToFile = function (target, filePath, call
- var base64Data = dataURI;
- if (base64Data.startsWith(prefix)) base64Data = base64Data.substring(prefix.length);
-
-- var buffer = new Buffer(base64Data, "base64");
-+ var buffer = Buffer.from(base64Data, "base64");
- fs.writeFile(actualPath, buffer, {}, function (err) {
- callback(actualPath, err);
- });
-diff --git a/app/pencil-core/common/util.js b/app/pencil-core/common/util.js
-index a6c761e..ac9ad79 100644
---- a/app/pencil-core/common/util.js
-+++ b/app/pencil-core/common/util.js
-@@ -2154,13 +2154,20 @@ Util.imageOnloadListener = function (event) {
-
- };
- Util.setupImage = function (image, src, mode, allowUpscale) {
-- image.onload = Util.imageOnloadListener;
-- image.style.visibility = "hidden";
-- image.style.width = "0px";
-- image.style.height = "0px";
-- image._mode = mode;
-- image._allowUpscale = allowUpscale;
-+ // image.onload = Util.imageOnloadListener;
-+ // image.style.visibility = "hidden";
-+ image.style.width = "100%";
-+ image.style.height = "100%";
-+ image.style.opacity = "0";
- image.src = src;
-+
-+ mode = mode || "center-crop";
-+
-+ var hp = (mode.indexOf("left") >= 0) ? "left" : ((mode.indexOf("right") >= 0) ? "right" : " center");
-+ var vp = (mode.indexOf("top") >= 0) ? "top" : ((mode.indexOf("bottom") >= 0) ? "bottom" : " center");
-+ image.parentNode.style.backgroundImage = "url('" + src + "')";
-+ image.parentNode.style.backgroundPosition = hp + " " + vp;
-+ image.parentNode.style.backgroundSize = (mode.indexOf("crop") >= 0) ? "cover" : "contain";
- };
-
- Util.isDev = function() {
-@@ -2466,6 +2473,33 @@ function copyFolderRecursiveSync(source, target) {
- }
- }
-
-+function PropertyMask(names) {
-+ this.names = (typeof(names) == "string") ? [names] : names;
-+}
-+PropertyMask.prototype.and = function (other) {
-+ return new PropertyMask(this.names.concat.other.names);
-+};
-+PropertyMask.prototype.contains = function (name) {
-+ return this.names.indexOf(name) >= 0;
-+};
-+PropertyMask.prototype.apply = function (original, newValue) {
-+ if (!original || !newValue) return original;
-+ var value = new original.constructor();
-+ for (var name in original) {
-+ if (original.hasOwnProperty(name)) {
-+ value[name] = original[name];
-+ }
-+ }
-+
-+ for (var name of this.names) {
-+ if (newValue.hasOwnProperty(name)) {
-+ value[name] = newValue[name];
-+ }
-+ }
-+
-+ return value;
-+};
-+
- function getStaticFilePath(subPath) {
- var filePath = __dirname;
- if (!subPath) return filePath;
-diff --git a/app/pencil-core/common/webPrinter.js b/app/pencil-core/common/webPrinter.js
-index f9db73a..27184d2 100644
---- a/app/pencil-core/common/webPrinter.js
-+++ b/app/pencil-core/common/webPrinter.js
-@@ -38,17 +38,7 @@ module.exports = function () {
- // }
- // }
- // });
-- browserWindow.webContents.printToPDF(options, function(error, pdfBuffer) {
-- if (error) {
-- try {
-- global.mainWindow.webContents.send(data.id, {success: false, message: error.message});
-- } finally {
-- __callback();
-- }
--
-- return;
-- }
--
-+ browserWindow.webContents.printToPDF(options).then(function(pdfBuffer) {
- fs.writeFile(data.targetFilePath, pdfBuffer, function(error) {
- try {
- if (error) {
-@@ -60,6 +50,12 @@ module.exports = function () {
- } finally {
- __callback();
- }
-+ }).catch (function (error) {
-+ try {
-+ global.mainWindow.webContents.send(data.id, {success: false, message: error.message});
-+ } finally {
-+ __callback();
-+ }
- })
- });
- } else {
-diff --git a/app/pencil-core/definition/collectionManager.js b/app/pencil-core/definition/collectionManager.js
-index d3962ad..2435b5d 100644
---- a/app/pencil-core/definition/collectionManager.js
-+++ b/app/pencil-core/definition/collectionManager.js
-@@ -313,10 +313,10 @@ CollectionManager.installNewCollection = function (callback) {
- { name: "Stencil files", extensions: ["zip", "epc"] }
- ]
-
-- }, function (filenames) {
-- if (!filenames || filenames.length <= 0) return;
-- Config.set("collection.install.recentlyDirPath", path.dirname(filenames[0]));
-- CollectionManager.installCollectionFromFilePath(filenames[0], callback);
-+ }).then(function (res) {
-+ if (!res || !res.filePaths || res.filePaths.length <= 0) return;
-+ Config.set("collection.install.recentlyDirPath", path.dirname(res.filePaths[0]));
-+ CollectionManager.installCollectionFromFilePath(res.filePaths[0], callback);
- });
- };
-
-diff --git a/app/pencil-core/editor/geometryEditor.js b/app/pencil-core/editor/geometryEditor.js
-index 13ab8b2..824770a 100644
---- a/app/pencil-core/editor/geometryEditor.js
-+++ b/app/pencil-core/editor/geometryEditor.js
-@@ -16,6 +16,7 @@ GeometryEditor.prototype.resetAccomulatedChanges = function () {
- };
- GeometryEditor.prototype.install = function (canvas) {
- this.canvas = canvas;
-+ this.canvas.geometryEditor = this;
- this.canvas.onScreenEditors.push(this);
- this.svgElement = canvas.ownerDocument.importNode(Dom.getSingle("/p:Config/svg:g", GeometryEditor.configDoc), true);
-
-@@ -314,6 +315,7 @@ GeometryEditor.prototype.handleMouseUp = function (event) {
- }, this, Util.getMessage("action.move.shape"));
- }
- } finally {
-+ console.log("Setting currentAnchor = null");
- this.currentAnchor = null;
- }
- };
-@@ -361,6 +363,7 @@ GeometryEditor.prototype.handleMouseMove = function (event) {
- var uPoint1 = Svg.vectorInCTM(new Point(this.oX, this.oY), this.geo.ctm);
- var uPoint2 = Svg.vectorInCTM(new Point(event.clientX, event.clientY), this.geo.ctm);
-
-+
- var matrix = this.currentAnchor._matrix;
- var t = event.shiftKey ? {x: 1, y: 1} : this.getGridSize(); //Svg.vectorInCTM(this.getGridSize(), this.geo.ctm, true);
- var grid = {w: t.x * this.canvas.zoom, h: t.y * this.canvas.zoom};
-@@ -390,6 +393,8 @@ GeometryEditor.prototype.handleMouseMove = function (event) {
- var controller = this.canvas.currentController;
- var bound = controller.getBounding();
-
-+ var xsnap = null;
-+
- //HORIZONTAL
- if (!locking.width) {
- dx = matrix.dx * mdx;
-@@ -404,28 +409,13 @@ GeometryEditor.prototype.handleMouseMove = function (event) {
-
- var delta = newXNormalized - newX;
-
-- if (!locking.ratio) {
-+ if (!locking.ratio && !event.shiftKey) {
- var snapping = this._lastGuides.left ? this._lastGuides.left.clone() :
- new SnappingData("Left", bound.x, "Left", true, Util.newUUID());
-- snapping.pos += dx;
-- var snap = this.canvas.snappingHelper.findSnapping(true, false, {
-- vertical: [ snapping ], horizontal: []
-- }, (grid.w / 2) - 1);
--
-- if (snap && (snap.dx != 0 && !this.canvas.snappingHelper.snappedX)) {
-- this.canvas.snappingHelper.snappedX = true;
-- this.canvas.snappingHelper.snapX = newX;
-- delta = snap.dx;
-- } else {
-- var unsnapX = (this.canvas.snappingHelper.snapX != 0 && (Math.abs(this.canvas.snappingHelper.snapX - newX) > grid.w / 2));
-- if (unsnapX || !this.canvas.snappingHelper.snappedX) {
-- this.canvas.snappingHelper.snapX = 0;
-- this.canvas.snappingHelper.snappedX = false;
-- this.canvas.snappingHelper.clearSnappingGuideX();
-- } else {
-- delta = snap.dx;
-- }
-- }
-+
-+ xsnap = this.canvas.snappingHelper.applySnappingValue(dx, [snapping], this.canvas.snappingHelper.lastXData, this.canvas.currentController);
-+ if (xsnap) delta = xsnap.d - dx;
-+ this.canvas.snappingHelper.drawSnaps(xsnap, null);
- }
-
- dx += delta;
-@@ -438,28 +428,13 @@ GeometryEditor.prototype.handleMouseMove = function (event) {
-
- var delta = newX2Normalized - newX2;
-
-- if (!locking.ratio) {
-+ if (!locking.ratio && !event.shiftKey) {
- var snapping = this._lastGuides.right ? this._lastGuides.right.clone() :
-- new SnappingData("Right", bound.x + bound.width, "Right", true, Util.newUUID());
-- snapping.pos += dw;
--
-- var snap = this.canvas.snappingHelper.findSnapping(true, false, {
-- vertical: [snapping], horizontal: []
-- }, (grid.w / 2) - 1);
-- if (snap && (snap.dx != 0 && !this.canvas.snappingHelper.snappedX)) {
-- this.canvas.snappingHelper.snappedX = true;
-- this.canvas.snappingHelper.snapX = newX2;
-- delta = snap.dx;
-- } else {
-- var unsnapX = (this.canvas.snappingHelper.snapX != 0 && (Math.abs(this.canvas.snappingHelper.snapX - newX2) > grid.w / 2));
-- if (unsnapX || !this.canvas.snappingHelper.snappedX) {
-- this.canvas.snappingHelper.snapX = 0;
-- this.canvas.snappingHelper.snappedX = false;
-- this.canvas.snappingHelper.clearSnappingGuideX();
-- } else {
-- delta = snap.dx;
-- }
-- }
-+ new SnappingData("Right", bound.x + bound.width, "Right", true, Util.newUUID());
-+
-+ xsnap = this.canvas.snappingHelper.applySnappingValue(dw, [snapping], this.canvas.snappingHelper.lastXData, this.canvas.currentController);
-+ if (xsnap) delta = xsnap.d - dw;
-+ this.canvas.snappingHelper.drawSnaps(xsnap, null);
- }
-
- dw += delta;
-@@ -481,29 +456,13 @@ GeometryEditor.prototype.handleMouseMove = function (event) {
-
- var delta = newYNormalized - newY;
-
-- if (!locking.ratio) {
-+ if (!locking.ratio && !event.shiftKey) {
- var snapping = this._lastGuides.top ? this._lastGuides.top.clone() :
-- new SnappingData("Top", bound.y, "Top", true, Util.newUUID());
-- snapping.pos += dy;
--
-- var snap = this.canvas.snappingHelper.findSnapping(false, true, {
-- vertical: [],
-- horizontal: [snapping]
-- }, (grid.w / 2) - 1);
-- if (snap && (snap.dy != 0 && !this.canvas.snappingHelper.snappedY)) {
-- this.canvas.snappingHelper.snappedY = true;
-- this.canvas.snappingHelper.snapY = newY;
-- delta = snap.dy;
-- } else {
-- var unsnapY = (this.canvas.snappingHelper.snapY != 0 && (Math.abs(this.canvas.snappingHelper.snapY - newY) > grid.w / 2));
-- if (unsnapY || !this.canvas.snappingHelper.snappedY) {
-- this.canvas.snappingHelper.snapY = 0;
-- this.canvas.snappingHelper.snappedY = false;
-- this.canvas.snappingHelper.clearSnappingGuideY();
-- } else {
-- delta = snap.dy;
-- }
-- }
-+ new SnappingData("Top", bound.y, "Top", true, Util.newUUID());
-+
-+ var ysnap = this.canvas.snappingHelper.applySnappingValue(dy, [snapping], this.canvas.snappingHelper.lastYData, this.canvas.currentController);
-+ if (ysnap) delta = ysnap.d - dy;
-+ this.canvas.snappingHelper.drawSnaps(xsnap, ysnap);
- }
-
- dy += delta;
-@@ -515,30 +474,13 @@ GeometryEditor.prototype.handleMouseMove = function (event) {
-
- var delta = newY2Normalized - newY2;
-
-- if (!locking.ratio) {
-+ if (!locking.ratio && !event.shiftKey) {
- var snapping = this._lastGuides.bottom ? this._lastGuides.bottom.clone() :
-- new SnappingData("Bottom", bound.y + bound.height, "Bottom", true, Util.newUUID());
-- snapping.pos += dh;
--
--
-- var snap = this.canvas.snappingHelper.findSnapping(false, true, {
-- vertical: [],
-- horizontal: [snapping]
-- }, (grid.w / 2) - 1);
-- if (snap && (snap.dy != 0 && !this.canvas.snappingHelper.snappedY)) {
-- this.canvas.snappingHelper.snappedY = true;
-- this.canvas.snappingHelper.snapY = newY2;
-- delta = snap.dy;
-- } else {
-- var unsnapY = (this.canvas.snappingHelper.snapY != 0 && (Math.abs(this.canvas.snappingHelper.snapY - newY2) > grid.w / 2));
-- if (unsnapY || !this.canvas.snappingHelper.snappedY) {
-- this.canvas.snappingHelper.snapY = 0;
-- this.canvas.snappingHelper.snappedY = false;
-- this.canvas.snappingHelper.clearSnappingGuideY();
-- } else {
-- delta = snap.dy;
-- }
-- }
-+ new SnappingData("Bottom", bound.y + bound.height, "Bottom", true, Util.newUUID());
-+
-+ var ysnap = this.canvas.snappingHelper.applySnappingValue(dh, [snapping], this.canvas.snappingHelper.lastYData, this.canvas.currentController);
-+ if (ysnap) delta = ysnap.d - dh;
-+ this.canvas.snappingHelper.drawSnaps(xsnap, ysnap);
- }
-
- dh += delta;
-diff --git a/app/pencil-core/exporter/documentExportManager.js b/app/pencil-core/exporter/documentExportManager.js
-index 872a0e5..ae6bf1c 100644
---- a/app/pencil-core/exporter/documentExportManager.js
-+++ b/app/pencil-core/exporter/documentExportManager.js
-@@ -36,6 +36,7 @@ DocumentExportManager.prototype.generateFriendlyId = function (page, usedFriendl
- return name;
- };
- DocumentExportManager.prototype._exportDocumentWithParamsImpl = function (doc, forcedExporterId, params) {
-+ console.log("Export requested...");
- var exporter = Pencil.getDocumentExporterById(params.exporterId);
- if (!exporter) return;
-
-@@ -140,13 +141,14 @@ DocumentExportManager.prototype._exportDocumentWithParamsImpl = function (doc, f
- thiz._exportDocumentToXML(doc, pages, pageExtraInfos, destFile, params, function () {
- listener.onTaskDone();
- NotificationPopup.show(Util.getMessage("document.has.been.exported", destFile), "View", function () {
-- shell.openItem(destFile);
-+ shell.openPath(destFile);
- });
- });
- })
- return;
- }
- var page = pages[pageIndex];
-+ console.log("Rasiterizing " + page.name);
-
- //signal progress
- var task = Util.getMessage("exporting.page.no.prefix", page.name);
-@@ -184,7 +186,7 @@ DocumentExportManager.prototype._exportDocumentWithParamsImpl = function (doc, f
- listener.onTaskDone();
- if (destFile) {
- NotificationPopup.show(Util.getMessage("document.has.been.exported", destFile), "View", function () {
-- shell.openItem(destFile);
-+ shell.openPath(destFile);
- });
- } else {
- NotificationPopup.show("Document has been exported.");
-@@ -407,7 +409,8 @@ DocumentExportManager.prototype._exportDocumentToXML = function (doc, pages, pag
-
- try {
- exporter.export(this.doc, exportSelection, destFile, xmlFile.name, function () {
-- xmlFile.removeCallback();
-+ console.log("xmlFile:" + xmlFile.name);
-+ //xmlFile.removeCallback();
- callback();
- });
- } catch (e) {
-diff --git a/app/pencil-core/privateCollection/privateCollectionManager.js b/app/pencil-core/privateCollection/privateCollectionManager.js
-index b4aaa6b..fed0dbd 100644
---- a/app/pencil-core/privateCollection/privateCollectionManager.js
-+++ b/app/pencil-core/privateCollection/privateCollectionManager.js
-@@ -11,8 +11,7 @@ PrivateCollectionManager.loadPrivateCollections = function () {
- var privateCollectionXmlLocation = path.join(PrivateCollectionManager.getPrivateCollectionDirectory(), "PrivateCollection.xml");
-
- // privateCollectionXmlLocation.append("PrivateCollection.xml");
-- var stat = fs.statSync(privateCollectionXmlLocation);
-- if (!stat) return;
-+ if (!fs.existsSync(privateCollectionXmlLocation)) return;
-
- // var fileContents = FileIO.read(privateCollectionXmlLocation, ShapeDefCollectionParser.CHARSET);
- var fileContents = fs.readFileSync(privateCollectionXmlLocation, ShapeDefCollectionParser.CHARSET);
-diff --git a/app/pencil-core/propertyType/alignment.js b/app/pencil-core/propertyType/alignment.js
-index 2adca1c..a7a49a0 100644
---- a/app/pencil-core/propertyType/alignment.js
-+++ b/app/pencil-core/propertyType/alignment.js
-@@ -2,6 +2,10 @@ function Alignment(h, v) {
- this.h = h ? h : 0;
- this.v = v ? v : 0;
- }
-+
-+Alignment.H = new PropertyMask("h");
-+Alignment.V = new PropertyMask("v");
-+
- Alignment.REG_EX = /^([0-9]+)\,([0-9]+)$/;
- Alignment.fromString = function(literal) {
- var align = new Alignment(0, 0);
-diff --git a/app/pencil-core/propertyType/font.js b/app/pencil-core/propertyType/font.js
-index 7b6d42e..971b0f4 100644
---- a/app/pencil-core/propertyType/font.js
-+++ b/app/pencil-core/propertyType/font.js
-@@ -9,6 +9,14 @@ function Font() {
- Font.REG_EX = /^([^\|]+)\|([^\|]+)\|([^\|]+)\|([0-9]+[a-z]+)$/i;
- Font.REG_EX_2 = /^([^\|]+)\|([^\|]+)\|([^\|]+)\|([0-9]+[a-z]+)\|([^\|]+)$/i;
- Font.REG_EX_3 = /^([^\|]+)\|([^\|]+)\|([^\|]+)\|([0-9]+[a-z]+)\|([^\|]+)\|([0-9\.]+)$/i;
-+
-+Font.FAMILY = new PropertyMask("family");
-+Font.STYLE = new PropertyMask("style");
-+Font.WEIGHT = new PropertyMask("weight");
-+Font.SIZE = new PropertyMask("size");
-+Font.DECOR = new PropertyMask("decor");
-+Font.LINE_HEIGHT = new PropertyMask("lineHeight");
-+
- Font.fromString = function (literal) {
- var font = new Font();
- font.decor = "none";
-diff --git a/app/pencil-core/propertyType/shadowStyle.js b/app/pencil-core/propertyType/shadowStyle.js
-index 26c4807..87c09f5 100644
---- a/app/pencil-core/propertyType/shadowStyle.js
-+++ b/app/pencil-core/propertyType/shadowStyle.js
-@@ -8,6 +8,12 @@ function ShadowStyle() {
-
- ShadowStyle.DEFAULT_COLOR = "#000000";
-
-+ShadowStyle.DX = new PropertyMask("dx");
-+ShadowStyle.DY = new PropertyMask("dy");
-+ShadowStyle.SIZE = new PropertyMask("size");
-+ShadowStyle.OPACITY = new PropertyMask("opacity");
-+ShadowStyle.COLOR = new PropertyMask("color");
-+
- ShadowStyle.REG_EX = /^([^\|]+)\|([^\|]+)\|([^\|]+)(\|([^\|]+))?(\|([^\|]+))?$/i;
- ShadowStyle.fromString = function (literal) {
- var shadowStyle = new ShadowStyle();
-diff --git a/app/pencil-core/propertyType/strokeStyle.js b/app/pencil-core/propertyType/strokeStyle.js
-index 350e92d..de574ac 100644
---- a/app/pencil-core/propertyType/strokeStyle.js
-+++ b/app/pencil-core/propertyType/strokeStyle.js
-@@ -2,6 +2,10 @@ function StrokeStyle(w, array) {
- this.w = (typeof(w) == "number") ? w : 1;
- this.array = typeof(array) != "undefined" ? array : null;
- }
-+
-+StrokeStyle.W = new PropertyMask("w");
-+StrokeStyle.ARRAY = new PropertyMask("array");
-+
- StrokeStyle.REG_EX = /^([0-9]+)\|([0-9 \,]*)$/;
- StrokeStyle.fromString = function(literal) {
- var style = new StrokeStyle();
-diff --git a/app/pencil-core/target/group.js b/app/pencil-core/target/group.js
-index 2a38d9d..1f411f6 100644
---- a/app/pencil-core/target/group.js
-+++ b/app/pencil-core/target/group.js
-@@ -75,9 +75,9 @@ Group.prototype.getProperties = function () {
- Group.prototype.getPropertyGroups = function () {
- return [this.propertyGroup];
- };
--Group.prototype.setProperty = function (name, value) {
-+Group.prototype.setProperty = function (name, value, nested, mask) {
- for (t in this.targets) {
-- this.targets[t].setProperty(name, value);
-+ this.targets[t].setProperty(name, value, nested, mask);
- }
- };
- Group.prototype.getProperty = function (name) {
-diff --git a/app/pencil-core/target/shape.js b/app/pencil-core/target/shape.js
-index 25807d7..fa7a2b2 100644
---- a/app/pencil-core/target/shape.js
-+++ b/app/pencil-core/target/shape.js
-@@ -362,7 +362,13 @@ Shape.prototype.evalExpression = function (expression, value) {
- return defaultValue;
- }
- };
--Shape.prototype.setProperty = function (name, value, nested) {
-+Shape.prototype.setProperty = function (name, value, nested, mask) {
-+ if (mask) {
-+ try {
-+ value = mask.apply(this.getProperty(name), value);
-+ } catch (e) {
-+ }
-+ }
- if (!nested) {
- this._appliedTargets = [];
- this.canvas.run( function () {
-@@ -1131,6 +1137,10 @@ Shape.prototype.getSnappingGuide = function () {
-
- var customSnappingData = this.performAction("getSnappingGuide");
- if (customSnappingData) {
-+ if (customSnappingData._ignoreBuiltIns) {
-+ vertical.length = 0;
-+ horizontal.length = 0;
-+ }
- for (var i = 0; i < customSnappingData.length; i++) {
- var data = customSnappingData[i];
- var m = this.svg.getTransformToElement(this.canvas.drawingLayer);
-@@ -1146,7 +1156,7 @@ Shape.prototype.getSnappingGuide = function () {
- ik = k;
- }
- }
-- if (ik != -1) {
-+ if (ik != -1 && !customSnappingData._allowTypeDuplications) {
- vertical[ik] = data;
- } else {
- vertical.push(data);
-@@ -1161,7 +1171,7 @@ Shape.prototype.getSnappingGuide = function () {
- ik = k;
- }
- }
-- if (ik != -1) {
-+ if (ik != -1 && !customSnappingData._allowTypeDuplications) {
- horizontal[ik] = data;
- } else {
- horizontal.push(data);
-diff --git a/app/pencil-core/target/targetSet.js b/app/pencil-core/target/targetSet.js
-index 5194cc9..b3eaa3c 100644
---- a/app/pencil-core/target/targetSet.js
-+++ b/app/pencil-core/target/targetSet.js
-@@ -64,9 +64,9 @@ TargetSet.prototype.applyBehaviorForProperty = function (name) {
- TargetSet.prototype.getPropertyGroups = function () {
- return [this.propertyGroup];
- };
--TargetSet.prototype.setProperty = function (name, value) {
-+TargetSet.prototype.setProperty = function (name, value, nested, mask) {
- for (t in this.targets) {
-- this.targets[t].setProperty(name, value);
-+ this.targets[t].setProperty(name, value, nested, mask);
- }
- };
- TargetSet.prototype.getProperty = function (name, any) {
-diff --git a/app/pencil-core/templates/HTML/prototype.HTML/Resources/expand.png b/app/pencil-core/templates/HTML/prototype.HTML/Resources/expand.png
-new file mode 100644
-index 0000000..a906329
-Binary files /dev/null and b/app/pencil-core/templates/HTML/prototype.HTML/Resources/expand.png differ
-diff --git a/app/pencil-core/templates/HTML/prototype.HTML/Resources/fit.png b/app/pencil-core/templates/HTML/prototype.HTML/Resources/fit.png
-new file mode 100644
-index 0000000..497b3fc
-Binary files /dev/null and b/app/pencil-core/templates/HTML/prototype.HTML/Resources/fit.png differ
-diff --git a/app/pencil-core/templates/HTML/prototype.HTML/Resources/script.js b/app/pencil-core/templates/HTML/prototype.HTML/Resources/script.js
-index 1c1fed0..43e7767 100644
---- a/app/pencil-core/templates/HTML/prototype.HTML/Resources/script.js
-+++ b/app/pencil-core/templates/HTML/prototype.HTML/Resources/script.js
-@@ -8,77 +8,87 @@ function scaleMap(page, r) {
- } else {
- container.innerHTML = "";
- }
--
-+
- map.querySelectorAll("area").forEach(function (area) {
- var original = area._originalCoords || area.getAttribute("coords");
- area._originalCoords = original;
- var coords = original.split(/\,/).map(function (v) {
- return Math.round(parseFloat(v) / r);
- });
--
-+
- area.setAttribute("coords", coords.join(","));
- var a = document.createElement("a");
-- a.style.left = coords[0] + "px";
-- a.style.top = coords[1] + "px";
-- a.style.width = (coords[2] - coords[0]) + "px";
-- a.style.height = (coords[3] - coords[1]) + "px";
-+ a.style.left = convertRatio(coords[0]) + "px";
-+ a.style.top = convertRatio(coords[1]) + "px";
-+ a.style.width = convertRatio(coords[2] - coords[0]) + "px";
-+ a.style.height = convertRatio(coords[3] - coords[1]) + "px";
- a.setAttribute("href", area.getAttribute("href"));
--
-+
- container.appendChild(a);
- });
- }
-+function convertRatio(value) {
-+ return parseFloat(value); // * window.devicePixelRatio;
-+}
-
- function fitImages() {
- var pages = document.querySelectorAll("body > div.Page");
- var W = 0;
- var H = 0;
--
-+
- var activePage = null;
--
-+
- pages.forEach(function (page) {
- if (page.offsetWidth == 0 || page.offsetHeight == 0) return;
--
-- W = page.offsetWidth - 30;
-- H = page.offsetHeight - 30;
-+
-+ W = page.offsetWidth - (window.useExpandedMode ? 200 : 40);
-+ H = page.offsetHeight - 40;
- activePage = page;
- });
--
-+
- if (activePage && window.lastActivePage != activePage) {
-- document.querySelectorAll(".TOC > div").forEach(function (item) {
-+ window.useExpandedMode = false;
-+ invalidateExpandMode("dontFit");
-+ window.lastSize = null;
-+
-+ document.body.querySelectorAll(".TOC > div").forEach(function (item) {
- var matched = item.classList.contains("Page_" + activePage.id);
- if (matched) {
-+ document.title = item._name + " - " + window.originalTitle;
- item.classList.add("Focused");
- item.focus();
- } else {
- item.classList.remove("Focused");
- }
- });
-+
-+ window.lastActivePage = activePage;
- }
--
--
-+
-+
- if (W && H) {
- if (window.lastSize && window.lastSize.W == W && window.lastSize.H == H) return;
-
- var imgs = document.querySelectorAll("body > div.Page img");
- imgs.forEach(function (img) {
-- var r = Math.max(img.naturalWidth / W, img.naturalHeight / H);
--
-- if (r < 1) r = 1;
-+ var r = window.useExpandedMode ? Math.min(img.naturalWidth / W, img.naturalHeight / H) : Math.max(img.naturalWidth / W, img.naturalHeight / H);
-+
-+ if (r < 1 && !window.useExpandedMode) r = 1;
- var w = Math.round(img.naturalWidth / r);
- var h = Math.round(img.naturalHeight / r);
--
-+
- img.style.width = w + "px";
- img.style.height = h + "px";
--
-+
- img.setAttribute("width", w);
- img.setAttribute("height", h);
--
-+
- var page = img;
- while (!page.classList.contains("Page")) page = page.parentNode;
--
-- scaleMap(page, r);
-+
-+ scaleMap(page, r * (img._originalWidth / img.naturalWidth));
- });
--
-+
- window.lastSize = {W: W, H: H};
- }
- }
-@@ -90,7 +100,7 @@ function checkActivePage() {
- if (!firstPage) firstPage = page;
- if (page.offsetWidth != 0 && page.offsetHeight != 0) found = true;
- });
--
-+
- if (!found && firstPage) {
- location.hash = "#" + firstPage.id;
- fitImages();
-@@ -122,7 +132,7 @@ function handleMouseMove() {
- if (!document.body.classList.contains("Active")) {
- document.body.classList.add("Active");
- }
--
-+
- if (idleTimeout) window.clearTimeout(idleTimeout);
- idleTimeout = window.setTimeout(function () {
- document.body.classList.remove("Active");
-@@ -139,17 +149,17 @@ function buildThumbnail(url, callback) {
- image.onload = function () {
- var canvas = document.createElement('canvas');
- var ctx = canvas.getContext('2d');
--
-+
- var r = Math.max(image.width / THUMB_WIDTH, image.height / THUMB_HEIGHT);
- var w = image.width / r, h = image.height / r;
- canvas.width = w;
- canvas.height = h;
--
-+
- ctx.drawImage(image, 0, 0, w, h);
--
-+
- callback(canvas.toDataURL('image/png'), w, h);
- };
--
-+
- image.src = url;
- }
-
-@@ -160,65 +170,78 @@ function generateTOC() {
- pages.forEach(function (page) {
- var title = page.querySelector("h2");
- var img = page.querySelector(".ImageContainer img");
--
-+
- var item = document.createElement("div");
- var imageWrapper = document.createElement("a");
- var itemImage = document.createElement("img");
--
-+
- item.classList.add("Page_" + page.id);
- item.setAttribute("tabindex", 0);
--
-- imageWrapper.style.width = THUMB_DISPLAY_SIZE + "px";
--
-+ item._name = title.textContent;
-+
- imageWrapper.setAttribute("href", "#" + page.id);
-
- item.appendChild(imageWrapper);
- var name = document.createElement("strong");
- name.innerHTML = title.innerHTML;
-- item.appendChild(name);
--
-+
- toc.appendChild(item);
--
-+
- buildThumbnail(img.src, function (dataUrl, w, h) {
- var r = Math.max(w / THUMB_DISPLAY_SIZE, h / THUMB_DISPLAY_SIZE);
- var w = w / r, h = h / r;
--
-+
- imageWrapper.appendChild(itemImage);
- itemImage.style.width = w + "px";
- itemImage.style.height = h + "px";
- itemImage.src = dataUrl;
-+
-+ imageWrapper.appendChild(name);
- });
- });
--
-+
- document.body.appendChild(toc);
- }
-
-+function invalidateExpandMode(dontFit) {
-+ if (window.useExpandedMode) {
-+ document.body.classList.add("ExpandMode");
-+ } else {
-+ document.body.classList.remove("ExpandMode");
-+ }
-+
-+ if (!dontFit) fitImages();
-+}
-+
- function boot() {
-+ window.originalTitle = document.title;
- document.addEventListener("mousemove", handleMouseMove);
- var style = document.createElement("link");
- style.setAttribute("rel", "stylesheet");
- style.setAttribute("href", "Resources/style.css");
- document.querySelector("head").appendChild(style);
-- workingThreadFunction();
-- generateTOC();
--}
--
--window.onload = boot;
--
--
--
--
--
--
--
--
--
--
--
-
-+ var imgs = document.querySelectorAll("body > div.Page img");
-+ imgs.forEach(function (img) {
-+ img._originalWidth = parseInt(img.getAttribute("width"), 10);
-+ img._originalHeight = parseInt(img.getAttribute("height"), 10);
-+ });
-
-
-+ generateTOC();
-+ workingThreadFunction();
-
-
-+ window.zoomToggleButton = document.createElement("button");
-+ window.zoomToggleButton.classList.add("ToggleZoomButton");
-+ window.zoomToggleButton.setAttribute("title", "Toggle expand/fit mode");
-+ document.body.appendChild(window.zoomToggleButton);
-
-+ window.zoomToggleButton.addEventListener("click", function () {
-+ window.useExpandedMode = window.useExpandedMode ? false : true;
-+ window.lastSize = null;
-+ invalidateExpandMode();
-+ }, false);
-+}
-
-+window.onload = boot;
-diff --git a/app/pencil-core/templates/HTML/prototype.HTML/Resources/style.css b/app/pencil-core/templates/HTML/prototype.HTML/Resources/style.css
-index 1419b77..1c967f8 100644
---- a/app/pencil-core/templates/HTML/prototype.HTML/Resources/style.css
-+++ b/app/pencil-core/templates/HTML/prototype.HTML/Resources/style.css
-@@ -20,14 +20,22 @@ body, html {
- top: 0px;
- right: 0px;
- bottom: 0px;
--
-+ background: #00000077;
-+ text-align: center;
-+}
-+body:not(.ExpandMode) .Page {
- display: flex;
-+ flex-direction: column;
- align-items: center;
- justify-content: center;
-- background: #00000077;
-+}
-+body.ExpandMode .Page {
-+ overflow: auto;
-+ padding: 20px;
-+ text-align: center;
- }
- .Page:not(:target) {
-- display: none;
-+ display: none !important;
- }
-
- .Page > h2 {
-@@ -36,7 +44,10 @@ body, html {
- .Page .ImageContainer {
- box-shadow: 0px 0px 1em #00000077;
- }
--
-+body.ExpandMode .Page .ImageContainer {
-+ display: inline-block;
-+ margin-bottom: 20px;
-+}
- .Page .ImageContainer {
- position: relative;
- }
-@@ -60,7 +71,7 @@ body.Active .Page .ImageContainer > .Links > a {
- width: 230px;
- display: flex;
- flex-direction: column;
--
-+
- overflow-y: auto;
- overflow-x: visible;
- z-index: 2;
-@@ -69,28 +80,36 @@ body.Active .Page .ImageContainer > .Links > a {
- .TOC > div {
- display: flex;
- flex-direction: column;
-- align-items: center;
-- padding: 1em;
-- background: transparent;
-- transition: background 0.2s ease;
- }
--.TOC > div.Focused {
-+.TOC > div.Focused > a {
- background: #5294E2;
- }
--.TOC > div:not(.Focused):hover {
-+.TOC > div:not(.Focused):hover > a {
- background: #5294E266;
- }
-+.TOC > div:not(.Focused):not(:hover) {
-+ opacity: 0.7;
-+}
- .TOC > div + div {
- margin-top: 1em;
- }
-
- .TOC > div > a {
-+ flex: 1 1 auto;
-+ display: flex;
-+ flex-direction: column;
-+ align-items: center;
-+ padding: 1em;
-+ background: transparent;
-+ transition: background 0.2s ease;
-+ text-decoration: none;
-+}
-+.TOC > div > a > img {
- display: block;
- border: solid 2px #FFF;
- box-shadow: 0px 0px 5px #000;
- }
--
--.TOC > div > strong {
-+.TOC > div > a > strong {
- display: block;
- text-align: center;
- color: #FFF;
-@@ -98,32 +117,27 @@ body.Active .Page .ImageContainer > .Links > a {
- margin-top: 0.3em;
- }
-
-+.ToggleZoomButton {
-+ position: fixed;
-+ top: 0.5em;
-+ right: 0.5em;
-+ width: 1.5em;
-+ height: 1.5em;
-+ padding: 0.3em;
-+ box-sizing: content-box;
-+ background: url(expand.png) 50% 50% no-repeat #CCCCCC;
-+ background-origin: content-box;
-+ background-size: contain;
-
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-+ border: solid 1px #777;
-+}
-+.ToggleZoomButton:active {
-+ margin-top: 1px;
-+ margin-left: 1px;
-+}
-+.ToggleZoomButton:not(:hover) {
-+ opacity: 0.3;
-+}
-+body.ExpandMode .ToggleZoomButton {
-+ background-image: url(fit.png)
-+}
-diff --git a/app/pencil-core/xferHelper/pngImageXferHelper.js b/app/pencil-core/xferHelper/pngImageXferHelper.js
-index 5b04db6..6879391 100644
---- a/app/pencil-core/xferHelper/pngImageXferHelper.js
-+++ b/app/pencil-core/xferHelper/pngImageXferHelper.js
-@@ -32,7 +32,8 @@ PNGImageXferHelper.prototype.handleDataImpl = function (imageData, shapeId) {
- this.canvas.insertShape(bitmapDef, this.canvas.lastMouse || {x: 10, y: 10});
-
- if (this.canvas.currentController) {
-- var dim = new Dimension(imageData.w, imageData.h);
-+ var ratio = window.devicePixelRatio || 1;
-+ var dim = new Dimension(Math.round(imageData.w / ratio), Math.round(imageData.h / ratio));
- this.canvas.currentController.setProperty("imageData", imageData);
- this.canvas.currentController.setProperty("box", dim);
- this.canvas.invalidateEditors();
-@@ -67,7 +68,8 @@ JPGGIFImageXferHelper.prototype.handleData = function (url) {
- var thiz = this;
-
- var handler = function (imageData) {
-- var dim = new Dimension(imageData.w, imageData.h);
-+ var ratio = window.devicePixelRatio || 1;
-+ var dim = new Dimension(Math.round(imageData.w / ratio), Math.round(imageData.h / ratio));
- thiz.canvas.currentController.setProperty("imageData", imageData);
- thiz.canvas.currentController.setProperty("box", dim);
- thiz.canvas.invalidateEditors();
-diff --git a/app/views/ApplicationPane.js b/app/views/ApplicationPane.js
-index 704fbac..7e2f960 100644
---- a/app/views/ApplicationPane.js
-+++ b/app/views/ApplicationPane.js
-@@ -125,13 +125,24 @@ ApplicationPane.prototype.onAttached = function () {
- // });
- // });
- // }, 100);
--
--
-+
-+
- };
-+
-+Config.UI_CUSTOM_FONT_FAMILY = Config.define("ui.customUIFontFamily", "");
-+Config.UI_CUSTOM_FONT_SIZE = Config.define("ui.customUIFontSize", "");
-+
- ApplicationPane.prototype.invalidateUIForConfig = function () {
- debug("BOOT: invalidating UI using configuration");
- var useCompactLayout = Config.get("view.useCompactLayout", false);
- document.body.setAttribute("compact-layout", useCompactLayout);
-+
-+ var family = Config.get(Config.UI_CUSTOM_FONT_FAMILY);
-+ if (family) document.body.style.fontFamily = family;
-+
-+ var size = Config.get(Config.UI_CUSTOM_FONT_SIZE);
-+ if (size) document.body.style.fontSize = size;
-+
- this.toolBarSrollView.invalidate();
- };
- ApplicationPane.prototype.invalidateUIForControllerStatus = function () {
-@@ -172,19 +183,19 @@ ApplicationPane.prototype.createCanvas = function () {
- var stencilToolbar = new StencilShapeCanvasToolbar().into(wrapper);
-
- var canvas = null;
--
--
-+
-+
- scrollPane.addEventListener("mousedown", function (e) {
- scrollPane._mouseDownAt = e.timeStamp;
- });
--
-+
- scrollPane.addEventListener("mouseup", function (e) {
- if (!scrollPane._mouseDownAt || (e.timeStamp - scrollPane._mouseDownAt) > 150) return;
- if (!Dom.findParentWithClass(e.target, "CanvasWrapper")) {
- if (!canvas.isSelectingRange) canvas.selectNone();
- }
- });
--
-+
- canvas = new Canvas(container, null, scrollPane);
-
- this.getCanvasContainer().appendChild(scrollPane);
-@@ -288,7 +299,7 @@ ApplicationPane.prototype.showStartupPane = function () {
- const NO_CONTENT_VALUE = 22;
- ApplicationPane.prototype.getNoContentValue = function () {
- var compact = Config.get("view.useCompactLayout", false);
-- return compact ? 0 : NO_CONTENT_VALUE;
-+ return compact ? 10 : NO_CONTENT_VALUE;
- }
- ApplicationPane.prototype.getCanvasToolbarHeight = function () {
- return StencilCollectionBuilder.isDocumentConfiguredAsStencilCollection() ? Math.round(3 * Util.em()) : 0;
-diff --git a/app/views/ExportDialog.js b/app/views/ExportDialog.js
-index 9e9dcb4..34b6679 100644
---- a/app/views/ExportDialog.js
-+++ b/app/views/ExportDialog.js
-@@ -243,10 +243,10 @@ ExportDialog.prototype.getDialogActions = function () {
- }
-
- dialogOptions.filters = filters;
-- console.log("dialogOptions", dialogOptions);
-- dialog.showSaveDialog(dialogOptions, function (filename) {
-- if (!filename) return;
-- result.targetPath = filename;
-+ dialog.showSaveDialog(dialogOptions).then(function (res) {
-+ if (!res || !res.filePath) return;
-+ result.targetPath = res.filePath;
-+ console.log("Selected", res.filePath);
-
- this.close(result);
-
-@@ -262,9 +262,9 @@ ExportDialog.prototype.getDialogActions = function () {
- }
- }
-
-- dialog.showOpenDialog(dialogOptions, function (filenames) {
-- if (!filenames || filenames.length <= 0) return;
-- result.targetPath = filenames[0];
-+ dialog.showOpenDialog(dialogOptions).then(function (res) {
-+ if (!res || !res.filePaths || res.filePaths.length <= 0) return;
-+ result.targetPath = res.filePaths[0];
-
- this.close(result);
-
-diff --git a/app/views/StartUpDocumentView.js b/app/views/StartUpDocumentView.js
-index 8e02e23..93bf998 100644
---- a/app/views/StartUpDocumentView.js
-+++ b/app/views/StartUpDocumentView.js
-@@ -24,7 +24,7 @@ function StartUpDocumentView() {
- if (pinDocs && pinDocs.indexOf(filePath) >= 0) Dom.addClass(binding.pin, "Unpin");
- if (thumbPath) {
- window.setTimeout(function () {
-- Util.setupImage(binding.thumbnailImage, ImageData.filePathToURL(thumbPath), "center-crop", "allowUpscale");
-+ Util.setupImage(binding.thumbnailImage, ImageData.filePathToURL(thumbPath), "center-top-crop", "allowUpscale");
- }, 10);
- }
- binding._node._filePath = filePath;
-diff --git a/app/views/StartUpDocumentView.xhtml b/app/views/StartUpDocumentView.xhtml
-index 05e6eeb..3f136f9 100644
---- a/app/views/StartUpDocumentView.xhtml
-+++ b/app/views/StartUpDocumentView.xhtml
-@@ -44,7 +44,7 @@
- }
- @recentDocumentPane .Repeater-Document vbox[role="item"] .ImageContainer {
- width: 22ex;
-- height: 25ex;
-+ height: 14ex;
- background: #FFF;
- }
- @recentDocumentPane .Repeater-Document vbox[role="item"] .InfoPane {
-diff --git a/app/views/collections/BaseCollectionPane.js b/app/views/collections/BaseCollectionPane.js
-index 9019fb0..aff7054 100644
---- a/app/views/collections/BaseCollectionPane.js
-+++ b/app/views/collections/BaseCollectionPane.js
-@@ -224,12 +224,13 @@ BaseCollectionPane.prototype.reload = function (selectedCollectionId) {
- BaseCollectionPane.prototype.filterCollections = function () {
- var filter = this.searchInput.value;
- this.clearTextButton.style.display = filter != null && filter.length > 0 ? "block" : "none"
-- var collectionNodes = Dom.getList(".//*[@class='Item']", this.selectorPane);
-+ var collectionNodes = this.selectorPane.querySelectorAll(".Item");
- var hasLast = false;
- var firstNode = null;
- for (var i in collectionNodes) {
- var collectionNode = collectionNodes[i];
- var collection = collectionNodes[i]._collection;
-+ if (!collection) continue;
- collection._shapeCount = 0;
- collection._filteredShapes = [];
- if (!filter) {
-@@ -244,6 +245,7 @@ BaseCollectionPane.prototype.filterCollections = function () {
- collection._filteredShapes.push(def);
- }
- }
-+
- if (collection._shapeCount <= 0) {
- collectionNode.setAttribute("_hidden", true);
- collectionNode.style.display = "none";
-diff --git a/app/views/collections/CollectionBrowserDialog.js b/app/views/collections/CollectionBrowserDialog.js
-index b2b7edf..e6917f8 100644
---- a/app/views/collections/CollectionBrowserDialog.js
-+++ b/app/views/collections/CollectionBrowserDialog.js
-@@ -9,9 +9,9 @@ function CollectionBrowserDialog (collectionPanel, managerDialog) {
- this.managerDialog = managerDialog;
- this.title = "Collection Repository";
- this.subTitle = "Browse the user-contributed collection repository."
--
-+
- var thiz = this;
--
-+
- this.bind("e:TabChange", function (event) {
- var tab = this.tabPane.getActiveTabPane();
- if (!tab._initialized) {
-diff --git a/app/views/common/Dialog.xhtml b/app/views/common/Dialog.xhtml
-index fd43ad3..9acee3c 100644
---- a/app/views/common/Dialog.xhtml
-+++ b/app/views/common/Dialog.xhtml
-@@ -52,8 +52,8 @@
- background: rgba(0, 0, 0, 0.05);
- }
- body @dialogFrame @dialogTitle {
-- color: #555555;
-- font-size: 1em;
-+ color: #567ab4;
-+ font-size: 1.3em;
- display: block;
- }
- body @dialogFrame @dialogSubTitle {
-@@ -63,18 +63,18 @@
- display: none;
- }
- body @dialogFrame @dialogTitleContainer {
-- padding: 0.5em;
- }
- body @dialogFrame @dialogHeaderPane {
- margin-bottom: 0em;
-- background: #d3d3d3;
- }
- body @dialogFrame @dialogBody {
- padding: 1.2em;
- overflow: hidden;
- }
- body @dialogFrame @dialogHeaderPane {
-- padding: 0.4em 0.7em;
-+ padding: 1.2em;
-+ padding-bottom: 0.2em;
-+ align-items: center;
- }
- body @dialogFrame @dialogBody {
- padding-bottom: 0em;
-@@ -96,6 +96,8 @@
- min-width: 6em;
- text-align: center;
- display: inline-block;
-+ font-weight: bold;
-+ text-transform: capitalize;
- }
-
- body @dialogFooter > hbox > button[mode='accept'] {
-diff --git a/app/views/common/PageThumbnailView.js b/app/views/common/PageThumbnailView.js
-index 46cadd9..fd1f0d2 100644
---- a/app/views/common/PageThumbnailView.js
-+++ b/app/views/common/PageThumbnailView.js
-@@ -1,24 +1,24 @@
- function PageThumbnailView() {
- BaseTemplatedWidget.call(this);
-- this.bind("load", function (event) {
-- var W = this.pageThumbnailContainer.offsetWidth - 2;
-- var H = this.pageThumbnailContainer.offsetHeight - 2;
-- var w = this.pageThumbnail.naturalWidth;
-- var h = this.pageThumbnail.naturalHeight;
--
-- var r = Math.min(w/W, h/H);
--
-- w /= r;
-- h /= r;
--
-- this.pageThumbnail.style.width = w + "px";
-- this.pageThumbnail.style.height = h + "px";
--
-- this.pageThumbnail.style.left = (W - w) / 2 + "px";
-- this.pageThumbnail.style.top = (H - h) / 2 + "px";
--
-- this.pageThumbnail.style.visibility = "visible";
-- }, this.pageThumbnail);
-+ // this.bind("load", function (event) {
-+ // var W = this.pageThumbnailContainer.offsetWidth - 2;
-+ // var H = this.pageThumbnailContainer.offsetHeight - 2;
-+ // var w = this.pageThumbnail.naturalWidth;
-+ // var h = this.pageThumbnail.naturalHeight;
-+ //
-+ // var r = Math.min(w/W, h/H);
-+ //
-+ // w /= r;
-+ // h /= r;
-+ //
-+ // this.pageThumbnail.style.width = w + "px";
-+ // this.pageThumbnail.style.height = h + "px";
-+ //
-+ // this.pageThumbnail.style.left = (W - w) / 2 + "px";
-+ // this.pageThumbnail.style.top = (H - h) / 2 + "px";
-+ //
-+ // this.pageThumbnail.style.visibility = "visible";
-+ // }, this.pageThumbnail);
-
- this.pageThumbnail.style.visibility = "hidden";
-
-@@ -47,7 +47,7 @@ PageThumbnailView.prototype.setPage = function (page, childMenu) {
- PageThumbnailView.prototype._updateUI = function () {
- this.pageThumbnail.style.visibility = "hidden";
- if (!this.page.children || this.page.children.length == 0) this.pageActionButton.style.visibility = "hidden";
-- if (this.page.thumbPath) this.pageThumbnail.src = this.page.thumbPath + "?time=" + (new Date().getTime());
-+ if (this.page.thumbPath) Util.setupImage(this.pageThumbnail, this.page.thumbPath + "?time=" + (new Date().getTime()), "center-top-crop", "allowUpscale");
- // this.pageTitle.appendChild(document.createTextNode(this.page.name));
- this.pageTitle.innerHTML = Dom.htmlEncode(this.page.name);
- this.node().setAttribute("title", this.page.name);
-diff --git a/app/views/common/ProgressiveJobDialog.xhtml b/app/views/common/ProgressiveJobDialog.xhtml
-index ba92c73..c233dc2 100644
---- a/app/views/common/ProgressiveJobDialog.xhtml
-+++ b/app/views/common/ProgressiveJobDialog.xhtml
-@@ -7,7 +7,7 @@
- }
- @progressBar,
- @statusLabel {
-- width: 18em;
-+ width: 24em;
- overflow: hidden;
- text-overflow: ellipsis;
- }
-@@ -15,6 +15,9 @@
- height: 100%;
- background: @selected_bg;
- }
-+ @statusLabel {
-+ white-space: nowrap;
-+ }
- @container {
- padding: 1em;
- }
-diff --git a/app/views/common/Tree.js b/app/views/common/Tree.js
-index 2b7ae54..7ac27fa 100644
---- a/app/views/common/Tree.js
-+++ b/app/views/common/Tree.js
-@@ -96,7 +96,7 @@ var Tree = function() {
- if ((target.checked && tree.options.propagateCheckActionDownwards)
- || (!target.checked && tree.options.propagateUncheckActionDownwards)) {
- var itemNode = target.parentNode.parentNode;
-- setItemsCheckedRecursivelyFromNodes(getChildrenContainerFromItemNode(itemNode).childNodes, target.checked);
-+ if (!event.shiftKey) setItemsCheckedRecursivelyFromNodes(getChildrenContainerFromItemNode(itemNode).childNodes, target.checked);
- }
-
- Dom.emitEvent("blur", treeContainer, {});
-diff --git a/app/views/editors/AlignEditor.js b/app/views/editors/AlignEditor.js
-index 88132c2..84d2dac 100644
---- a/app/views/editors/AlignEditor.js
-+++ b/app/views/editors/AlignEditor.js
-@@ -10,12 +10,12 @@ AlignEditor.prototype.setup = function () {
- AlignEditor.prototype._handleClick = function (event) {
- var button = Dom.findParentByTagName(event.target, "button");
- if (!button) return;
--
-+
- button.parentNode.querySelectorAll("button").forEach(function (b) {
- b.setAttribute("checked", b == button);
- });
--
-- this.fireChangeEvent();
-+
-+ this.fireChangeEvent(button.parentNode == this.horizontalGroup ? Alignment.H : Alignment.V);
- };
- AlignEditor.prototype.setValue = function (alignment) {
- this.horizontalGroup.querySelectorAll("button").forEach(function (button) {
-diff --git a/app/views/editors/ColorSelector.js b/app/views/editors/ColorSelector.js
-index 39f93f1..bb5583f 100644
---- a/app/views/editors/ColorSelector.js
-+++ b/app/views/editors/ColorSelector.js
-@@ -193,14 +193,14 @@ function ColorSelector() {
- }
- this.recentlyUsedColor.addEventListener("click", colorListSelectHandler, false);
- this.documentPaletteContainer.addEventListener("click", colorListSelectHandler, false);
--
-+
- this.bind("contextmenu", function (event) {
- var color = Dom.findUpwardForData(event.target, "_color");
- if (!color) return;
-
- ColorSelector._handlePaletteMenu(thiz, color, event);
- }, this.documentPaletteContainer);
--
-+
- this.bind("click", this.pickColor, this.pickerButton);
- this.bind("click", this.addToPalette, this.addToPaletteButton);
- }
-@@ -235,7 +235,7 @@ ColorSelector._handlePaletteMenu = function (thiz, color, event) {
- }
- });
- }
--
-+
- ColorSelector._colorToRemove = color;
- ColorSelector._instanceForMenu = thiz;
- ColorSelector._paletteMenu.showMenuAt(event.clientX, event.clientY);
-@@ -354,7 +354,7 @@ ColorSelector.prototype.setupColors = function () {
- };
- ColorSelector.prototype.loadRecentlyUsedColors = function () {
- var colors = Config.get("gridcolorpicker.recentlyUsedColors", "");
--
-+
- this._lastUsedColors = colors;
- var c = colors.split(",");
- this.recentlyUsedColors = c;
-@@ -378,16 +378,16 @@ ColorSelector.prototype.addToPalette = function () {
- ColorSelector.prototype.loadDocumentColors = function () {
- Dom.toggleClass(this.documentPalettePane, "NoDocument", Pencil.controller && Pencil.controller.doc ? false : true);
- if (!Pencil.controller || !Pencil.controller.doc) return;
--
-+
- Dom.setInnerText(this.paletteTitle, (Pencil.controller.doc.name || "Untitled Document") + " color palette:")
--
-+
- var colors = Pencil.controller.getDocumentColorPalette();
- if (!colors || colors.length == 0) {
- Dom.addClass(this.documentPalettePane, "Empty");
- } else {
- Dom.removeClass(this.documentPalettePane, "Empty");
- }
--
-+
- Dom.empty(this.documentPaletteContainer);
- colors.forEach(function (c) {
- var cell = document.createElement("div");
-@@ -543,20 +543,20 @@ ColorSelector.installGlobalListeners = function () {
- ColorSelector.currentPickerInstance.onColorPickingCanceled();
- return;
- }
--
-+
- var maxWidth = 0;
- var maxHeight = 0;
- displays.forEach(function (d) {
- maxWidth = Math.max(maxWidth, d.bounds.x + d.bounds.width);
- maxHeight = Math.max(maxHeight, d.bounds.y + d.bounds.height);
- });
--
-+
-
- document.body.setAttribute("color-picker-active", "picking");
--
-+
- var x = event.screenX;
- var y = event.screenY;
--
-+
- new Capturer().captureFullScreenData(
- {
- x: 0,
-@@ -574,7 +574,7 @@ ColorSelector.installGlobalListeners = function () {
- ColorSelector.currentPickerInstance.onColorPickingCanceled();
- return;
- }
--
-+
- ColorSelector.currentPickerInstance.onColorPicked(color);
- ColorSelector.currentPickerInstance = null;
- });
-@@ -611,15 +611,17 @@ ColorSelector.installGlobalListeners = function () {
- };
- ColorSelector.prototype.onColorPickingCanceled = function () {
- document.body.removeAttribute("color-picker-active");
-+ document.body.removeAttribute("color-picker-active-external");
- BaseWidget.closableProcessingDisabled = false;
- ColorSelector.currentPickerInstance = null;
- BaseWidget.unregisterClosable(ColorSelector._pickerClosable);
- };
- ColorSelector.prototype.onColorPicked = function (color) {
- document.body.removeAttribute("color-picker-active");
-+ document.body.removeAttribute("color-picker-active-external");
- BaseWidget.closableProcessingDisabled = false;
- BaseWidget.unregisterClosable(ColorSelector._pickerClosable);
--
-+
- var a = this.color.a;
- this.color = Color.fromString(color);
- this.color.a = a;
-@@ -633,7 +635,42 @@ ColorSelector._pickerClosable = {
- }
- };
-
--ColorSelector.prototype.pickColor = function () {
-+ColorSelector.CONFIG_EXTERNAL_COLOR_PICKER_PATH = Config.define("color.external_picker_path", "");
-+
-+ColorSelector.prototype.pickColor = function (event) {
-+ var externalPickerPath = Config.get(ColorSelector.CONFIG_EXTERNAL_COLOR_PICKER_PATH, "");
-+ if (!externalPickerPath) {
-+ this.pickColorUsingElectronCapture();
-+ return;
-+ }
-+
-+ var thiz = this;
-+
-+ if (event && event.shiftKey) {
-+ window.setTimeout(function () {
-+ thiz.pickColorUsingExternalTool(externalPickerPath);
-+ }, 2000);
-+ } else {
-+ thiz.pickColorUsingExternalTool(externalPickerPath);
-+ }
-+};
-+ColorSelector.prototype.pickColorUsingExternalTool = function (externalPickerPath) {
-+ var thiz = this;
-+
-+ document.body.setAttribute("color-picker-active-external", true);
-+ var exec = require("child_process").exec;
-+ exec(externalPickerPath, function (error, stdout, stderr) {
-+ var color = stdout;
-+ console.log("Color: " + color);
-+ if (color) {
-+ thiz.onColorPicked(color.replace(/[^0-9#A-F]+/gi, ""));
-+ } else {
-+ thiz.onColorPickingCanceled();
-+ }
-+ });
-+}
-+
-+ColorSelector.prototype.pickColorUsingElectronCapture = function () {
- ColorSelector.installGlobalListeners();
-
- document.body.setAttribute("color-picker-active", true);
-@@ -641,4 +678,4 @@ ColorSelector.prototype.pickColor = function () {
-
- ColorSelector.currentPickerInstance = this;
- BaseWidget.registerClosable(ColorSelector._pickerClosable);
--};
-\ No newline at end of file
-+};
-diff --git a/app/views/editors/ColorSelector.xhtml b/app/views/editors/ColorSelector.xhtml
-index e46c0c7..51afcb3 100644
---- a/app/views/editors/ColorSelector.xhtml
-+++ b/app/views/editors/ColorSelector.xhtml
-@@ -147,7 +147,8 @@
- margin-left: 0.2ex;
- }
-
-- body[color-picker-active] .ColorPopup {
-+ body[color-picker-active] .ColorPopup,
-+ body[color-picker-active-external] .ColorPopup {
- visibility: hidden !important;
- }
- body[color-picker-active="true"],
-diff --git a/app/views/editors/FontEditor.js b/app/views/editors/FontEditor.js
-index f0fdfc6..52fb49e 100644
---- a/app/views/editors/FontEditor.js
-+++ b/app/views/editors/FontEditor.js
-@@ -37,14 +37,14 @@ FontEditor._loadFontItems = function (fontCombo, withNullValue) {
- FontEditor.prototype.setup = function () {
- var thiz = this;
- FontEditor._setupFontCombo(this.fontCombo, function () {
-- thiz.fireChangeEvent();
-+ thiz.fireChangeEvent(Font.FAMILY);
- });
-
- this.bind("p:ItemSelected", this.invalidateWeightCombo, this.fontCombo);
-
- this.pixelFontSize.addEventListener("input", function(event) {
- if (!thiz.font || OnScreenTextEditor.isEditing || thiz.pixelFontSize.value == "" || thiz.pixelFontSize.value < 5) return;
-- thiz.fireChangeEvent();
-+ thiz.fireChangeEvent(Font.SIZE);
- }, false);
- this.pixelFontSize.addEventListener("keyup", function(event) {
- if (event.keyCode == 13 || event.keyCode == 10) {
-@@ -52,19 +52,19 @@ FontEditor.prototype.setup = function () {
- if (thiz.pixelFontSize.value == "" || thiz.pixelFontSize.value < 5) {
- thiz.pixelFontSize.value = 5;
- }
-- thiz.fireChangeEvent();
-+ thiz.fireChangeEvent(Font.SIZE);
- }
- }, false);
- this.pixelFontSize.addEventListener("wheel", function(event) {
- if (!thiz.font || OnScreenTextEditor.isEditing || thiz.pixelFontSize.value == "" || thiz.pixelFontSize.value < 5) return;
-- thiz.fireChangeEvent();
-+ thiz.fireChangeEvent(Font.SIZE);
- });
- this.pixelFontSize.addEventListener("change", function(event) {
- if (!thiz.font || OnScreenTextEditor.isEditing) return;
- if (thiz.pixelFontSize.value == "" || thiz.pixelFontSize.value < 5) {
- thiz.pixelFontSize.value = 5;
- }
-- thiz.fireChangeEvent();
-+ thiz.fireChangeEvent(Font.SIZE);
- }, false);
-
- this.boldButton.addEventListener("click", function(event) {
-@@ -76,12 +76,12 @@ FontEditor.prototype.setup = function () {
- thiz.boldButton.setAttribute("checked", "true");
- checked = true;
- }
-- thiz.fireChangeEvent();
-+ thiz.fireChangeEvent(Font.WEIGHT);
- }, false);
-
- this.bind("p:ItemSelected", function () {
- if (!thiz.font || OnScreenTextEditor.isEditing) return;
-- thiz.fireChangeEvent();
-+ thiz.fireChangeEvent(Font.WEIGHT);
- }, this.weightCombo);
-
- this.italicButton.addEventListener("click", function(event) {
-@@ -94,7 +94,7 @@ FontEditor.prototype.setup = function () {
- checked = true;
- }
-
-- thiz.fireChangeEvent();
-+ thiz.fireChangeEvent(Font.STYLE);
- }, false);
-
- this.lineHeight.addEventListener("keyup", function(event) {
-@@ -103,19 +103,19 @@ FontEditor.prototype.setup = function () {
- if (thiz.lineHeight.value == "" || thiz.lineHeight.value < 0) {
- thiz.lineHeight.value = 0;
- }
-- thiz.fireChangeEvent();
-+ thiz.fireChangeEvent(Font.WEIGHT);
- }
- }, false);
- this.lineHeight.addEventListener("wheel", function(event) {
- if (!thiz.font || OnScreenTextEditor.isEditing || thiz.lineHeight.value == "" || thiz.lineHeight.value < 0) return;
-- thiz.fireChangeEvent();
-+ thiz.fireChangeEvent(Font.LINE_HEIGHT);
- });
- this.lineHeight.addEventListener("change", function(event) {
- if (!thiz.font || OnScreenTextEditor.isEditing) return;
- if (thiz.lineHeight.value == "" || thiz.lineHeight.value < 0) {
- thiz.lineHeight.value = 0;
- }
-- thiz.fireChangeEvent();
-+ thiz.fireChangeEvent(Font.LINE_HEIGHT);
- }, false);
-
-
-diff --git a/app/views/editors/OnMenuEditor.js b/app/views/editors/OnMenuEditor.js
-index 3b1a307..19fde9e 100644
---- a/app/views/editors/OnMenuEditor.js
-+++ b/app/views/editors/OnMenuEditor.js
-@@ -132,7 +132,8 @@ OnMenuEditor.prototype.generateMenuItems = function () {
- onDone: function (newImageData, options) {
- thiz.targetObject.setProperty(propName, newImageData);
- if (options && options.updateBox) {
-- var dim = new Dimension(newImageData.w, newImageData.h);
-+ var ratio = window.devicePixelRatio || 1;
-+ var dim = new Dimension(Math.round(newImageData.w / ratio), Math.round(newImageData.h / ratio));
- thiz.targetObject.setProperty("box", dim);
- }
- }
-diff --git a/app/views/editors/PropertyEditor.js b/app/views/editors/PropertyEditor.js
-index 9e83182..0a76264 100644
---- a/app/views/editors/PropertyEditor.js
-+++ b/app/views/editors/PropertyEditor.js
-@@ -4,7 +4,7 @@ function PropertyEditor() {
- }
- __extend(BaseTemplatedWidget, PropertyEditor);
-
--PropertyEditor.prototype.fireChangeEvent = function () {
-+PropertyEditor.prototype.fireChangeEvent = function (mask) {
- this.modified = true;
-- Dom.emitEvent("p:ValueChanged", this.node(), {});
-+ Dom.emitEvent("p:ValueChanged", this.node(), {mask: mask});
- };
-diff --git a/app/views/editors/ShadowStyleEditor.js b/app/views/editors/ShadowStyleEditor.js
-index 2fc5512..000fc7b 100644
---- a/app/views/editors/ShadowStyleEditor.js
-+++ b/app/views/editors/ShadowStyleEditor.js
-@@ -27,7 +27,7 @@ ShadowStyleEditor.prototype.setup = function () {
- this.selector.addEventListener("ValueChange", function (event) {
- thiz.color = thiz.selector.getColor().toRGBString();
- thiz.invalidateColorDisplay();
-- thiz.fireChangeEvent();
-+ thiz.fireChangeEvent(ShadowStyle.COLOR);
- }, false);
-
- this.selector.addEventListener("p:CloseColorSelector", function (event) {
-@@ -37,8 +37,17 @@ ShadowStyleEditor.prototype.setup = function () {
- }
- }, false);
-
-- this.node().addEventListener("change", function (event) {
-- thiz.fireChangeEvent();
-+ this.dx.addEventListener("change", function (event) {
-+ thiz.fireChangeEvent(ShadowStyle.DX);
-+ }, false);
-+ this.dy.addEventListener("change", function (event) {
-+ thiz.fireChangeEvent(ShadowStyle.DY);
-+ }, false);
-+ this.size.addEventListener("change", function (event) {
-+ thiz.fireChangeEvent(ShadowStyle.SIZE);
-+ }, false);
-+ this.opacity.addEventListener("change", function (event) {
-+ thiz.fireChangeEvent(ShadowStyle.OPACITY);
- }, false);
- };
- ShadowStyleEditor.prototype.setValue = function (shadowStyle) {
-diff --git a/app/views/editors/SharedBorderStyleEditor.js b/app/views/editors/SharedBorderStyleEditor.js
-index ccc5c72..72c410e 100644
---- a/app/views/editors/SharedBorderStyleEditor.js
-+++ b/app/views/editors/SharedBorderStyleEditor.js
-@@ -14,10 +14,10 @@ SharedBorderStyleEditor.prototype.setup = function () {
-
- var thiz = this;
- this.editor.addEventListener("p:ItemSelected", function (event) {
-- thiz.handleCommandEvent();
-+ thiz.handleCommandEvent(StrokeStyle.ARRAY);
- }, false);
- this.editor.addEventListener("input", function (event) {
-- thiz.handleCommandEvent();
-+ thiz.handleCommandEvent(StrokeStyle.W);
- }, false);
-
- this.editor.addEventListener("keypress", function (event) {
-@@ -27,11 +27,11 @@ SharedBorderStyleEditor.prototype.setup = function () {
- }, false);
-
- };
--SharedBorderStyleEditor.prototype.handleCommandEvent = function () {
-+SharedBorderStyleEditor.prototype.handleCommandEvent = function (mask) {
- var thiz = this;
- var style = thiz.editor.getValue();
- Pencil.activeCanvas.run(function () {
-- this.setProperty(SharedBorderStyleEditor.PROPERTY_NAME, thiz.editor.getValue());
-+ this.setProperty(SharedBorderStyleEditor.PROPERTY_NAME, thiz.editor.getValue(), false, mask);
- Pencil.activeCanvas.snappingHelper.updateSnappingGuide(this);
- thiz.invalidate();
- Pencil.activeCanvas.invalidateEditors(thiz);
-diff --git a/app/views/editors/SharedFontEditor.js b/app/views/editors/SharedFontEditor.js
-index b9f493e..d5df4af 100644
---- a/app/views/editors/SharedFontEditor.js
-+++ b/app/views/editors/SharedFontEditor.js
-@@ -20,7 +20,7 @@ SharedFontEditor.prototype.setup = function () {
- FontEditor._setupFontCombo(this.fontCombo, function(event) {
- if (!thiz.target || !thiz.font || OnScreenTextEditor.isEditing) return;
- thiz.font.family = thiz.fontCombo.getSelectedItem().family;
-- thiz._applyValue();
-+ thiz._applyValue(Font.FAMILY);
- });
-
- this.bind("p:ItemSelected", this.invalidateWeightCombo, this.fontCombo);
-@@ -28,20 +28,20 @@ SharedFontEditor.prototype.setup = function () {
- this.pixelFontSize.addEventListener("input", function(event) {
- if (!thiz.target || !thiz.font || OnScreenTextEditor.isEditing || thiz.pixelFontSize.value == "" || thiz.pixelFontSize.value == "0") return;
- thiz.font.size = thiz.pixelFontSize.value + "px";
-- thiz._applyValue();
-+ thiz._applyValue(Font.SIZE);
- }, false);
-
- this.pixelFontSize.addEventListener("wheel", function(event) {
- if (!thiz.target || !thiz.font || OnScreenTextEditor.isEditing || thiz.pixelFontSize.value == "") return;
- thiz.font.size = thiz.pixelFontSize.value + "px";
-- thiz._applyValue();
-+ thiz._applyValue(Font.SIZE);
- });
- this.pixelFontSize.addEventListener("keyup", function(event) {
- if (event.keyCode == 13 || event.keyCode == 10) {
- if (!thiz.target || !thiz.font || OnScreenTextEditor.isEditing || thiz.pixelFontSize.value == "") return;
- thiz.pixelFontSize.value = Math.max(5, parseInt(thiz.pixelFontSize.value, 10));
- thiz.font.size = thiz.pixelFontSize.value + "px";
-- thiz._applyValue();
-+ thiz._applyValue(Font.SIZE);
- }
- }, false);
- this.pixelFontSize.addEventListener("change", function(event) {
-@@ -60,13 +60,13 @@ SharedFontEditor.prototype.setup = function () {
- checked = true;
- }
- thiz.font.weight = checked ? "bold" : "normal";
-- thiz._applyValue();
-+ thiz._applyValue(Font.WEIGHT);
- }, false);
-
- this.bind("p:ItemSelected", function () {
- if (!thiz.target || !thiz.font || OnScreenTextEditor.isEditing) return;
- thiz.font.weight = thiz.weightCombo.getSelectedItem();
-- thiz._applyValue();
-+ thiz._applyValue(Font.WEIGHT);
-
- }, this.weightCombo);
-
-@@ -82,7 +82,7 @@ SharedFontEditor.prototype.setup = function () {
- }
-
- thiz.font.style = checked ? "italic" : "normal";
-- thiz._applyValue();
-+ thiz._applyValue(Font.STYLE);
- }, false);
-
- this.formatPainterButton.addEventListener("click", function (event) {
-@@ -139,10 +139,10 @@ SharedFontEditor.prototype.beginFormatPainter = function () {
- SharedFontEditor.prototype.isDisabled = function () {
- return this.disabledEditor;
- };
--SharedFontEditor.prototype._applyValue = function () {
-+SharedFontEditor.prototype._applyValue = function (attrMask) {
- var thiz = this;
- Pencil.activeCanvas.run(function() {
-- this.setProperty(SharedFontEditor.PROPERTY_NAME, thiz.font);
-+ this.setProperty(SharedFontEditor.PROPERTY_NAME, thiz.font, false, attrMask);
- }, this.target, Util.getMessage("action.apply.properties.value"))
- };
- SharedFontEditor.prototype.attach = function (target) {
-diff --git a/app/views/editors/SharedPropertyEditor.js b/app/views/editors/SharedPropertyEditor.js
-index 81226ec..62b8388 100644
---- a/app/views/editors/SharedPropertyEditor.js
-+++ b/app/views/editors/SharedPropertyEditor.js
-@@ -18,7 +18,7 @@ SharedPropertyEditor.prototype.setup = function () {
- if (!editor) return;
-
- var propertyName = editor._property.name;
-- thiz.target.setProperty(propertyName, thiz.propertyEditor[propertyName].getValue());
-+ thiz.target.setProperty(propertyName, thiz.propertyEditor[propertyName].getValue(), false, event.mask);
-
- thiz.validationEditorUI();
- }, false);
-diff --git a/app/views/editors/StrokeEditor.js b/app/views/editors/StrokeEditor.js
-index 69179d0..7a03497 100644
---- a/app/views/editors/StrokeEditor.js
-+++ b/app/views/editors/StrokeEditor.js
-@@ -61,11 +61,11 @@ StrokeEditor.prototype.setup = function () {
- this.styleCombo.setItems(strokeItems);
- var thiz = this;
- this.styleCombo.addEventListener("p:ItemSelected", function (event) {
-- thiz.fireChangeEvent();
-+ thiz.fireChangeEvent(StrokeStyle.ARRAY);
- }, false);
- this.strokeWidth.addEventListener("input", function (event) {
- if (thiz.strokeWidth.value == "") thiz.strokeWidth.value = 1;
-- thiz.fireChangeEvent();
-+ thiz.fireChangeEvent(StrokeStyle.W);
- }, false);
-
- };
-diff --git a/app/views/menus/MainMenu.js b/app/views/menus/MainMenu.js
-index 6caddec..8007da2 100644
---- a/app/views/menus/MainMenu.js
-+++ b/app/views/menus/MainMenu.js
-@@ -194,15 +194,15 @@ MainMenu.prototype.setup = function () {
- }
- }));
-
-- // developerToolSubItems.push(UICommandManager.register({
-- // key: "deployStencilCollection",
-- // label: "Deploy Stencil Collection...",
-- // shortcut: "Ctrl+Shift+D",
-- // isAvailable: function () { return Pencil.controller && Pencil.controller.doc; },
-- // run: function () {
-- // new StencilCollectionBuilder(Pencil.controller).deploy();
-- // }
-- // }));
-+ developerToolSubItems.push(UICommandManager.register({
-+ key: "deployStencilCollection",
-+ label: "Deploy Stencil Collection...",
-+ shortcut: "Ctrl+Shift+D",
-+ isAvailable: function () { return Pencil.controller && Pencil.controller.doc; },
-+ run: function () {
-+ new StencilCollectionBuilder(Pencil.controller).deploy();
-+ }
-+ }));
-
- developerToolSubItems.push(UICommandManager.register({
- key: "checkMissingResources",
-diff --git a/app/views/tools/OpenClipartPane.js b/app/views/tools/OpenClipartPane.js
-index 9e34d54..3a2683a 100644
---- a/app/views/tools/OpenClipartPane.js
-+++ b/app/views/tools/OpenClipartPane.js
-@@ -1,7 +1,7 @@
- function OpenClipartPane() {
- BaseTemplatedWidget.call(this);
- var thiz = this;
-- this.backend = new OpenClipartSearch();
-+ this.backend = new OpenClipartSearch2();
-
- function injectSvgInfo (svg) {
- try {
-diff --git a/app/views/tools/ScriptEditorDialog.js b/app/views/tools/ScriptEditorDialog.js
-index 591d79c..b2eae60 100644
---- a/app/views/tools/ScriptEditorDialog.js
-+++ b/app/views/tools/ScriptEditorDialog.js
-@@ -1,6 +1,10 @@
--function ScriptEditorDialog() {
-+function ScriptEditorDialog(large) {
- Dialog.call(this);
- this.title = "Script Editor";
-+
-+ if (large) {
-+ Dom.addClass(this.scriptInputContainer, "Large");
-+ }
- }
- __extend(Dialog, ScriptEditorDialog);
-
-diff --git a/app/views/tools/ScriptEditorDialog.xhtml b/app/views/tools/ScriptEditorDialog.xhtml
-index 8276528..4b617e3 100644
---- a/app/views/tools/ScriptEditorDialog.xhtml
-+++ b/app/views/tools/ScriptEditorDialog.xhtml
-@@ -17,6 +17,10 @@
- height: 40em;
- width: 60em;
- }
-+ @scriptInputContainer.Large {
-+ height: 55em;
-+ width: 100em;
-+ }
-
- </style>
- <hbox flex="1" anon-id="scriptInputContainer">
-diff --git a/app/views/tools/StencilGeneratorDialog.js b/app/views/tools/StencilGeneratorDialog.js
-index 6610dab..aff5834 100644
---- a/app/views/tools/StencilGeneratorDialog.js
-+++ b/app/views/tools/StencilGeneratorDialog.js
-@@ -241,7 +241,7 @@ StencilGeneratorDialog.prototype.loadStencil = function (result, stencils, index
- try {
- var readOnDone = function (fileData) {
- //var data = Base64.encode(fileData, true);
-- var data = new Buffer(fileData).toString("base64");
-+ var data = Buffer.from(fileData).toString("base64");
- var st = {
- id: "img_" + _index,
- label: _stencils[_index]._label,
-diff --git a/package-lock.json b/package-lock.json
-index d07ef39..89df0d2 100644
---- a/package-lock.json
-+++ b/package-lock.json
-@@ -9,10 +9,96 @@
- "integrity": "sha512-XtGk+IF57pr852UK1AhQJXqmm1WmSgS5uISL+LPs0z/iAxXouMvdlLJrHPeukP6gd7yR2rDTMSMkHNODgwIq7A==",
- "dev": true
- },
-+ "@electron/get": {
-+ "version": "1.12.2",
-+ "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.12.2.tgz",
-+ "integrity": "sha512-vAuHUbfvBQpYTJ5wB7uVIDq5c/Ry0fiTBMs7lnEYAo/qXXppIVcWdfBr57u6eRnKdVso7KSiH6p/LbQAG6Izrg==",
-+ "dev": true,
-+ "requires": {
-+ "debug": "^4.1.1",
-+ "env-paths": "^2.2.0",
-+ "fs-extra": "^8.1.0",
-+ "global-agent": "^2.0.2",
-+ "global-tunnel-ng": "^2.7.1",
-+ "got": "^9.6.0",
-+ "progress": "^2.0.3",
-+ "sanitize-filename": "^1.6.2",
-+ "sumchecker": "^3.0.1"
-+ },
-+ "dependencies": {
-+ "debug": {
-+ "version": "4.2.0",
-+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
-+ "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
-+ "dev": true,
-+ "requires": {
-+ "ms": "2.1.2"
-+ }
-+ },
-+ "get-stream": {
-+ "version": "4.1.0",
-+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
-+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
-+ "dev": true,
-+ "requires": {
-+ "pump": "^3.0.0"
-+ }
-+ },
-+ "got": {
-+ "version": "9.6.0",
-+ "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
-+ "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
-+ "dev": true,
-+ "requires": {
-+ "@sindresorhus/is": "^0.14.0",
-+ "@szmarczak/http-timer": "^1.1.2",
-+ "cacheable-request": "^6.0.0",
-+ "decompress-response": "^3.3.0",
-+ "duplexer3": "^0.1.4",
-+ "get-stream": "^4.1.0",
-+ "lowercase-keys": "^1.0.1",
-+ "mimic-response": "^1.0.1",
-+ "p-cancelable": "^1.0.0",
-+ "to-readable-stream": "^1.0.0",
-+ "url-parse-lax": "^3.0.0"
-+ }
-+ },
-+ "prepend-http": {
-+ "version": "2.0.0",
-+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
-+ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
-+ "dev": true
-+ },
-+ "url-parse-lax": {
-+ "version": "3.0.0",
-+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
-+ "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
-+ "dev": true,
-+ "requires": {
-+ "prepend-http": "^2.0.0"
-+ }
-+ }
-+ }
-+ },
-+ "@sindresorhus/is": {
-+ "version": "0.14.0",
-+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
-+ "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
-+ "dev": true
-+ },
-+ "@szmarczak/http-timer": {
-+ "version": "1.1.2",
-+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
-+ "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
-+ "dev": true,
-+ "requires": {
-+ "defer-to-connect": "^1.0.1"
-+ }
-+ },
- "@types/node": {
-- "version": "10.14.15",
-- "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.15.tgz",
-- "integrity": "sha512-CBR5avlLcu0YCILJiDIXeU2pTw7UK/NIxfC63m7d7CVamho1qDEzXKkOtEauQRPMy6MI8mLozth+JJkas7HY6g==",
-+ "version": "12.19.2",
-+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.2.tgz",
-+ "integrity": "sha512-SRH6QM0IMOBBFmDiJ75vlhcbUEYEquvSuhsVW9ijG20JvdFTfOrB1p6ddZxz5y/JNnbf+9HoHhjhOVSX2hsJyA==",
- "dev": true
- },
- "abbrev": {
-@@ -208,12 +294,6 @@
- "sprintf-js": "~1.0.2"
- }
- },
-- "array-find-index": {
-- "version": "1.0.2",
-- "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
-- "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
-- "dev": true
-- },
- "asn1": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
-@@ -289,6 +369,13 @@
- "bluebird": "^3.5.5"
- }
- },
-+ "boolean": {
-+ "version": "3.0.1",
-+ "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.0.1.tgz",
-+ "integrity": "sha512-HRZPIjPcbwAVQvOTxR4YE3o8Xs98NqbbL1iEZDCz7CL8ql0Lt5iOyJFxfnAB0oFs8Oh02F/lLlg30Mexv46LjA==",
-+ "dev": true,
-+ "optional": true
-+ },
- "boxen": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
-@@ -369,6 +456,12 @@
- "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==",
- "dev": true
- },
-+ "buffer-crc32": {
-+ "version": "0.2.13",
-+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
-+ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
-+ "dev": true
-+ },
- "buffer-fill": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
-@@ -437,20 +530,36 @@
- }
- }
- },
-- "camelcase": {
-- "version": "2.1.1",
-- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
-- "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
-- "dev": true
-- },
-- "camelcase-keys": {
-- "version": "2.1.0",
-- "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
-- "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
-+ "cacheable-request": {
-+ "version": "6.1.0",
-+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
-+ "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
- "dev": true,
- "requires": {
-- "camelcase": "^2.0.0",
-- "map-obj": "^1.0.0"
-+ "clone-response": "^1.0.2",
-+ "get-stream": "^5.1.0",
-+ "http-cache-semantics": "^4.0.0",
-+ "keyv": "^3.0.0",
-+ "lowercase-keys": "^2.0.0",
-+ "normalize-url": "^4.1.0",
-+ "responselike": "^1.0.2"
-+ },
-+ "dependencies": {
-+ "get-stream": {
-+ "version": "5.2.0",
-+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
-+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
-+ "dev": true,
-+ "requires": {
-+ "pump": "^3.0.0"
-+ }
-+ },
-+ "lowercase-keys": {
-+ "version": "2.0.0",
-+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
-+ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
-+ "dev": true
-+ }
- }
- },
- "capture-stack-trace": {
-@@ -566,6 +675,15 @@
- "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
- "dev": true
- },
-+ "clone-response": {
-+ "version": "1.0.2",
-+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
-+ "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
-+ "dev": true,
-+ "requires": {
-+ "mimic-response": "^1.0.0"
-+ }
-+ },
- "code-point-at": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
-@@ -617,51 +735,24 @@
- "concat-stream": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
-- "integrity": "sha1-kEvfGUzTEi/Gdcd/xKw9T/D9GjQ=",
-+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
- "dev": true,
- "requires": {
- "buffer-from": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^2.2.2",
- "typedarray": "^0.0.6"
-- },
-- "dependencies": {
-- "isarray": {
-- "version": "1.0.0",
-- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-- "dev": true
-- },
-- "readable-stream": {
-- "version": "2.3.6",
-- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-- "integrity": "sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8=",
-- "dev": true,
-- "requires": {
-- "core-util-is": "~1.0.0",
-- "inherits": "~2.0.3",
-- "isarray": "~1.0.0",
-- "process-nextick-args": "~2.0.0",
-- "safe-buffer": "~5.1.1",
-- "string_decoder": "~1.1.1",
-- "util-deprecate": "~1.0.1"
-- }
-- },
-- "safe-buffer": {
-- "version": "5.1.2",
-- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-- "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=",
-- "dev": true
-- },
-- "string_decoder": {
-- "version": "1.1.1",
-- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-- "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
-- "dev": true,
-- "requires": {
-- "safe-buffer": "~5.1.0"
-- }
-- }
-+ }
-+ },
-+ "config-chain": {
-+ "version": "1.1.12",
-+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz",
-+ "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==",
-+ "dev": true,
-+ "optional": true,
-+ "requires": {
-+ "ini": "^1.3.4",
-+ "proto-list": "~1.2.1"
- }
- },
- "configstore": {
-@@ -684,6 +775,13 @@
- "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
- "dev": true
- },
-+ "core-js": {
-+ "version": "3.6.5",
-+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
-+ "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==",
-+ "dev": true,
-+ "optional": true
-+ },
- "core-util-is": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
-@@ -734,15 +832,6 @@
- "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
- "dev": true
- },
-- "currently-unhandled": {
-- "version": "0.4.1",
-- "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
-- "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
-- "dev": true,
-- "requires": {
-- "array-find-index": "^1.0.1"
-- }
-- },
- "dashdash": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-@@ -775,6 +864,15 @@
- "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
- "dev": true
- },
-+ "decompress-response": {
-+ "version": "3.3.0",
-+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
-+ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
-+ "dev": true,
-+ "requires": {
-+ "mimic-response": "^1.0.0"
-+ }
-+ },
- "deep-extend": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
-@@ -790,6 +888,22 @@
- "clone": "^1.0.2"
- }
- },
-+ "defer-to-connect": {
-+ "version": "1.1.3",
-+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
-+ "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
-+ "dev": true
-+ },
-+ "define-properties": {
-+ "version": "1.1.3",
-+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
-+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
-+ "dev": true,
-+ "optional": true,
-+ "requires": {
-+ "object-keys": "^1.0.12"
-+ }
-+ },
- "delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-@@ -808,6 +922,13 @@
- "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
- "dev": true
- },
-+ "detect-node": {
-+ "version": "2.0.4",
-+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
-+ "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==",
-+ "dev": true,
-+ "optional": true
-+ },
- "dmg-builder": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-5.3.1.tgz",
-@@ -868,13 +989,13 @@
- "dev": true
- },
- "electron": {
-- "version": "6.0.1",
-- "resolved": "https://registry.npmjs.org/electron/-/electron-6.0.1.tgz",
-- "integrity": "sha512-XY69rI5IThIxsOS2BD+1ZkHE9hqkm4xN5a3WQFSmFRr2by4q5CnIe9vXmptlouGPTLs3tb7ySX/+K9CvH3szvg==",
-+ "version": "10.1.5",
-+ "resolved": "https://registry.npmjs.org/electron/-/electron-10.1.5.tgz",
-+ "integrity": "sha512-fys/KnEfJq05TtMij+lFvLuKkuVH030CHYx03iZrW5DNNLwjE6cW3pysJ420lB0FRSfPjTHBMu2eVCf5TG71zQ==",
- "dev": true,
- "requires": {
-- "@types/node": "^10.12.18",
-- "electron-download": "^4.1.0",
-+ "@electron/get": "^1.0.1",
-+ "@types/node": "^12.0.12",
- "extract-zip": "^1.0.3"
- }
- },
-@@ -1047,34 +1168,6 @@
- }
- }
- },
-- "electron-download": {
-- "version": "4.1.1",
-- "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-4.1.1.tgz",
-- "integrity": "sha512-FjEWG9Jb/ppK/2zToP+U5dds114fM1ZOJqMAR4aXXL5CvyPE9fiqBK/9YcwC9poIFQTEJk/EM/zyRwziziRZrg==",
-- "dev": true,
-- "requires": {
-- "debug": "^3.0.0",
-- "env-paths": "^1.0.0",
-- "fs-extra": "^4.0.1",
-- "minimist": "^1.2.0",
-- "nugget": "^2.0.1",
-- "path-exists": "^3.0.0",
-- "rc": "^1.2.1",
-- "semver": "^5.4.1",
-- "sumchecker": "^2.0.2"
-- },
-- "dependencies": {
-- "debug": {
-- "version": "3.2.6",
-- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
-- "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
-- "dev": true,
-- "requires": {
-- "ms": "^2.1.1"
-- }
-- }
-- }
-- },
- "electron-osx-sign": {
- "version": "0.4.10",
- "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.10.tgz",
-@@ -1162,6 +1255,13 @@
- "integrity": "sha1-kzoEBShgyF6DwSJHnEdIqOTHIVY=",
- "dev": true
- },
-+ "encodeurl": {
-+ "version": "1.0.2",
-+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
-+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
-+ "dev": true,
-+ "optional": true
-+ },
- "end-of-stream": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
-@@ -1172,19 +1272,17 @@
- }
- },
- "env-paths": {
-- "version": "1.0.0",
-- "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-1.0.0.tgz",
-- "integrity": "sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=",
-+ "version": "2.2.0",
-+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz",
-+ "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==",
- "dev": true
- },
-- "error-ex": {
-- "version": "1.3.2",
-- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
-- "integrity": "sha1-tKxAZIEH/c3PriQvQovqihTU8b8=",
-+ "es6-error": {
-+ "version": "4.1.1",
-+ "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
-+ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
- "dev": true,
-- "requires": {
-- "is-arrayish": "^0.2.1"
-- }
-+ "optional": true
- },
- "escape-string-regexp": {
- "version": "1.0.5",
-@@ -1220,15 +1318,32 @@
- "dev": true
- },
- "extract-zip": {
-- "version": "1.6.7",
-- "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
-- "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
-+ "version": "1.7.0",
-+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz",
-+ "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==",
- "dev": true,
- "requires": {
-- "concat-stream": "1.6.2",
-- "debug": "2.6.9",
-- "mkdirp": "0.5.1",
-- "yauzl": "2.4.1"
-+ "concat-stream": "^1.6.2",
-+ "debug": "^2.6.9",
-+ "mkdirp": "^0.5.4",
-+ "yauzl": "^2.10.0"
-+ },
-+ "dependencies": {
-+ "minimist": {
-+ "version": "1.2.5",
-+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
-+ "dev": true
-+ },
-+ "mkdirp": {
-+ "version": "0.5.5",
-+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
-+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
-+ "dev": true,
-+ "requires": {
-+ "minimist": "^1.2.5"
-+ }
-+ }
- }
- },
- "extsprintf": {
-@@ -1250,35 +1365,14 @@
- "dev": true
- },
- "fd-slicer": {
-- "version": "1.0.1",
-- "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
-- "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
-+ "version": "1.1.0",
-+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
-+ "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
- "dev": true,
- "requires": {
- "pend": "~1.2.0"
- }
- },
-- "find-up": {
-- "version": "1.1.2",
-- "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
-- "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
-- "dev": true,
-- "requires": {
-- "path-exists": "^2.0.0",
-- "pinkie-promise": "^2.0.0"
-- },
-- "dependencies": {
-- "path-exists": {
-- "version": "2.1.0",
-- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
-- "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
-- "dev": true,
-- "requires": {
-- "pinkie-promise": "^2.0.0"
-- }
-- }
-- }
-- },
- "forever-agent": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
-@@ -1297,12 +1391,12 @@
- }
- },
- "fs-extra": {
-- "version": "4.0.3",
-- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
-- "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
-+ "version": "8.1.0",
-+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
-+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
- "dev": true,
- "requires": {
-- "graceful-fs": "^4.1.2",
-+ "graceful-fs": "^4.2.0",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- }
-@@ -1367,12 +1461,6 @@
- "integrity": "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34=",
- "dev": true
- },
-- "get-stdin": {
-- "version": "4.0.1",
-- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
-- "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
-- "dev": true
-- },
- "get-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
-@@ -1402,6 +1490,31 @@
- "path-is-absolute": "^1.0.0"
- }
- },
-+ "global-agent": {
-+ "version": "2.1.12",
-+ "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.12.tgz",
-+ "integrity": "sha512-caAljRMS/qcDo69X9BfkgrihGUgGx44Fb4QQToNQjsiWh+YlQ66uqYVAdA8Olqit+5Ng0nkz09je3ZzANMZcjg==",
-+ "dev": true,
-+ "optional": true,
-+ "requires": {
-+ "boolean": "^3.0.1",
-+ "core-js": "^3.6.5",
-+ "es6-error": "^4.1.1",
-+ "matcher": "^3.0.0",
-+ "roarr": "^2.15.3",
-+ "semver": "^7.3.2",
-+ "serialize-error": "^7.0.1"
-+ },
-+ "dependencies": {
-+ "semver": {
-+ "version": "7.3.2",
-+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
-+ "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
-+ "dev": true,
-+ "optional": true
-+ }
-+ }
-+ },
- "global-dirs": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
-@@ -1411,6 +1524,29 @@
- "ini": "^1.3.4"
- }
- },
-+ "global-tunnel-ng": {
-+ "version": "2.7.1",
-+ "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz",
-+ "integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==",
-+ "dev": true,
-+ "optional": true,
-+ "requires": {
-+ "encodeurl": "^1.0.2",
-+ "lodash": "^4.17.10",
-+ "npm-conf": "^1.1.3",
-+ "tunnel": "^0.0.6"
-+ }
-+ },
-+ "globalthis": {
-+ "version": "1.0.1",
-+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.1.tgz",
-+ "integrity": "sha512-mJPRTc/P39NH/iNG4mXa9aIhNymaQikTrnspeCa2ZuJ+mH2QN/rXwtX3XwKrHqWgUQFbNZKtHM105aHzJalElw==",
-+ "dev": true,
-+ "optional": true,
-+ "requires": {
-+ "define-properties": "^1.1.3"
-+ }
-+ },
- "got": {
- "version": "6.7.1",
- "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
-@@ -1473,6 +1609,12 @@
- "lru-cache": "^5.1.1"
- }
- },
-+ "http-cache-semantics": {
-+ "version": "4.1.0",
-+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
-+ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
-+ "dev": true
-+ },
- "http-signature": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
-@@ -1505,15 +1647,6 @@
- "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
- "dev": true
- },
-- "indent-string": {
-- "version": "2.1.0",
-- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
-- "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
-- "dev": true,
-- "requires": {
-- "repeating": "^2.0.0"
-- }
-- },
- "inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-@@ -1542,12 +1675,6 @@
- "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
- "dev": true
- },
-- "is-arrayish": {
-- "version": "0.2.1",
-- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
-- "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
-- "dev": true
-- },
- "is-ci": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
-@@ -1557,15 +1684,6 @@
- "ci-info": "^1.5.0"
- }
- },
-- "is-finite": {
-- "version": "1.0.2",
-- "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
-- "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
-- "dev": true,
-- "requires": {
-- "number-is-nan": "^1.0.0"
-- }
-- },
- "is-fullwidth-code-point": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
-@@ -1630,16 +1748,10 @@
- "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
- "dev": true
- },
-- "is-utf8": {
-- "version": "0.2.1",
-- "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
-- "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
-- "dev": true
-- },
- "isarray": {
-- "version": "0.0.1",
-- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
-+ "version": "1.0.0",
-+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "isbinaryfile": {
-@@ -1679,6 +1791,12 @@
- "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
- "dev": true
- },
-+ "json-buffer": {
-+ "version": "3.0.0",
-+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
-+ "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
-+ "dev": true
-+ },
- "json-schema": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
-@@ -1727,6 +1845,15 @@
- "verror": "1.10.0"
- }
- },
-+ "keyv": {
-+ "version": "3.1.0",
-+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
-+ "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
-+ "dev": true,
-+ "requires": {
-+ "json-buffer": "3.0.0"
-+ }
-+ },
- "latest-version": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
-@@ -1751,19 +1878,6 @@
- "invert-kv": "^2.0.0"
- }
- },
-- "load-json-file": {
-- "version": "1.1.0",
-- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
-- "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
-- "dev": true,
-- "requires": {
-- "graceful-fs": "^4.1.2",
-- "parse-json": "^2.2.0",
-- "pify": "^2.0.0",
-- "pinkie-promise": "^2.0.0",
-- "strip-bom": "^2.0.0"
-- }
-- },
- "locate-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
-@@ -1774,6 +1888,13 @@
- "path-exists": "^3.0.0"
- }
- },
-+ "lodash": {
-+ "version": "4.17.20",
-+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
-+ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
-+ "dev": true,
-+ "optional": true
-+ },
- "lodash.assign": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
-@@ -1789,16 +1910,6 @@
- "chalk": "^2.0.1"
- }
- },
-- "loud-rejection": {
-- "version": "1.6.0",
-- "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
-- "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
-- "dev": true,
-- "requires": {
-- "currently-unhandled": "^0.4.1",
-- "signal-exit": "^3.0.0"
-- }
-- },
- "lowercase-keys": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
-@@ -1840,11 +1951,24 @@
- "p-defer": "^1.0.0"
- }
- },
-- "map-obj": {
-- "version": "1.0.1",
-- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
-- "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
-- "dev": true
-+ "matcher": {
-+ "version": "3.0.0",
-+ "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
-+ "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
-+ "dev": true,
-+ "optional": true,
-+ "requires": {
-+ "escape-string-regexp": "^4.0.0"
-+ },
-+ "dependencies": {
-+ "escape-string-regexp": {
-+ "version": "4.0.0",
-+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
-+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
-+ "dev": true,
-+ "optional": true
-+ }
-+ }
- },
- "mem": {
- "version": "4.3.0",
-@@ -1865,24 +1989,6 @@
- }
- }
- },
-- "meow": {
-- "version": "3.7.0",
-- "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
-- "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
-- "dev": true,
-- "requires": {
-- "camelcase-keys": "^2.0.0",
-- "decamelize": "^1.1.2",
-- "loud-rejection": "^1.0.0",
-- "map-obj": "^1.0.1",
-- "minimist": "^1.1.3",
-- "normalize-package-data": "^2.3.4",
-- "object-assign": "^4.0.1",
-- "read-pkg-up": "^1.0.1",
-- "redent": "^1.0.0",
-- "trim-newlines": "^1.0.0"
-- }
-- },
- "mime": {
- "version": "2.4.4",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
-@@ -1910,6 +2016,12 @@
- "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
- "dev": true
- },
-+ "mimic-response": {
-+ "version": "1.0.1",
-+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
-+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
-+ "dev": true
-+ },
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-@@ -2030,6 +2142,23 @@
- "validate-npm-package-license": "^3.0.1"
- }
- },
-+ "normalize-url": {
-+ "version": "4.5.0",
-+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
-+ "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
-+ "dev": true
-+ },
-+ "npm-conf": {
-+ "version": "1.1.3",
-+ "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz",
-+ "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==",
-+ "dev": true,
-+ "optional": true,
-+ "requires": {
-+ "config-chain": "^1.1.11",
-+ "pify": "^3.0.0"
-+ }
-+ },
- "npm-run-path": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
-@@ -2051,21 +2180,6 @@
- "set-blocking": "~2.0.0"
- }
- },
-- "nugget": {
-- "version": "2.0.1",
-- "resolved": "https://registry.npmjs.org/nugget/-/nugget-2.0.1.tgz",
-- "integrity": "sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA=",
-- "dev": true,
-- "requires": {
-- "debug": "^2.1.3",
-- "minimist": "^1.1.0",
-- "pretty-bytes": "^1.0.2",
-- "progress-stream": "^1.1.0",
-- "request": "^2.45.0",
-- "single-line-log": "^1.1.2",
-- "throttleit": "0.0.2"
-- }
-- },
- "number-is-nan": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
-@@ -2085,10 +2199,11 @@
- "dev": true
- },
- "object-keys": {
-- "version": "0.4.0",
-- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
-- "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
-- "dev": true
-+ "version": "1.1.1",
-+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
-+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
-+ "dev": true,
-+ "optional": true
- },
- "once": {
- "version": "1.4.0",
-@@ -2211,6 +2326,12 @@
- "os-tmpdir": "^1.0.0"
- }
- },
-+ "p-cancelable": {
-+ "version": "1.1.0",
-+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
-+ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
-+ "dev": true
-+ },
- "p-defer": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
-@@ -2282,15 +2403,6 @@
- }
- }
- },
-- "parse-json": {
-- "version": "2.2.0",
-- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
-- "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
-- "dev": true,
-- "requires": {
-- "error-ex": "^1.2.0"
-- }
-- },
- "path-exists": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
-@@ -2321,17 +2433,6 @@
- "integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw=",
- "dev": true
- },
-- "path-type": {
-- "version": "1.1.0",
-- "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
-- "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
-- "dev": true,
-- "requires": {
-- "graceful-fs": "^4.1.2",
-- "pify": "^2.0.0",
-- "pinkie-promise": "^2.0.0"
-- }
-- },
- "pend": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
-@@ -2345,25 +2446,11 @@
- "dev": true
- },
- "pify": {
-- "version": "2.3.0",
-- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-- "dev": true
-- },
-- "pinkie": {
-- "version": "2.0.4",
-- "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
-- "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
-- "dev": true
-- },
-- "pinkie-promise": {
-- "version": "2.0.1",
-- "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
-- "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
-+ "version": "3.0.0",
-+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
-+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
- "dev": true,
-- "requires": {
-- "pinkie": "^2.0.0"
-- }
-+ "optional": true
- },
- "plist": {
- "version": "3.0.1",
-@@ -2396,31 +2483,24 @@
- "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
- "dev": true
- },
-- "pretty-bytes": {
-- "version": "1.0.4",
-- "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz",
-- "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=",
-- "dev": true,
-- "requires": {
-- "get-stdin": "^4.0.1",
-- "meow": "^3.1.0"
-- }
-- },
- "process-nextick-args": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
- "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=",
- "dev": true
- },
-- "progress-stream": {
-- "version": "1.2.0",
-- "resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-1.2.0.tgz",
-- "integrity": "sha1-LNPP6jO6OonJwSHsM0er6asSX3c=",
-+ "progress": {
-+ "version": "2.0.3",
-+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
-+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
-+ "dev": true
-+ },
-+ "proto-list": {
-+ "version": "1.2.4",
-+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
-+ "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=",
- "dev": true,
-- "requires": {
-- "speedometer": "~0.1.2",
-- "through2": "~0.2.3"
-- }
-+ "optional": true
- },
- "pseudomap": {
- "version": "1.0.2",
-@@ -2485,47 +2565,27 @@
- "lazy-val": "^1.0.3"
- }
- },
-- "read-pkg": {
-- "version": "1.1.0",
-- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
-- "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
-- "dev": true,
-- "requires": {
-- "load-json-file": "^1.0.0",
-- "normalize-package-data": "^2.3.2",
-- "path-type": "^1.0.0"
-- }
-- },
-- "read-pkg-up": {
-- "version": "1.0.1",
-- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
-- "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
-- "dev": true,
-- "requires": {
-- "find-up": "^1.0.0",
-- "read-pkg": "^1.0.0"
-- }
-- },
- "readable-stream": {
-- "version": "1.1.14",
-- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
-- "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
-+ "version": "2.3.7",
-+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
-+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
-- "inherits": "~2.0.1",
-- "isarray": "0.0.1",
-- "string_decoder": "~0.10.x"
-- }
-- },
-- "redent": {
-- "version": "1.0.0",
-- "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
-- "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
-- "dev": true,
-- "requires": {
-- "indent-string": "^2.1.0",
-- "strip-indent": "^1.0.1"
-+ "inherits": "~2.0.3",
-+ "isarray": "~1.0.0",
-+ "process-nextick-args": "~2.0.0",
-+ "safe-buffer": "~5.1.1",
-+ "string_decoder": "~1.1.1",
-+ "util-deprecate": "~1.0.1"
-+ },
-+ "dependencies": {
-+ "safe-buffer": {
-+ "version": "5.1.2",
-+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-+ "dev": true
-+ }
- }
- },
- "registry-auth-token": {
-@@ -2547,15 +2607,6 @@
- "rc": "^1.0.1"
- }
- },
-- "repeating": {
-- "version": "2.0.1",
-- "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
-- "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
-- "dev": true,
-- "requires": {
-- "is-finite": "^1.0.0"
-- }
-- },
- "request": {
- "version": "2.88.0",
- "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
-@@ -2605,6 +2656,15 @@
- "path-parse": "^1.0.6"
- }
- },
-+ "responselike": {
-+ "version": "1.0.2",
-+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
-+ "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
-+ "dev": true,
-+ "requires": {
-+ "lowercase-keys": "^1.0.0"
-+ }
-+ },
- "restore-cursor": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
-@@ -2624,6 +2684,30 @@
- "glob": "^7.0.5"
- }
- },
-+ "roarr": {
-+ "version": "2.15.4",
-+ "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz",
-+ "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==",
-+ "dev": true,
-+ "optional": true,
-+ "requires": {
-+ "boolean": "^3.0.1",
-+ "detect-node": "^2.0.4",
-+ "globalthis": "^1.0.1",
-+ "json-stringify-safe": "^5.0.1",
-+ "semver-compare": "^1.0.0",
-+ "sprintf-js": "^1.1.2"
-+ },
-+ "dependencies": {
-+ "sprintf-js": {
-+ "version": "1.1.2",
-+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
-+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
-+ "dev": true,
-+ "optional": true
-+ }
-+ }
-+ },
- "rxjs": {
- "version": "6.5.2",
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz",
-@@ -2666,6 +2750,13 @@
- "integrity": "sha1-eQp89v6lRZuslhELKbYEEtyP+Ws=",
- "dev": true
- },
-+ "semver-compare": {
-+ "version": "1.0.0",
-+ "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
-+ "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
-+ "dev": true,
-+ "optional": true
-+ },
- "semver-diff": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
-@@ -2675,6 +2766,16 @@
- "semver": "^5.0.3"
- }
- },
-+ "serialize-error": {
-+ "version": "7.0.1",
-+ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
-+ "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
-+ "dev": true,
-+ "optional": true,
-+ "requires": {
-+ "type-fest": "^0.13.1"
-+ }
-+ },
- "set-blocking": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-@@ -2702,15 +2803,6 @@
- "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
- "dev": true
- },
-- "single-line-log": {
-- "version": "1.1.2",
-- "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-1.1.2.tgz",
-- "integrity": "sha1-wvg/Jzo+GhbtsJlWYdoO1e8DM2Q=",
-- "dev": true,
-- "requires": {
-- "string-width": "^1.0.1"
-- }
-- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-@@ -2787,12 +2879,6 @@
- "integrity": "sha1-NpS1gEVnpFjTyARYQqY1hjL2JlQ=",
- "dev": true
- },
-- "speedometer": {
-- "version": "0.1.4",
-- "resolved": "https://registry.npmjs.org/speedometer/-/speedometer-0.1.4.tgz",
-- "integrity": "sha1-mHbb0qFp0xFUAtSObqYynIgWpQ0=",
-- "dev": true
-- },
- "sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-@@ -2834,10 +2920,21 @@
- }
- },
- "string_decoder": {
-- "version": "0.10.31",
-- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
-- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
-- "dev": true
-+ "version": "1.1.1",
-+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-+ "dev": true,
-+ "requires": {
-+ "safe-buffer": "~5.1.0"
-+ },
-+ "dependencies": {
-+ "safe-buffer": {
-+ "version": "5.1.2",
-+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-+ "dev": true
-+ }
-+ }
- },
- "strip-ansi": {
- "version": "3.0.1",
-@@ -2848,30 +2945,12 @@
- "ansi-regex": "^2.0.0"
- }
- },
-- "strip-bom": {
-- "version": "2.0.0",
-- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
-- "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
-- "dev": true,
-- "requires": {
-- "is-utf8": "^0.2.0"
-- }
-- },
- "strip-eof": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
- "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
- "dev": true
- },
-- "strip-indent": {
-- "version": "1.0.1",
-- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
-- "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
-- "dev": true,
-- "requires": {
-- "get-stdin": "^4.0.1"
-- }
-- },
- "strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
-@@ -2879,12 +2958,23 @@
- "dev": true
- },
- "sumchecker": {
-- "version": "2.0.2",
-- "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-2.0.2.tgz",
-- "integrity": "sha1-D0LBDl0F2l1C7qPlbDOZo31sWz4=",
-+ "version": "3.0.1",
-+ "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
-+ "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
- "dev": true,
- "requires": {
-- "debug": "^2.2.0"
-+ "debug": "^4.1.0"
-+ },
-+ "dependencies": {
-+ "debug": {
-+ "version": "4.2.0",
-+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
-+ "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
-+ "dev": true,
-+ "requires": {
-+ "ms": "2.1.2"
-+ }
-+ }
- }
- },
- "supports-color": {
-@@ -2943,28 +3033,18 @@
- "execa": "^0.7.0"
- }
- },
-- "throttleit": {
-- "version": "0.0.2",
-- "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz",
-- "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=",
-- "dev": true
-- },
-- "through2": {
-- "version": "0.2.3",
-- "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
-- "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=",
-- "dev": true,
-- "requires": {
-- "readable-stream": "~1.1.9",
-- "xtend": "~2.1.1"
-- }
-- },
- "timed-out": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
- "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
- "dev": true
- },
-+ "to-readable-stream": {
-+ "version": "1.0.0",
-+ "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
-+ "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
-+ "dev": true
-+ },
- "tough-cookie": {
- "version": "2.4.3",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
-@@ -2983,12 +3063,6 @@
- }
- }
- },
-- "trim-newlines": {
-- "version": "1.0.0",
-- "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
-- "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
-- "dev": true
-- },
- "truncate-utf8-bytes": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
-@@ -3004,6 +3078,13 @@
- "integrity": "sha1-w8GflZc/sKYpc/sJ2Q2WHuQ+XIo=",
- "dev": true
- },
-+ "tunnel": {
-+ "version": "0.0.6",
-+ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
-+ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
-+ "dev": true,
-+ "optional": true
-+ },
- "tunnel-agent": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-@@ -3019,6 +3100,13 @@
- "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
- "dev": true
- },
-+ "type-fest": {
-+ "version": "0.13.1",
-+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
-+ "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
-+ "dev": true,
-+ "optional": true
-+ },
- "typedarray": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
-@@ -3276,15 +3364,6 @@
- "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=",
- "dev": true
- },
-- "xtend": {
-- "version": "2.1.2",
-- "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
-- "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
-- "dev": true,
-- "requires": {
-- "object-keys": "~0.4.0"
-- }
-- },
- "y18n": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
-@@ -3377,12 +3456,13 @@
- }
- },
- "yauzl": {
-- "version": "2.4.1",
-- "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
-- "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
-+ "version": "2.10.0",
-+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
-+ "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
- "dev": true,
- "requires": {
-- "fd-slicer": "~1.0.1"
-+ "buffer-crc32": "~0.2.3",
-+ "fd-slicer": "~1.1.0"
- }
- }
- }
-diff --git a/package.json b/package.json
-index db31c3b..9c2d20c 100644
---- a/package.json
-+++ b/package.json
-@@ -1,7 +1,7 @@
- {
- "name": "Pencil",
- "devDependencies": {
-- "electron": "6.0.1",
-+ "electron": "10.1.5",
- "electron-builder": "20.28.4",
- "electron-rebuild": "^1.8.5",
- "rimraf": "^2.5.4"
-@@ -71,7 +71,7 @@
- "postinstall": "install-app-deps",
- "install-app-deps": "node ./node_modules/electron-builder/out/install-app-deps.js",
- "start": "./node_modules/.bin/electron ./app",
-- "start:dev": "./node_modules/.bin/electron ./app --enable-dev --enable-transparent-visuals --disable-gpu",
-+ "start:dev": "./node_modules/.bin/electron ./app --enable-dev --enable-transparent-visuals",
- "start:mac": "./node_modules/.bin/electron ./app --enable-dev",
- "clean": "rimraf dist",
- "pack": "build",