diff --git a/AdGuard/build-electron-app.sh b/AdGuard/build-electron-app.sh index e8e7df00..4b4d6525 100644 --- a/AdGuard/build-electron-app.sh +++ b/AdGuard/build-electron-app.sh @@ -56,6 +56,11 @@ else yarn upgrade --force -P safari-ext || exit 1 fi +# Compile electron-remote +cd "node_modules/electron-remote" +yarn install +cd ../.. + # Rebuild safari-ext and other node packages yarn electron-rebuild diff --git a/ElectronMainApp/package.json b/ElectronMainApp/package.json index af57a22b..ec921714 100644 --- a/ElectronMainApp/package.json +++ b/ElectronMainApp/package.json @@ -20,8 +20,9 @@ "electron-debug": "^2.0.0", "electron-log": "^3.0.6", "electron-reload": "^1.3.0", + "electron-remote": "git+https://github.com/AdguardTeam/electron-remote.git#18c5b1d", "electron-simple-updater": "^1.5.0", - "electron-store": "^2.0.0", + "electron-store": "^5.0.0", "electron-updater": "^4.0.6", "filters-downloader": "git+https://github.com/AdguardTeam/FiltersDownloader.git#a7d2177", "i18n": "^0.8.3", diff --git a/ElectronMainApp/src/main/app/content-blocker/content-blocker-adapter.js b/ElectronMainApp/src/main/app/content-blocker/content-blocker-adapter.js index 8e77725d..fcc1a7ca 100644 --- a/ElectronMainApp/src/main/app/content-blocker/content-blocker-adapter.js +++ b/ElectronMainApp/src/main/app/content-blocker/content-blocker-adapter.js @@ -3,11 +3,11 @@ const listeners = require('../../notifier'); const events = require('../../events'); const settings = require('../settings-manager'); const antibanner = require('../antibanner'); -const {jsonFromFilters} = require('../libs/JSConverter'); const whitelist = require('../whitelist'); const log = require('../utils/log'); const concurrent = require('../utils/concurrent'); const {groupRules, rulesGroupsBundles, filterGroupsBundles} = require('./rule-groups'); +const {requireTaskPool} = require('electron-remote'); /** * Safari Content Blocker Adapter @@ -35,7 +35,7 @@ module.exports = (function () { */ const updateContentBlocker = () => { - loadRules(rules => { + loadRules(async rules => { const grouped = groupRules(rules); let overlimit = false; @@ -43,7 +43,8 @@ module.exports = (function () { for (let group of grouped) { let json = emptyBlockerJSON; - const result = jsonFromFilters(group.rules.map(x => x.ruleText), RULES_LIMIT, false, false); + const rulesTexts = group.rules.map(x => x.ruleText); + const result = await jsonFromRules(rulesTexts, false); if (result && result.converted) { json = JSON.parse(result.converted); if (result.overLimit) { @@ -62,7 +63,7 @@ module.exports = (function () { setSafariContentBlocker(rulesGroupsBundles[group.key], json, info); } - const advancedBlocking = setAdvancedBlocking(rules.map(x => x.ruleText)); + const advancedBlocking = await setAdvancedBlocking(rules.map(x => x.ruleText)); listeners.notifyListeners(events.CONTENT_BLOCKER_UPDATED, { rulesCount: rules.length, @@ -73,14 +74,27 @@ module.exports = (function () { }); }; + /** + * Runs converter method for rules + * + * @param rules array of rules + * @param advancedBlocking if we need advanced blocking content + */ + const jsonFromRules = async (rules, advancedBlocking) => { + const converterModule = requireTaskPool(require.resolve('../libs/JSConverter')); + + const result = await converterModule.jsonFromFilters(rules, RULES_LIMIT, false, advancedBlocking); + return result; + }; + /** * Activates advanced blocking json * * @param rules * @return {Array} */ - const setAdvancedBlocking = (rules) => { - const result = jsonFromFilters(rules, RULES_LIMIT, false, true); + const setAdvancedBlocking = async (rules) => { + const result = await jsonFromRules(rules, true); const advancedBlocking = result ? JSON.parse(result.advancedBlocking) : []; setSafariContentBlocker(rulesGroupsBundles["advancedBlocking"], advancedBlocking); diff --git a/ElectronMainApp/src/main/app/filters/filter-rules.js b/ElectronMainApp/src/main/app/filters/filter-rules.js index 4eb215a4..f9c180af 100644 --- a/ElectronMainApp/src/main/app/filters/filter-rules.js +++ b/ElectronMainApp/src/main/app/filters/filter-rules.js @@ -58,7 +58,7 @@ module.exports = (() => { * Saves updated filter rules to the storage. * * @param filterId Filter id - * @param events Events (what has changed?) + * @param eventsToProcess Events (what has changed?) * @private */ const processSaveFilterRulesToStorageEvents = (filterId, eventsToProcess) => { diff --git a/ElectronMainApp/src/main/app/storage/rules-storage.js b/ElectronMainApp/src/main/app/storage/rules-storage.js index aa2e65fb..44d02c01 100644 --- a/ElectronMainApp/src/main/app/storage/rules-storage.js +++ b/ElectronMainApp/src/main/app/storage/rules-storage.js @@ -3,25 +3,38 @@ const store = new Store(); /** * Filter rules storage implementation - * TODO: Look for faster and better implementation */ module.exports = (() => { + const cache = Object.create(null); + const getKey = (path) => { return 'filter_' + path; }; const read = (path, callback) => { + const cached = cache[path]; + if (cached) { + callback(cached); + return; + } + const lines = store.get(getKey(path)); + cache[path] = lines; + callback(lines); }; const write = (path, data, callback) => { + cache[path] = data; + store.set(getKey(path), data); callback(); }; const remove = (path, successCallback) => { + delete cache[path]; + store.delete(getKey(path)); successCallback(); }; diff --git a/ElectronMainApp/src/main/app/utils/log.js b/ElectronMainApp/src/main/app/utils/log.js index a7dd1c8b..f0e754f6 100644 --- a/ElectronMainApp/src/main/app/utils/log.js +++ b/ElectronMainApp/src/main/app/utils/log.js @@ -6,7 +6,7 @@ const logImpl = require('electron-log'); module.exports = (() => { // Redefine if you need it - const CURRENT_LEVEL = "DEBUG"; + const CURRENT_LEVEL = "INFO"; const LEVELS = { ERROR: 1, diff --git a/ElectronMainApp/yarn.lock b/ElectronMainApp/yarn.lock index 3758b1e5..47680e57 100644 --- a/ElectronMainApp/yarn.lock +++ b/ElectronMainApp/yarn.lock @@ -18,7 +18,7 @@ accessibility-developer-tools@^2.11.0: version "2.12.0" resolved "https://registry.yarnpkg.com/accessibility-developer-tools/-/accessibility-developer-tools-2.12.0.tgz#3da0cce9d6ec6373964b84f35db7cfc3df7ab514" -ajv@^6.5.5: +ajv@^6.10.2, ajv@^6.5.5: version "6.10.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" dependencies: @@ -566,15 +566,19 @@ concat-stream@1.6.2, concat-stream@^1.6.0: readable-stream "^2.2.2" typedarray "^0.0.6" -conf@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/conf/-/conf-2.2.0.tgz#ee282efafc1450b61e205372041ad7d866802d9a" - dependencies: - dot-prop "^4.1.0" - env-paths "^1.0.0" - make-dir "^1.0.0" - pkg-up "^2.0.0" - write-file-atomic "^2.3.0" +conf@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/conf/-/conf-6.0.1.tgz#3d0f681ac62e2c528c8a854dfb7ff42ee93195db" + dependencies: + ajv "^6.10.2" + dot-prop "^5.0.0" + env-paths "^2.2.0" + json-schema-typed "^7.0.1" + make-dir "^3.0.0" + onetime "^5.1.0" + pkg-up "^3.0.1" + semver "^6.2.0" + write-file-atomic "^3.0.0" config@^1.31.0: version "1.31.0" @@ -741,11 +745,11 @@ devtron@^1.4.0: highlight.js "^9.3.0" humanize-plus "^1.8.1" -dot-prop@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" +dot-prop@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.1.0.tgz#bdd8c986a77b83e3fca524e53786df916cabbd8a" dependencies: - is-obj "^1.0.0" + is-obj "^2.0.0" duplexify@^3.6.0: version "3.7.1" @@ -860,6 +864,17 @@ electron-reload@^1.3.0: dependencies: chokidar "^3.0.2" +"electron-remote@git+https://github.com/Mizzick/electron-remote.git#cb3d295": + version "1.3.0" + resolved "git+https://github.com/Mizzick/electron-remote.git#cb3d295d5cdf8ca761e2daa0db7a7dd51365d90b" + dependencies: + debug "^2.5.1" + hashids "^1.1.1" + lodash.get "^4.4.2" + pify "^2.3.0" + rxjs "^5.0.0-beta.12" + xmlhttprequest "^1.8.0" + electron-simple-updater@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/electron-simple-updater/-/electron-simple-updater-1.5.0.tgz#c69e13e5a25fbc189203a92bee169c41cf190782" @@ -867,11 +882,12 @@ electron-simple-updater@^1.5.0: httpreq "0.4.24" semver "*" -electron-store@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/electron-store/-/electron-store-2.0.0.tgz#1035cca2a95409d1f54c7466606345852450d64a" +electron-store@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/electron-store/-/electron-store-5.0.0.tgz#d4dc410a49c50c8ef3a8db34b3bdc4097188247f" dependencies: - conf "^2.0.0" + conf "^6.0.0" + type-fest "^0.7.1" electron-updater@^4.0.6: version "4.1.2" @@ -908,6 +924,10 @@ env-paths@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0" +env-paths@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" + errlop@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/errlop/-/errlop-1.1.1.tgz#d9ae4c76c3e64956c5d79e6e035d6343bfd62250" @@ -1130,12 +1150,6 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - dependencies: - locate-path "^2.0.0" - find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -1500,6 +1514,10 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" +hashids@^1.1.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/hashids/-/hashids-1.2.2.tgz#28635c7f2f7360ba463686078eee837479e8eafb" + highlight.js@^9.3.0: version "9.15.10" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.15.10.tgz#7b18ed75c90348c045eef9ed08ca1319a2219ad2" @@ -1728,9 +1746,9 @@ is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" -is-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" @@ -1744,7 +1762,7 @@ is-relative@^1.0.0: dependencies: is-unc-path "^1.0.0" -is-typedarray@~1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -1813,6 +1831,10 @@ json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" +json-schema-typed@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/json-schema-typed/-/json-schema-typed-7.0.1.tgz#5e56564b5a0950423e22b285a30ade219e38084d" + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" @@ -1930,13 +1952,6 @@ load-json-file@^1.0.0: pinkie-promise "^2.0.0" strip-bom "^2.0.0" -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -1948,6 +1963,10 @@ lodash.assign@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + lodash.isequal@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" @@ -1979,11 +1998,11 @@ lru-queue@0.1: dependencies: es5-ext "~0.10.2" -make-dir@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" +make-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.0.tgz#1b5f39f6b9270ed33f9f054c5c0f84304989f801" dependencies: - pify "^3.0.0" + semver "^6.0.0" make-iterator@^1.0.0: version "1.0.1" @@ -2095,6 +2114,10 @@ mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + "minimatch@2 || 3", minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -2378,6 +2401,12 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" +onetime@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" + dependencies: + mimic-fn "^2.1.0" + ora@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318" @@ -2416,34 +2445,18 @@ osenv@^0.1.4: os-homedir "^1.0.0" os-tmpdir "^1.0.0" -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - dependencies: - p-try "^1.0.0" - p-limit@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" dependencies: p-try "^2.0.0" -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - dependencies: - p-limit "^1.1.0" - p-locate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" dependencies: p-limit "^2.0.0" -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -2534,14 +2547,10 @@ picomatch@^2.0.4: version "2.0.7" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6" -pify@^2.0.0: +pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" @@ -2552,11 +2561,11 @@ pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" +pkg-up@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" dependencies: - find-up "^2.1.0" + find-up "^3.0.0" plist@^3.0.1: version "3.0.1" @@ -2851,6 +2860,12 @@ rimraf@2, rimraf@^2.6.1: dependencies: glob "^7.1.3" +rxjs@^5.0.0-beta.12: + version "5.5.12" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" + dependencies: + symbol-observable "1.0.1" + rxjs@^6.3.1: version "6.5.2" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.2.tgz#2e35ce815cd46d84d02a209fb4e5921e051dbec7" @@ -2905,7 +2920,7 @@ semver-greatest-satisfied-range@^1.1.0: dependencies: sver-compat "^1.5.0" -semver@*, semver@^6.2.0: +semver@*, semver@^6.0.0, semver@^6.2.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -3164,6 +3179,10 @@ sver-compat@^1.5.0: es6-iterator "^2.0.1" es6-symbol "^3.1.1" +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" + tar@^4, tar@^4.4.8: version "4.4.10" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.10.tgz#946b2810b9a5e0b26140cf78bea6b0b0d689eba1" @@ -3300,6 +3319,10 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" +type-fest@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" + type@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/type/-/type-1.0.3.tgz#16f5d39f27a2d28d86e48f8981859e9d3296c179" @@ -3318,6 +3341,12 @@ typechecker@~2.0.1: version "2.0.8" resolved "https://registry.yarnpkg.com/typechecker/-/typechecker-2.0.8.tgz#e83da84bb64c584ccb345838576c40b0337db82e" +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -3525,13 +3554,14 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" -write-file-atomic@^2.3.0: - version "2.4.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" +write-file-atomic@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.0.tgz#1b64dbbf77cb58fd09056963d63e62667ab4fb21" dependencies: - graceful-fs "^4.1.11" imurmurhash "^0.1.4" + is-typedarray "^1.0.0" signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" xmlbuilder@^9.0.7: version "9.0.7"