From cc6a87da4046511fb1ef15b2a5ad6c440231aa8c Mon Sep 17 00:00:00 2001 From: Sandor Molnar Date: Wed, 5 Jun 2024 00:07:37 +0300 Subject: [PATCH] Backed out 7 changesets (bug 1894958) for causing bc failures @ browser_usercharacteristics.js CLOSED TREE Backed out changeset f0b3873afbbf (bug 1894958) Backed out changeset 0163ab00de90 (bug 1894958) Backed out changeset dc5209d0115f (bug 1894958) Backed out changeset c7c58e406791 (bug 1894958) Backed out changeset 1ff86ac5480e (bug 1894958) Backed out changeset 862f163cf35c (bug 1894958) Backed out changeset 4ad50fcd042b (bug 1894958) --- .prettierignore | 1 - docshell/base/nsAboutRedirector.cpp | 2 +- docshell/build/components.conf | 2 +- dom/security/nsContentSecurityUtils.cpp | 53 +- .../resistfingerprinting/RFPHelper.sys.mjs | 7 +- .../UserCharacteristicsPageService.sys.mjs | 33 +- .../content/gl-matrix.LICENSE | 19 - .../resistfingerprinting/content/gl-matrix.js | 28 - .../resistfingerprinting/content/moz.yaml | 20 - .../content/usercharacteristics.css | 7 - .../content/usercharacteristics.html | 256 +------- .../content/usercharacteristics.js | 597 +----------------- .../components/resistfingerprinting/jar.mn | 2 - .../resistfingerprinting/metrics.yaml | 260 -------- .../browser/browser_usercharacteristics.js | 9 +- toolkit/content/license.html | 1 - tools/rewriting/ThirdPartyPaths.txt | 1 - 17 files changed, 56 insertions(+), 1242 deletions(-) delete mode 100644 toolkit/components/resistfingerprinting/content/gl-matrix.LICENSE delete mode 100644 toolkit/components/resistfingerprinting/content/gl-matrix.js delete mode 100644 toolkit/components/resistfingerprinting/content/moz.yaml delete mode 100644 toolkit/components/resistfingerprinting/content/usercharacteristics.css diff --git a/.prettierignore b/.prettierignore index 8f833610ee0f..64998e44c37c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1447,7 +1447,6 @@ toolkit/components/normandy/vendor/ toolkit/components/passwordmgr/PasswordRulesParser.sys.mjs toolkit/components/protobuf/ toolkit/components/reader/readability/ -toolkit/components/resistfingerprinting/content/gl-matrix.js toolkit/components/translation/cld2/ toolkit/components/translations/bergamot-translator/thirdparty toolkit/components/translations/bergamot-translator/bergamot-translator.js diff --git a/docshell/base/nsAboutRedirector.cpp b/docshell/base/nsAboutRedirector.cpp index 7b10bd1b682f..56efb7aed723 100644 --- a/docshell/base/nsAboutRedirector.cpp +++ b/docshell/base/nsAboutRedirector.cpp @@ -108,7 +108,7 @@ static const RedirEntry kRedirMap[] = { {"credits", "https://www.mozilla.org/credits/", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::URI_MUST_LOAD_IN_CHILD}, - {"fingerprintingprotection", + {"fingerprinting", "chrome://global/content/usercharacteristics/usercharacteristics.html", nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::HIDE_FROM_ABOUTABOUT | nsIAboutModule::ALLOW_SCRIPT | diff --git a/docshell/build/components.conf b/docshell/build/components.conf index 4742adc30a7d..bcc6542d673c 100644 --- a/docshell/build/components.conf +++ b/docshell/build/components.conf @@ -16,7 +16,7 @@ about_pages = [ 'crashgpu', 'crashextensions', 'credits', - 'fingerprintingprotection', + 'fingerprinting', 'httpsonlyerror', 'license', 'logging', diff --git a/dom/security/nsContentSecurityUtils.cpp b/dom/security/nsContentSecurityUtils.cpp index d4597c17c16c..7bcbbdd002f1 100644 --- a/dom/security/nsContentSecurityUtils.cpp +++ b/dom/security/nsContentSecurityUtils.cpp @@ -1332,20 +1332,19 @@ void nsContentSecurityUtils::AssertAboutPageHasCSP(Document* aDocument) { // This allowlist contains about: pages that are permanently allowed to // render without a CSP applied. static nsLiteralCString sAllowedAboutPagesWithNoCSP[] = { - // about:blank is a special about page -> no CSP - "about:blank"_ns, - // about:srcdoc is a special about page -> no CSP - "about:srcdoc"_ns, - // about:sync-log displays plain text only -> no CSP - "about:sync-log"_ns, - // about:logo just displays the firefox logo -> no CSP - "about:logo"_ns, - // about:sync is a special mozilla-signed developer addon with low usage - // -> - // no CSP - "about:sync"_ns, + // about:blank is a special about page -> no CSP + "about:blank"_ns, + // about:srcdoc is a special about page -> no CSP + "about:srcdoc"_ns, + // about:sync-log displays plain text only -> no CSP + "about:sync-log"_ns, + // about:logo just displays the firefox logo -> no CSP + "about:logo"_ns, + // about:sync is a special mozilla-signed developer addon with low usage -> + // no CSP + "about:sync"_ns, # if defined(ANDROID) - "about:config"_ns, + "about:config"_ns, # endif }; @@ -1364,20 +1363,20 @@ void nsContentSecurityUtils::AssertAboutPageHasCSP(Document* aDocument) { "about: page must contain a CSP denying object-src"); // preferences and downloads allow legacy inline scripts through hash src. - MOZ_ASSERT( - !foundScriptSrc || StringBeginsWith(aboutSpec, "about:preferences"_ns) || - StringBeginsWith(aboutSpec, "about:settings"_ns) || - StringBeginsWith(aboutSpec, "about:downloads"_ns) || - StringBeginsWith(aboutSpec, "about:fingerprintingprotection"_ns) || - StringBeginsWith(aboutSpec, "about:asrouter"_ns) || - StringBeginsWith(aboutSpec, "about:newtab"_ns) || - StringBeginsWith(aboutSpec, "about:logins"_ns) || - StringBeginsWith(aboutSpec, "about:compat"_ns) || - StringBeginsWith(aboutSpec, "about:welcome"_ns) || - StringBeginsWith(aboutSpec, "about:profiling"_ns) || - StringBeginsWith(aboutSpec, "about:studies"_ns) || - StringBeginsWith(aboutSpec, "about:home"_ns), - "about: page must not contain a CSP including script-src"); + MOZ_ASSERT(!foundScriptSrc || + StringBeginsWith(aboutSpec, "about:preferences"_ns) || + StringBeginsWith(aboutSpec, "about:settings"_ns) || + StringBeginsWith(aboutSpec, "about:downloads"_ns) || + StringBeginsWith(aboutSpec, "about:fingerprinting"_ns) || + StringBeginsWith(aboutSpec, "about:asrouter"_ns) || + StringBeginsWith(aboutSpec, "about:newtab"_ns) || + StringBeginsWith(aboutSpec, "about:logins"_ns) || + StringBeginsWith(aboutSpec, "about:compat"_ns) || + StringBeginsWith(aboutSpec, "about:welcome"_ns) || + StringBeginsWith(aboutSpec, "about:profiling"_ns) || + StringBeginsWith(aboutSpec, "about:studies"_ns) || + StringBeginsWith(aboutSpec, "about:home"_ns), + "about: page must not contain a CSP including script-src"); MOZ_ASSERT(!foundWorkerSrc, "about: page must not contain a CSP including worker-src"); diff --git a/toolkit/components/resistfingerprinting/RFPHelper.sys.mjs b/toolkit/components/resistfingerprinting/RFPHelper.sys.mjs index 3fe83bca0f5e..ddb83124ff4b 100644 --- a/toolkit/components/resistfingerprinting/RFPHelper.sys.mjs +++ b/toolkit/components/resistfingerprinting/RFPHelper.sys.mjs @@ -118,7 +118,7 @@ class _RFPHelper { UserCharacteristicsDataDone: { wantUntrusted: true }, }, }, - matches: ["about:fingerprintingprotection"], + matches: ["about:fingerprinting"], remoteTypes: ["privilegedabout"], }); } @@ -324,11 +324,6 @@ class _RFPHelper { } _registerLetterboxingActor() { - /* - * It turns out that this triggers a warning that we're registering a Desktop-only actor - * in toolkit (which will also run on mobile.) It just happens this actor only handles - * letterboxing, which isn't used on mobile, but we should resolve this. - */ ChromeUtils.registerWindowActor("RFPHelper", { parent: { esModuleURI: "resource:///actors/RFPHelperParent.sys.mjs", diff --git a/toolkit/components/resistfingerprinting/UserCharacteristicsPageService.sys.mjs b/toolkit/components/resistfingerprinting/UserCharacteristicsPageService.sys.mjs index eaf62ff42337..435070b2f1e5 100644 --- a/toolkit/components/resistfingerprinting/UserCharacteristicsPageService.sys.mjs +++ b/toolkit/components/resistfingerprinting/UserCharacteristicsPageService.sys.mjs @@ -169,7 +169,7 @@ export class UserCharacteristicsPageService { }; let userCharacteristicsPageURI = Services.io.newURI( - "about:fingerprintingprotection" + "about:fingerprinting" ); browser.loadURI(userCharacteristicsPageURI, loadURIOptions); @@ -190,39 +190,8 @@ export class UserCharacteristicsPageService { for (let gamepad of data.output.gamepads) { Glean.characteristics.gamepads.add(gamepad); } - Glean.characteristics.zoomCount.set(await this.populateZoomPrefs()); - try { - Glean.characteristics.canvasdata1.set(data.output.canvas1data); - Glean.characteristics.canvasdata2.set(data.output.canvas2data); - Glean.characteristics.canvasdata3.set(data.output.canvas3data); - Glean.characteristics.canvasdata4.set(data.output.canvas4data); - Glean.characteristics.canvasdata5.set(data.output.canvas5data); - Glean.characteristics.canvasdata6.set(data.output.canvas6data); - Glean.characteristics.canvasdata7.set(data.output.canvas7data); - Glean.characteristics.canvasdata8.set(data.output.canvas8data); - Glean.characteristics.canvasdata9.set(data.output.canvas9data); - Glean.characteristics.canvasdata10.set(data.output.canvas10data); - Glean.characteristics.canvasdata11Webgl.set(data.output.glcanvasdata); - Glean.characteristics.canvasdata12Fingerprintjs1.set( - data.output.fingerprintjscanvas1data - ); - Glean.characteristics.canvasdata13Fingerprintjs2.set( - data.output.fingerprintjscanvas2data - ); - - for (let gamepad of data.output.gamepads) { - Glean.characteristics.gamepads.add(gamepad); - } - } catch (e) { - // Grab the exception and send it to the console - // (we don't see it otherwise) - lazy.console.debug(e); - // But still fail - throw e; - } - lazy.console.debug("Unregistering actor"); Services.obs.notifyObservers( null, diff --git a/toolkit/components/resistfingerprinting/content/gl-matrix.LICENSE b/toolkit/components/resistfingerprinting/content/gl-matrix.LICENSE deleted file mode 100644 index 3a96fca424d4..000000000000 --- a/toolkit/components/resistfingerprinting/content/gl-matrix.LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015-2021, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/toolkit/components/resistfingerprinting/content/gl-matrix.js b/toolkit/components/resistfingerprinting/content/gl-matrix.js deleted file mode 100644 index 747b3a77ee91..000000000000 --- a/toolkit/components/resistfingerprinting/content/gl-matrix.js +++ /dev/null @@ -1,28 +0,0 @@ -/*! -@fileoverview gl-matrix - High performance matrix and vector operations -@author Brandon Jones -@author Colin MacKenzie IV -@version 2.7.0 - -Copyright (c) 2015-2018, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ -!function(t,n){if("object"==typeof exports&&"object"==typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define([],n);else{var r=n();for(var a in r)("object"==typeof exports?exports:t)[a]=r[a]}}("undefined"!=typeof self?self:this,function(){return function(t){var n={};function r(a){if(n[a])return n[a].exports;var e=n[a]={i:a,l:!1,exports:{}};return t[a].call(e.exports,e,e.exports,r),e.l=!0,e.exports}return r.m=t,r.c=n,r.d=function(t,n,a){r.o(t,n)||Object.defineProperty(t,n,{enumerable:!0,get:a})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,n){if(1&n&&(t=r(t)),8&n)return t;if(4&n&&"object"==typeof t&&t&&t.__esModule)return t;var a=Object.create(null);if(r.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:t}),2&n&&"string"!=typeof t)for(var e in t)r.d(a,e,function(n){return t[n]}.bind(null,e));return a},r.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(n,"a",n),n},r.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},r.p="",r(r.s=10)}([function(t,n,r){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.setMatrixArrayType=function(t){n.ARRAY_TYPE=t},n.toRadian=function(t){return t*e},n.equals=function(t,n){return Math.abs(t-n)<=a*Math.max(1,Math.abs(t),Math.abs(n))};var a=n.EPSILON=1e-6;n.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,n.RANDOM=Math.random;var e=Math.PI/180},function(t,n,r){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.forEach=n.sqrLen=n.len=n.sqrDist=n.dist=n.div=n.mul=n.sub=void 0,n.create=e,n.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},n.fromValues=function(t,n,r,e){var u=new a.ARRAY_TYPE(4);return u[0]=t,u[1]=n,u[2]=r,u[3]=e,u},n.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},n.set=function(t,n,r,a,e){return t[0]=n,t[1]=r,t[2]=a,t[3]=e,t},n.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t},n.subtract=u,n.multiply=o,n.divide=i,n.ceil=function(t,n){return t[0]=Math.ceil(n[0]),t[1]=Math.ceil(n[1]),t[2]=Math.ceil(n[2]),t[3]=Math.ceil(n[3]),t},n.floor=function(t,n){return t[0]=Math.floor(n[0]),t[1]=Math.floor(n[1]),t[2]=Math.floor(n[2]),t[3]=Math.floor(n[3]),t},n.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t[3]=Math.min(n[3],r[3]),t},n.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t[3]=Math.max(n[3],r[3]),t},n.round=function(t,n){return t[0]=Math.round(n[0]),t[1]=Math.round(n[1]),t[2]=Math.round(n[2]),t[3]=Math.round(n[3]),t},n.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t},n.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t},n.distance=s,n.squaredDistance=c,n.length=f,n.squaredLength=M,n.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=-n[3],t},n.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t[3]=1/n[3],t},n.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u;o>0&&(o=1/Math.sqrt(o),t[0]=r*o,t[1]=a*o,t[2]=e*o,t[3]=u*o);return t},n.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]+t[3]*n[3]},n.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t[3]=i+a*(r[3]-i),t},n.random=function(t,n){var r,e,u,o,i,s;n=n||1;do{r=2*a.RANDOM()-1,e=2*a.RANDOM()-1,i=r*r+e*e}while(i>=1);do{u=2*a.RANDOM()-1,o=2*a.RANDOM()-1,s=u*u+o*o}while(s>=1);var c=Math.sqrt((1-i)/s);return t[0]=n*r,t[1]=n*e,t[2]=n*u*c,t[3]=n*o*c,t},n.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3];return t[0]=r[0]*a+r[4]*e+r[8]*u+r[12]*o,t[1]=r[1]*a+r[5]*e+r[9]*u+r[13]*o,t[2]=r[2]*a+r[6]*e+r[10]*u+r[14]*o,t[3]=r[3]*a+r[7]*e+r[11]*u+r[15]*o,t},n.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],s=r[2],c=r[3],f=c*a+i*u-s*e,M=c*e+s*a-o*u,h=c*u+o*e-i*a,l=-o*a-i*e-s*u;return t[0]=f*c+l*-o+M*-s-h*-i,t[1]=M*c+l*-i+h*-o-f*-s,t[2]=h*c+l*-s+f*-i-M*-o,t[3]=n[3],t},n.str=function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},n.exactEquals=function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]},n.equals=function(t,n){var r=t[0],e=t[1],u=t[2],o=t[3],i=n[0],s=n[1],c=n[2],f=n[3];return Math.abs(r-i)<=a.EPSILON*Math.max(1,Math.abs(r),Math.abs(i))&&Math.abs(e-s)<=a.EPSILON*Math.max(1,Math.abs(e),Math.abs(s))&&Math.abs(u-c)<=a.EPSILON*Math.max(1,Math.abs(u),Math.abs(c))&&Math.abs(o-f)<=a.EPSILON*Math.max(1,Math.abs(o),Math.abs(f))};var a=function(t){if(t&&t.__esModule)return t;var n={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.default=t,n}(r(0));function e(){var t=new a.ARRAY_TYPE(4);return a.ARRAY_TYPE!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0,t[3]=0),t}function u(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t}function o(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t[3]=n[3]*r[3],t}function i(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t[3]=n[3]/r[3],t}function s(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return Math.sqrt(r*r+a*a+e*e+u*u)}function c(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return r*r+a*a+e*e+u*u}function f(t){var n=t[0],r=t[1],a=t[2],e=t[3];return Math.sqrt(n*n+r*r+a*a+e*e)}function M(t){var n=t[0],r=t[1],a=t[2],e=t[3];return n*n+r*r+a*a+e*e}n.sub=u,n.mul=o,n.div=i,n.dist=s,n.sqrDist=c,n.len=f,n.sqrLen=M,n.forEach=function(){var t=e();return function(n,r,a,e,u,o){var i=void 0,s=void 0;for(r||(r=4),a||(a=0),s=e?Math.min(e*r+a,n.length):n.length,i=a;i1?0:e<-1?Math.PI:Math.acos(e)},n.str=function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},n.exactEquals=function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]},n.equals=function(t,n){var r=t[0],e=t[1],u=t[2],o=n[0],i=n[1],s=n[2];return Math.abs(r-o)<=a.EPSILON*Math.max(1,Math.abs(r),Math.abs(o))&&Math.abs(e-i)<=a.EPSILON*Math.max(1,Math.abs(e),Math.abs(i))&&Math.abs(u-s)<=a.EPSILON*Math.max(1,Math.abs(u),Math.abs(s))};var a=function(t){if(t&&t.__esModule)return t;var n={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.default=t,n}(r(0));function e(){var t=new a.ARRAY_TYPE(3);return a.ARRAY_TYPE!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t}function u(t){var n=t[0],r=t[1],a=t[2];return Math.sqrt(n*n+r*r+a*a)}function o(t,n,r){var e=new a.ARRAY_TYPE(3);return e[0]=t,e[1]=n,e[2]=r,e}function i(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t}function s(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t}function c(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t}function f(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return Math.sqrt(r*r+a*a+e*e)}function M(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return r*r+a*a+e*e}function h(t){var n=t[0],r=t[1],a=t[2];return n*n+r*r+a*a}function l(t,n){var r=n[0],a=n[1],e=n[2],u=r*r+a*a+e*e;return u>0&&(u=1/Math.sqrt(u),t[0]=n[0]*u,t[1]=n[1]*u,t[2]=n[2]*u),t}function v(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]}n.sub=i,n.mul=s,n.div=c,n.dist=f,n.sqrDist=M,n.len=u,n.sqrLen=h,n.forEach=function(){var t=e();return function(n,r,a,e,u,o){var i=void 0,s=void 0;for(r||(r=3),a||(a=0),s=e?Math.min(e*r+a,n.length):n.length,i=a;ia.EPSILON?(t[0]=n[0]/e,t[1]=n[1]/e,t[2]=n[2]/e):(t[0]=1,t[1]=0,t[2]=0);return r},n.multiply=f,n.rotateX=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),s=Math.cos(r);return t[0]=a*s+o*i,t[1]=e*s+u*i,t[2]=u*s-e*i,t[3]=o*s-a*i,t},n.rotateY=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),s=Math.cos(r);return t[0]=a*s-u*i,t[1]=e*s+o*i,t[2]=u*s+a*i,t[3]=o*s-e*i,t},n.rotateZ=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),s=Math.cos(r);return t[0]=a*s+e*i,t[1]=e*s-a*i,t[2]=u*s+o*i,t[3]=o*s-u*i,t},n.calculateW=function(t,n){var r=n[0],a=n[1],e=n[2];return t[0]=r,t[1]=a,t[2]=e,t[3]=Math.sqrt(Math.abs(1-r*r-a*a-e*e)),t},n.slerp=M,n.random=function(t){var n=a.RANDOM(),r=a.RANDOM(),e=a.RANDOM(),u=Math.sqrt(1-n),o=Math.sqrt(n);return t[0]=u*Math.sin(2*Math.PI*r),t[1]=u*Math.cos(2*Math.PI*r),t[2]=o*Math.sin(2*Math.PI*e),t[3]=o*Math.cos(2*Math.PI*e),t},n.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u,i=o?1/o:0;return t[0]=-r*i,t[1]=-a*i,t[2]=-e*i,t[3]=u*i,t},n.conjugate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=n[3],t},n.fromMat3=h,n.fromEuler=function(t,n,r,a){var e=.5*Math.PI/180;n*=e,r*=e,a*=e;var u=Math.sin(n),o=Math.cos(n),i=Math.sin(r),s=Math.cos(r),c=Math.sin(a),f=Math.cos(a);return t[0]=u*s*f-o*i*c,t[1]=o*i*f+u*s*c,t[2]=o*s*c-u*i*f,t[3]=o*s*f+u*i*c,t},n.str=function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"};var a=i(r(0)),e=i(r(5)),u=i(r(2)),o=i(r(1));function i(t){if(t&&t.__esModule)return t;var n={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.default=t,n}function s(){var t=new a.ARRAY_TYPE(4);return a.ARRAY_TYPE!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t[3]=1,t}function c(t,n,r){r*=.5;var a=Math.sin(r);return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=Math.cos(r),t}function f(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],s=r[1],c=r[2],f=r[3];return t[0]=a*f+o*i+e*c-u*s,t[1]=e*f+o*s+u*i-a*c,t[2]=u*f+o*c+a*s-e*i,t[3]=o*f-a*i-e*s-u*c,t}function M(t,n,r,e){var u=n[0],o=n[1],i=n[2],s=n[3],c=r[0],f=r[1],M=r[2],h=r[3],l=void 0,v=void 0,d=void 0,b=void 0,m=void 0;return(v=u*c+o*f+i*M+s*h)<0&&(v=-v,c=-c,f=-f,M=-M,h=-h),1-v>a.EPSILON?(l=Math.acos(v),d=Math.sin(l),b=Math.sin((1-e)*l)/d,m=Math.sin(e*l)/d):(b=1-e,m=e),t[0]=b*u+m*c,t[1]=b*o+m*f,t[2]=b*i+m*M,t[3]=b*s+m*h,t}function h(t,n){var r=n[0]+n[4]+n[8],a=void 0;if(r>0)a=Math.sqrt(r+1),t[3]=.5*a,a=.5/a,t[0]=(n[5]-n[7])*a,t[1]=(n[6]-n[2])*a,t[2]=(n[1]-n[3])*a;else{var e=0;n[4]>n[0]&&(e=1),n[8]>n[3*e+e]&&(e=2);var u=(e+1)%3,o=(e+2)%3;a=Math.sqrt(n[3*e+e]-n[3*u+u]-n[3*o+o]+1),t[e]=.5*a,a=.5/a,t[3]=(n[3*u+o]-n[3*o+u])*a,t[u]=(n[3*u+e]+n[3*e+u])*a,t[o]=(n[3*o+e]+n[3*e+o])*a}return t}n.clone=o.clone,n.fromValues=o.fromValues,n.copy=o.copy,n.set=o.set,n.add=o.add,n.mul=f,n.scale=o.scale,n.dot=o.dot,n.lerp=o.lerp;var l=n.length=o.length,v=(n.len=l,n.squaredLength=o.squaredLength),d=(n.sqrLen=v,n.normalize=o.normalize);n.exactEquals=o.exactEquals,n.equals=o.equals,n.rotationTo=function(){var t=u.create(),n=u.fromValues(1,0,0),r=u.fromValues(0,1,0);return function(a,e,o){var i=u.dot(e,o);return i<-.999999?(u.cross(t,n,e),u.len(t)<1e-6&&u.cross(t,r,e),u.normalize(t,t),c(a,t,Math.PI),a):i>.999999?(a[0]=0,a[1]=0,a[2]=0,a[3]=1,a):(u.cross(t,e,o),a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=1+i,d(a,a))}}(),n.sqlerp=function(){var t=s(),n=s();return function(r,a,e,u,o,i){return M(t,a,o,i),M(n,e,u,i),M(r,t,n,2*i*(1-i)),r}}(),n.setAxes=function(){var t=e.create();return function(n,r,a,e){return t[0]=a[0],t[3]=a[1],t[6]=a[2],t[1]=e[0],t[4]=e[1],t[7]=e[2],t[2]=-r[0],t[5]=-r[1],t[8]=-r[2],d(n,h(n,t))}}()},function(t,n,r){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.sub=n.mul=void 0,n.create=function(){var t=new a.ARRAY_TYPE(16);a.ARRAY_TYPE!=Float32Array&&(t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=0,t[12]=0,t[13]=0,t[14]=0);return t[0]=1,t[5]=1,t[10]=1,t[15]=1,t},n.clone=function(t){var n=new a.ARRAY_TYPE(16);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},n.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},n.fromValues=function(t,n,r,e,u,o,i,s,c,f,M,h,l,v,d,b){var m=new a.ARRAY_TYPE(16);return m[0]=t,m[1]=n,m[2]=r,m[3]=e,m[4]=u,m[5]=o,m[6]=i,m[7]=s,m[8]=c,m[9]=f,m[10]=M,m[11]=h,m[12]=l,m[13]=v,m[14]=d,m[15]=b,m},n.set=function(t,n,r,a,e,u,o,i,s,c,f,M,h,l,v,d,b){return t[0]=n,t[1]=r,t[2]=a,t[3]=e,t[4]=u,t[5]=o,t[6]=i,t[7]=s,t[8]=c,t[9]=f,t[10]=M,t[11]=h,t[12]=l,t[13]=v,t[14]=d,t[15]=b,t},n.identity=e,n.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[3],u=n[6],o=n[7],i=n[11];t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=r,t[6]=n[9],t[7]=n[13],t[8]=a,t[9]=u,t[11]=n[14],t[12]=e,t[13]=o,t[14]=i}else t[0]=n[0],t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=n[1],t[5]=n[5],t[6]=n[9],t[7]=n[13],t[8]=n[2],t[9]=n[6],t[10]=n[10],t[11]=n[14],t[12]=n[3],t[13]=n[7],t[14]=n[11],t[15]=n[15];return t},n.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],s=n[6],c=n[7],f=n[8],M=n[9],h=n[10],l=n[11],v=n[12],d=n[13],b=n[14],m=n[15],p=r*i-a*o,P=r*s-e*o,A=r*c-u*o,E=a*s-e*i,O=a*c-u*i,R=e*c-u*s,y=f*d-M*v,q=f*b-h*v,x=f*m-l*v,_=M*b-h*d,Y=M*m-l*d,L=h*m-l*b,S=p*L-P*Y+A*_+E*x-O*q+R*y;if(!S)return null;return S=1/S,t[0]=(i*L-s*Y+c*_)*S,t[1]=(e*Y-a*L-u*_)*S,t[2]=(d*R-b*O+m*E)*S,t[3]=(h*O-M*R-l*E)*S,t[4]=(s*x-o*L-c*q)*S,t[5]=(r*L-e*x+u*q)*S,t[6]=(b*A-v*R-m*P)*S,t[7]=(f*R-h*A+l*P)*S,t[8]=(o*Y-i*x+c*y)*S,t[9]=(a*x-r*Y-u*y)*S,t[10]=(v*O-d*A+m*p)*S,t[11]=(M*A-f*O-l*p)*S,t[12]=(i*q-o*_-s*y)*S,t[13]=(r*_-a*q+e*y)*S,t[14]=(d*P-v*E-b*p)*S,t[15]=(f*E-M*P+h*p)*S,t},n.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],s=n[6],c=n[7],f=n[8],M=n[9],h=n[10],l=n[11],v=n[12],d=n[13],b=n[14],m=n[15];return t[0]=i*(h*m-l*b)-M*(s*m-c*b)+d*(s*l-c*h),t[1]=-(a*(h*m-l*b)-M*(e*m-u*b)+d*(e*l-u*h)),t[2]=a*(s*m-c*b)-i*(e*m-u*b)+d*(e*c-u*s),t[3]=-(a*(s*l-c*h)-i*(e*l-u*h)+M*(e*c-u*s)),t[4]=-(o*(h*m-l*b)-f*(s*m-c*b)+v*(s*l-c*h)),t[5]=r*(h*m-l*b)-f*(e*m-u*b)+v*(e*l-u*h),t[6]=-(r*(s*m-c*b)-o*(e*m-u*b)+v*(e*c-u*s)),t[7]=r*(s*l-c*h)-o*(e*l-u*h)+f*(e*c-u*s),t[8]=o*(M*m-l*d)-f*(i*m-c*d)+v*(i*l-c*M),t[9]=-(r*(M*m-l*d)-f*(a*m-u*d)+v*(a*l-u*M)),t[10]=r*(i*m-c*d)-o*(a*m-u*d)+v*(a*c-u*i),t[11]=-(r*(i*l-c*M)-o*(a*l-u*M)+f*(a*c-u*i)),t[12]=-(o*(M*b-h*d)-f*(i*b-s*d)+v*(i*h-s*M)),t[13]=r*(M*b-h*d)-f*(a*b-e*d)+v*(a*h-e*M),t[14]=-(r*(i*b-s*d)-o*(a*b-e*d)+v*(a*s-e*i)),t[15]=r*(i*h-s*M)-o*(a*h-e*M)+f*(a*s-e*i),t},n.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],s=t[7],c=t[8],f=t[9],M=t[10],h=t[11],l=t[12],v=t[13],d=t[14],b=t[15];return(n*o-r*u)*(M*b-h*d)-(n*i-a*u)*(f*b-h*v)+(n*s-e*u)*(f*d-M*v)+(r*i-a*o)*(c*b-h*l)-(r*s-e*o)*(c*d-M*l)+(a*s-e*i)*(c*v-f*l)},n.multiply=u,n.translate=function(t,n,r){var a=r[0],e=r[1],u=r[2],o=void 0,i=void 0,s=void 0,c=void 0,f=void 0,M=void 0,h=void 0,l=void 0,v=void 0,d=void 0,b=void 0,m=void 0;n===t?(t[12]=n[0]*a+n[4]*e+n[8]*u+n[12],t[13]=n[1]*a+n[5]*e+n[9]*u+n[13],t[14]=n[2]*a+n[6]*e+n[10]*u+n[14],t[15]=n[3]*a+n[7]*e+n[11]*u+n[15]):(o=n[0],i=n[1],s=n[2],c=n[3],f=n[4],M=n[5],h=n[6],l=n[7],v=n[8],d=n[9],b=n[10],m=n[11],t[0]=o,t[1]=i,t[2]=s,t[3]=c,t[4]=f,t[5]=M,t[6]=h,t[7]=l,t[8]=v,t[9]=d,t[10]=b,t[11]=m,t[12]=o*a+f*e+v*u+n[12],t[13]=i*a+M*e+d*u+n[13],t[14]=s*a+h*e+b*u+n[14],t[15]=c*a+l*e+m*u+n[15]);return t},n.scale=function(t,n,r){var a=r[0],e=r[1],u=r[2];return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*e,t[5]=n[5]*e,t[6]=n[6]*e,t[7]=n[7]*e,t[8]=n[8]*u,t[9]=n[9]*u,t[10]=n[10]*u,t[11]=n[11]*u,t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},n.rotate=function(t,n,r,e){var u=e[0],o=e[1],i=e[2],s=Math.sqrt(u*u+o*o+i*i),c=void 0,f=void 0,M=void 0,h=void 0,l=void 0,v=void 0,d=void 0,b=void 0,m=void 0,p=void 0,P=void 0,A=void 0,E=void 0,O=void 0,R=void 0,y=void 0,q=void 0,x=void 0,_=void 0,Y=void 0,L=void 0,S=void 0,w=void 0,I=void 0;if(s0?(r[0]=2*(c*s+h*e+f*i-M*u)/l,r[1]=2*(f*s+h*u+M*e-c*i)/l,r[2]=2*(M*s+h*i+c*u-f*e)/l):(r[0]=2*(c*s+h*e+f*i-M*u),r[1]=2*(f*s+h*u+M*e-c*i),r[2]=2*(M*s+h*i+c*u-f*e));return o(t,n,r),t},n.getTranslation=function(t,n){return t[0]=n[12],t[1]=n[13],t[2]=n[14],t},n.getScaling=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[4],o=n[5],i=n[6],s=n[8],c=n[9],f=n[10];return t[0]=Math.sqrt(r*r+a*a+e*e),t[1]=Math.sqrt(u*u+o*o+i*i),t[2]=Math.sqrt(s*s+c*c+f*f),t},n.getRotation=function(t,n){var r=n[0]+n[5]+n[10],a=0;r>0?(a=2*Math.sqrt(r+1),t[3]=.25*a,t[0]=(n[6]-n[9])/a,t[1]=(n[8]-n[2])/a,t[2]=(n[1]-n[4])/a):n[0]>n[5]&&n[0]>n[10]?(a=2*Math.sqrt(1+n[0]-n[5]-n[10]),t[3]=(n[6]-n[9])/a,t[0]=.25*a,t[1]=(n[1]+n[4])/a,t[2]=(n[8]+n[2])/a):n[5]>n[10]?(a=2*Math.sqrt(1+n[5]-n[0]-n[10]),t[3]=(n[8]-n[2])/a,t[0]=(n[1]+n[4])/a,t[1]=.25*a,t[2]=(n[6]+n[9])/a):(a=2*Math.sqrt(1+n[10]-n[0]-n[5]),t[3]=(n[1]-n[4])/a,t[0]=(n[8]+n[2])/a,t[1]=(n[6]+n[9])/a,t[2]=.25*a);return t},n.fromRotationTranslationScale=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3],s=e+e,c=u+u,f=o+o,M=e*s,h=e*c,l=e*f,v=u*c,d=u*f,b=o*f,m=i*s,p=i*c,P=i*f,A=a[0],E=a[1],O=a[2];return t[0]=(1-(v+b))*A,t[1]=(h+P)*A,t[2]=(l-p)*A,t[3]=0,t[4]=(h-P)*E,t[5]=(1-(M+b))*E,t[6]=(d+m)*E,t[7]=0,t[8]=(l+p)*O,t[9]=(d-m)*O,t[10]=(1-(M+v))*O,t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},n.fromRotationTranslationScaleOrigin=function(t,n,r,a,e){var u=n[0],o=n[1],i=n[2],s=n[3],c=u+u,f=o+o,M=i+i,h=u*c,l=u*f,v=u*M,d=o*f,b=o*M,m=i*M,p=s*c,P=s*f,A=s*M,E=a[0],O=a[1],R=a[2],y=e[0],q=e[1],x=e[2],_=(1-(d+m))*E,Y=(l+A)*E,L=(v-P)*E,S=(l-A)*O,w=(1-(h+m))*O,I=(b+p)*O,N=(v+P)*R,g=(b-p)*R,T=(1-(h+d))*R;return t[0]=_,t[1]=Y,t[2]=L,t[3]=0,t[4]=S,t[5]=w,t[6]=I,t[7]=0,t[8]=N,t[9]=g,t[10]=T,t[11]=0,t[12]=r[0]+y-(_*y+S*q+N*x),t[13]=r[1]+q-(Y*y+w*q+g*x),t[14]=r[2]+x-(L*y+I*q+T*x),t[15]=1,t},n.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,s=e+e,c=r*o,f=a*o,M=a*i,h=e*o,l=e*i,v=e*s,d=u*o,b=u*i,m=u*s;return t[0]=1-M-v,t[1]=f+m,t[2]=h-b,t[3]=0,t[4]=f-m,t[5]=1-c-v,t[6]=l+d,t[7]=0,t[8]=h+b,t[9]=l-d,t[10]=1-c-M,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},n.frustum=function(t,n,r,a,e,u,o){var i=1/(r-n),s=1/(e-a),c=1/(u-o);return t[0]=2*u*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*u*s,t[6]=0,t[7]=0,t[8]=(r+n)*i,t[9]=(e+a)*s,t[10]=(o+u)*c,t[11]=-1,t[12]=0,t[13]=0,t[14]=o*u*2*c,t[15]=0,t},n.perspective=function(t,n,r,a,e){var u=1/Math.tan(n/2),o=void 0;t[0]=u/r,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=u,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=-1,t[12]=0,t[13]=0,t[15]=0,null!=e&&e!==1/0?(o=1/(a-e),t[10]=(e+a)*o,t[14]=2*e*a*o):(t[10]=-1,t[14]=-2*a);return t},n.perspectiveFromFieldOfView=function(t,n,r,a){var e=Math.tan(n.upDegrees*Math.PI/180),u=Math.tan(n.downDegrees*Math.PI/180),o=Math.tan(n.leftDegrees*Math.PI/180),i=Math.tan(n.rightDegrees*Math.PI/180),s=2/(o+i),c=2/(e+u);return t[0]=s,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=c,t[6]=0,t[7]=0,t[8]=-(o-i)*s*.5,t[9]=(e-u)*c*.5,t[10]=a/(r-a),t[11]=-1,t[12]=0,t[13]=0,t[14]=a*r/(r-a),t[15]=0,t},n.ortho=function(t,n,r,a,e,u,o){var i=1/(n-r),s=1/(a-e),c=1/(u-o);return t[0]=-2*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*s,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*c,t[11]=0,t[12]=(n+r)*i,t[13]=(e+a)*s,t[14]=(o+u)*c,t[15]=1,t},n.lookAt=function(t,n,r,u){var o=void 0,i=void 0,s=void 0,c=void 0,f=void 0,M=void 0,h=void 0,l=void 0,v=void 0,d=void 0,b=n[0],m=n[1],p=n[2],P=u[0],A=u[1],E=u[2],O=r[0],R=r[1],y=r[2];if(Math.abs(b-O)0&&(l=1/Math.sqrt(l),f*=l,M*=l,h*=l);var v=s*h-c*M,d=c*f-i*h,b=i*M-s*f;(l=v*v+d*d+b*b)>0&&(l=1/Math.sqrt(l),v*=l,d*=l,b*=l);return t[0]=v,t[1]=d,t[2]=b,t[3]=0,t[4]=M*b-h*d,t[5]=h*v-f*b,t[6]=f*d-M*v,t[7]=0,t[8]=f,t[9]=M,t[10]=h,t[11]=0,t[12]=e,t[13]=u,t[14]=o,t[15]=1,t},n.str=function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},n.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2)+Math.pow(t[9],2)+Math.pow(t[10],2)+Math.pow(t[11],2)+Math.pow(t[12],2)+Math.pow(t[13],2)+Math.pow(t[14],2)+Math.pow(t[15],2))},n.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t[4]=n[4]+r[4],t[5]=n[5]+r[5],t[6]=n[6]+r[6],t[7]=n[7]+r[7],t[8]=n[8]+r[8],t[9]=n[9]+r[9],t[10]=n[10]+r[10],t[11]=n[11]+r[11],t[12]=n[12]+r[12],t[13]=n[13]+r[13],t[14]=n[14]+r[14],t[15]=n[15]+r[15],t},n.subtract=i,n.multiplyScalar=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t[4]=n[4]*r,t[5]=n[5]*r,t[6]=n[6]*r,t[7]=n[7]*r,t[8]=n[8]*r,t[9]=n[9]*r,t[10]=n[10]*r,t[11]=n[11]*r,t[12]=n[12]*r,t[13]=n[13]*r,t[14]=n[14]*r,t[15]=n[15]*r,t},n.multiplyScalarAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t[4]=n[4]+r[4]*a,t[5]=n[5]+r[5]*a,t[6]=n[6]+r[6]*a,t[7]=n[7]+r[7]*a,t[8]=n[8]+r[8]*a,t[9]=n[9]+r[9]*a,t[10]=n[10]+r[10]*a,t[11]=n[11]+r[11]*a,t[12]=n[12]+r[12]*a,t[13]=n[13]+r[13]*a,t[14]=n[14]+r[14]*a,t[15]=n[15]+r[15]*a,t},n.exactEquals=function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]&&t[4]===n[4]&&t[5]===n[5]&&t[6]===n[6]&&t[7]===n[7]&&t[8]===n[8]&&t[9]===n[9]&&t[10]===n[10]&&t[11]===n[11]&&t[12]===n[12]&&t[13]===n[13]&&t[14]===n[14]&&t[15]===n[15]},n.equals=function(t,n){var r=t[0],e=t[1],u=t[2],o=t[3],i=t[4],s=t[5],c=t[6],f=t[7],M=t[8],h=t[9],l=t[10],v=t[11],d=t[12],b=t[13],m=t[14],p=t[15],P=n[0],A=n[1],E=n[2],O=n[3],R=n[4],y=n[5],q=n[6],x=n[7],_=n[8],Y=n[9],L=n[10],S=n[11],w=n[12],I=n[13],N=n[14],g=n[15];return Math.abs(r-P)<=a.EPSILON*Math.max(1,Math.abs(r),Math.abs(P))&&Math.abs(e-A)<=a.EPSILON*Math.max(1,Math.abs(e),Math.abs(A))&&Math.abs(u-E)<=a.EPSILON*Math.max(1,Math.abs(u),Math.abs(E))&&Math.abs(o-O)<=a.EPSILON*Math.max(1,Math.abs(o),Math.abs(O))&&Math.abs(i-R)<=a.EPSILON*Math.max(1,Math.abs(i),Math.abs(R))&&Math.abs(s-y)<=a.EPSILON*Math.max(1,Math.abs(s),Math.abs(y))&&Math.abs(c-q)<=a.EPSILON*Math.max(1,Math.abs(c),Math.abs(q))&&Math.abs(f-x)<=a.EPSILON*Math.max(1,Math.abs(f),Math.abs(x))&&Math.abs(M-_)<=a.EPSILON*Math.max(1,Math.abs(M),Math.abs(_))&&Math.abs(h-Y)<=a.EPSILON*Math.max(1,Math.abs(h),Math.abs(Y))&&Math.abs(l-L)<=a.EPSILON*Math.max(1,Math.abs(l),Math.abs(L))&&Math.abs(v-S)<=a.EPSILON*Math.max(1,Math.abs(v),Math.abs(S))&&Math.abs(d-w)<=a.EPSILON*Math.max(1,Math.abs(d),Math.abs(w))&&Math.abs(b-I)<=a.EPSILON*Math.max(1,Math.abs(b),Math.abs(I))&&Math.abs(m-N)<=a.EPSILON*Math.max(1,Math.abs(m),Math.abs(N))&&Math.abs(p-g)<=a.EPSILON*Math.max(1,Math.abs(p),Math.abs(g))};var a=function(t){if(t&&t.__esModule)return t;var n={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.default=t,n}(r(0));function e(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t}function u(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],s=n[5],c=n[6],f=n[7],M=n[8],h=n[9],l=n[10],v=n[11],d=n[12],b=n[13],m=n[14],p=n[15],P=r[0],A=r[1],E=r[2],O=r[3];return t[0]=P*a+A*i+E*M+O*d,t[1]=P*e+A*s+E*h+O*b,t[2]=P*u+A*c+E*l+O*m,t[3]=P*o+A*f+E*v+O*p,P=r[4],A=r[5],E=r[6],O=r[7],t[4]=P*a+A*i+E*M+O*d,t[5]=P*e+A*s+E*h+O*b,t[6]=P*u+A*c+E*l+O*m,t[7]=P*o+A*f+E*v+O*p,P=r[8],A=r[9],E=r[10],O=r[11],t[8]=P*a+A*i+E*M+O*d,t[9]=P*e+A*s+E*h+O*b,t[10]=P*u+A*c+E*l+O*m,t[11]=P*o+A*f+E*v+O*p,P=r[12],A=r[13],E=r[14],O=r[15],t[12]=P*a+A*i+E*M+O*d,t[13]=P*e+A*s+E*h+O*b,t[14]=P*u+A*c+E*l+O*m,t[15]=P*o+A*f+E*v+O*p,t}function o(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=a+a,s=e+e,c=u+u,f=a*i,M=a*s,h=a*c,l=e*s,v=e*c,d=u*c,b=o*i,m=o*s,p=o*c;return t[0]=1-(l+d),t[1]=M+p,t[2]=h-m,t[3]=0,t[4]=M-p,t[5]=1-(f+d),t[6]=v+b,t[7]=0,t[8]=h+m,t[9]=v-b,t[10]=1-(f+l),t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t}function i(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t[4]=n[4]-r[4],t[5]=n[5]-r[5],t[6]=n[6]-r[6],t[7]=n[7]-r[7],t[8]=n[8]-r[8],t[9]=n[9]-r[9],t[10]=n[10]-r[10],t[11]=n[11]-r[11],t[12]=n[12]-r[12],t[13]=n[13]-r[13],t[14]=n[14]-r[14],t[15]=n[15]-r[15],t}n.mul=u,n.sub=i},function(t,n,r){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.sub=n.mul=void 0,n.create=function(){var t=new a.ARRAY_TYPE(9);a.ARRAY_TYPE!=Float32Array&&(t[1]=0,t[2]=0,t[3]=0,t[5]=0,t[6]=0,t[7]=0);return t[0]=1,t[4]=1,t[8]=1,t},n.fromMat4=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[4],t[4]=n[5],t[5]=n[6],t[6]=n[8],t[7]=n[9],t[8]=n[10],t},n.clone=function(t){var n=new a.ARRAY_TYPE(9);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n},n.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},n.fromValues=function(t,n,r,e,u,o,i,s,c){var f=new a.ARRAY_TYPE(9);return f[0]=t,f[1]=n,f[2]=r,f[3]=e,f[4]=u,f[5]=o,f[6]=i,f[7]=s,f[8]=c,f},n.set=function(t,n,r,a,e,u,o,i,s,c){return t[0]=n,t[1]=r,t[2]=a,t[3]=e,t[4]=u,t[5]=o,t[6]=i,t[7]=s,t[8]=c,t},n.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},n.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[5];t[1]=n[3],t[2]=n[6],t[3]=r,t[5]=n[7],t[6]=a,t[7]=e}else t[0]=n[0],t[1]=n[3],t[2]=n[6],t[3]=n[1],t[4]=n[4],t[5]=n[7],t[6]=n[2],t[7]=n[5],t[8]=n[8];return t},n.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],s=n[6],c=n[7],f=n[8],M=f*o-i*c,h=-f*u+i*s,l=c*u-o*s,v=r*M+a*h+e*l;if(!v)return null;return v=1/v,t[0]=M*v,t[1]=(-f*a+e*c)*v,t[2]=(i*a-e*o)*v,t[3]=h*v,t[4]=(f*r-e*s)*v,t[5]=(-i*r+e*u)*v,t[6]=l*v,t[7]=(-c*r+a*s)*v,t[8]=(o*r-a*u)*v,t},n.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],s=n[6],c=n[7],f=n[8];return t[0]=o*f-i*c,t[1]=e*c-a*f,t[2]=a*i-e*o,t[3]=i*s-u*f,t[4]=r*f-e*s,t[5]=e*u-r*i,t[6]=u*c-o*s,t[7]=a*s-r*c,t[8]=r*o-a*u,t},n.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],s=t[7],c=t[8];return n*(c*u-o*s)+r*(-c*e+o*i)+a*(s*e-u*i)},n.multiply=e,n.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],s=n[5],c=n[6],f=n[7],M=n[8],h=r[0],l=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=s,t[6]=h*a+l*o+c,t[7]=h*e+l*i+f,t[8]=h*u+l*s+M,t},n.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],s=n[5],c=n[6],f=n[7],M=n[8],h=Math.sin(r),l=Math.cos(r);return t[0]=l*a+h*o,t[1]=l*e+h*i,t[2]=l*u+h*s,t[3]=l*o-h*a,t[4]=l*i-h*e,t[5]=l*s-h*u,t[6]=c,t[7]=f,t[8]=M,t},n.scale=function(t,n,r){var a=r[0],e=r[1];return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=e*n[3],t[4]=e*n[4],t[5]=e*n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},n.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=n[0],t[7]=n[1],t[8]=1,t},n.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=-r,t[4]=a,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},n.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=n[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},n.fromMat2d=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=0,t[3]=n[2],t[4]=n[3],t[5]=0,t[6]=n[4],t[7]=n[5],t[8]=1,t},n.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,s=e+e,c=r*o,f=a*o,M=a*i,h=e*o,l=e*i,v=e*s,d=u*o,b=u*i,m=u*s;return t[0]=1-M-v,t[3]=f-m,t[6]=h+b,t[1]=f+m,t[4]=1-c-v,t[7]=l-d,t[2]=h-b,t[5]=l+d,t[8]=1-c-M,t},n.normalFromMat4=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],s=n[6],c=n[7],f=n[8],M=n[9],h=n[10],l=n[11],v=n[12],d=n[13],b=n[14],m=n[15],p=r*i-a*o,P=r*s-e*o,A=r*c-u*o,E=a*s-e*i,O=a*c-u*i,R=e*c-u*s,y=f*d-M*v,q=f*b-h*v,x=f*m-l*v,_=M*b-h*d,Y=M*m-l*d,L=h*m-l*b,S=p*L-P*Y+A*_+E*x-O*q+R*y;if(!S)return null;return S=1/S,t[0]=(i*L-s*Y+c*_)*S,t[1]=(s*x-o*L-c*q)*S,t[2]=(o*Y-i*x+c*y)*S,t[3]=(e*Y-a*L-u*_)*S,t[4]=(r*L-e*x+u*q)*S,t[5]=(a*x-r*Y-u*y)*S,t[6]=(d*R-b*O+m*E)*S,t[7]=(b*A-v*R-m*P)*S,t[8]=(v*O-d*A+m*p)*S,t},n.projection=function(t,n,r){return t[0]=2/n,t[1]=0,t[2]=0,t[3]=0,t[4]=-2/r,t[5]=0,t[6]=-1,t[7]=1,t[8]=1,t},n.str=function(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"},n.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2))},n.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t[4]=n[4]+r[4],t[5]=n[5]+r[5],t[6]=n[6]+r[6],t[7]=n[7]+r[7],t[8]=n[8]+r[8],t},n.subtract=u,n.multiplyScalar=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t[4]=n[4]*r,t[5]=n[5]*r,t[6]=n[6]*r,t[7]=n[7]*r,t[8]=n[8]*r,t},n.multiplyScalarAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t[4]=n[4]+r[4]*a,t[5]=n[5]+r[5]*a,t[6]=n[6]+r[6]*a,t[7]=n[7]+r[7]*a,t[8]=n[8]+r[8]*a,t},n.exactEquals=function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]&&t[4]===n[4]&&t[5]===n[5]&&t[6]===n[6]&&t[7]===n[7]&&t[8]===n[8]},n.equals=function(t,n){var r=t[0],e=t[1],u=t[2],o=t[3],i=t[4],s=t[5],c=t[6],f=t[7],M=t[8],h=n[0],l=n[1],v=n[2],d=n[3],b=n[4],m=n[5],p=n[6],P=n[7],A=n[8];return Math.abs(r-h)<=a.EPSILON*Math.max(1,Math.abs(r),Math.abs(h))&&Math.abs(e-l)<=a.EPSILON*Math.max(1,Math.abs(e),Math.abs(l))&&Math.abs(u-v)<=a.EPSILON*Math.max(1,Math.abs(u),Math.abs(v))&&Math.abs(o-d)<=a.EPSILON*Math.max(1,Math.abs(o),Math.abs(d))&&Math.abs(i-b)<=a.EPSILON*Math.max(1,Math.abs(i),Math.abs(b))&&Math.abs(s-m)<=a.EPSILON*Math.max(1,Math.abs(s),Math.abs(m))&&Math.abs(c-p)<=a.EPSILON*Math.max(1,Math.abs(c),Math.abs(p))&&Math.abs(f-P)<=a.EPSILON*Math.max(1,Math.abs(f),Math.abs(P))&&Math.abs(M-A)<=a.EPSILON*Math.max(1,Math.abs(M),Math.abs(A))};var a=function(t){if(t&&t.__esModule)return t;var n={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.default=t,n}(r(0));function e(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],s=n[5],c=n[6],f=n[7],M=n[8],h=r[0],l=r[1],v=r[2],d=r[3],b=r[4],m=r[5],p=r[6],P=r[7],A=r[8];return t[0]=h*a+l*o+v*c,t[1]=h*e+l*i+v*f,t[2]=h*u+l*s+v*M,t[3]=d*a+b*o+m*c,t[4]=d*e+b*i+m*f,t[5]=d*u+b*s+m*M,t[6]=p*a+P*o+A*c,t[7]=p*e+P*i+A*f,t[8]=p*u+P*s+A*M,t}function u(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t[4]=n[4]-r[4],t[5]=n[5]-r[5],t[6]=n[6]-r[6],t[7]=n[7]-r[7],t[8]=n[8]-r[8],t}n.mul=e,n.sub=u},function(t,n,r){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.forEach=n.sqrLen=n.sqrDist=n.dist=n.div=n.mul=n.sub=n.len=void 0,n.create=e,n.clone=function(t){var n=new a.ARRAY_TYPE(2);return n[0]=t[0],n[1]=t[1],n},n.fromValues=function(t,n){var r=new a.ARRAY_TYPE(2);return r[0]=t,r[1]=n,r},n.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t},n.set=function(t,n,r){return t[0]=n,t[1]=r,t},n.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t},n.subtract=u,n.multiply=o,n.divide=i,n.ceil=function(t,n){return t[0]=Math.ceil(n[0]),t[1]=Math.ceil(n[1]),t},n.floor=function(t,n){return t[0]=Math.floor(n[0]),t[1]=Math.floor(n[1]),t},n.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t},n.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t},n.round=function(t,n){return t[0]=Math.round(n[0]),t[1]=Math.round(n[1]),t},n.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t},n.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t},n.distance=s,n.squaredDistance=c,n.length=f,n.squaredLength=M,n.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t},n.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t},n.normalize=function(t,n){var r=n[0],a=n[1],e=r*r+a*a;e>0&&(e=1/Math.sqrt(e),t[0]=n[0]*e,t[1]=n[1]*e);return t},n.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]},n.cross=function(t,n,r){var a=n[0]*r[1]-n[1]*r[0];return t[0]=t[1]=0,t[2]=a,t},n.lerp=function(t,n,r,a){var e=n[0],u=n[1];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t},n.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI;return t[0]=Math.cos(r)*n,t[1]=Math.sin(r)*n,t},n.transformMat2=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e,t[1]=r[1]*a+r[3]*e,t},n.transformMat2d=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e+r[4],t[1]=r[1]*a+r[3]*e+r[5],t},n.transformMat3=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[3]*e+r[6],t[1]=r[1]*a+r[4]*e+r[7],t},n.transformMat4=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[4]*e+r[12],t[1]=r[1]*a+r[5]*e+r[13],t},n.rotate=function(t,n,r,a){var e=n[0]-r[0],u=n[1]-r[1],o=Math.sin(a),i=Math.cos(a);return t[0]=e*i-u*o+r[0],t[1]=e*o+u*i+r[1],t},n.angle=function(t,n){var r=t[0],a=t[1],e=n[0],u=n[1],o=r*r+a*a;o>0&&(o=1/Math.sqrt(o));var i=e*e+u*u;i>0&&(i=1/Math.sqrt(i));var s=(r*e+a*u)*o*i;return s>1?0:s<-1?Math.PI:Math.acos(s)},n.str=function(t){return"vec2("+t[0]+", "+t[1]+")"},n.exactEquals=function(t,n){return t[0]===n[0]&&t[1]===n[1]},n.equals=function(t,n){var r=t[0],e=t[1],u=n[0],o=n[1];return Math.abs(r-u)<=a.EPSILON*Math.max(1,Math.abs(r),Math.abs(u))&&Math.abs(e-o)<=a.EPSILON*Math.max(1,Math.abs(e),Math.abs(o))};var a=function(t){if(t&&t.__esModule)return t;var n={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.default=t,n}(r(0));function e(){var t=new a.ARRAY_TYPE(2);return a.ARRAY_TYPE!=Float32Array&&(t[0]=0,t[1]=0),t}function u(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t}function o(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t}function i(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t}function s(t,n){var r=n[0]-t[0],a=n[1]-t[1];return Math.sqrt(r*r+a*a)}function c(t,n){var r=n[0]-t[0],a=n[1]-t[1];return r*r+a*a}function f(t){var n=t[0],r=t[1];return Math.sqrt(n*n+r*r)}function M(t){var n=t[0],r=t[1];return n*n+r*r}n.len=f,n.sub=u,n.mul=o,n.div=i,n.dist=s,n.sqrDist=c,n.sqrLen=M,n.forEach=function(){var t=e();return function(n,r,a,e,u,o){var i=void 0,s=void 0;for(r||(r=2),a||(a=0),s=e?Math.min(e*r+a,n.length):n.length,i=a;i0){r=Math.sqrt(r);var a=n[0]/r,e=n[1]/r,u=n[2]/r,o=n[3]/r,i=n[4],s=n[5],c=n[6],f=n[7],M=a*i+e*s+u*c+o*f;t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=(i-a*M)/r,t[5]=(s-e*M)/r,t[6]=(c-u*M)/r,t[7]=(f-o*M)/r}return t},n.str=function(t){return"quat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+")"},n.exactEquals=function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]&&t[4]===n[4]&&t[5]===n[5]&&t[6]===n[6]&&t[7]===n[7]},n.equals=function(t,n){var r=t[0],e=t[1],u=t[2],o=t[3],i=t[4],s=t[5],c=t[6],f=t[7],M=n[0],h=n[1],l=n[2],v=n[3],d=n[4],b=n[5],m=n[6],p=n[7];return Math.abs(r-M)<=a.EPSILON*Math.max(1,Math.abs(r),Math.abs(M))&&Math.abs(e-h)<=a.EPSILON*Math.max(1,Math.abs(e),Math.abs(h))&&Math.abs(u-l)<=a.EPSILON*Math.max(1,Math.abs(u),Math.abs(l))&&Math.abs(o-v)<=a.EPSILON*Math.max(1,Math.abs(o),Math.abs(v))&&Math.abs(i-d)<=a.EPSILON*Math.max(1,Math.abs(i),Math.abs(d))&&Math.abs(s-b)<=a.EPSILON*Math.max(1,Math.abs(s),Math.abs(b))&&Math.abs(c-m)<=a.EPSILON*Math.max(1,Math.abs(c),Math.abs(m))&&Math.abs(f-p)<=a.EPSILON*Math.max(1,Math.abs(f),Math.abs(p))};var a=o(r(0)),e=o(r(3)),u=o(r(4));function o(t){if(t&&t.__esModule)return t;var n={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.default=t,n}function i(t,n,r){var a=.5*r[0],e=.5*r[1],u=.5*r[2],o=n[0],i=n[1],s=n[2],c=n[3];return t[0]=o,t[1]=i,t[2]=s,t[3]=c,t[4]=a*c+e*s-u*i,t[5]=e*c+u*o-a*s,t[6]=u*c+a*i-e*o,t[7]=-a*o-e*i-u*s,t}function s(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t}n.getReal=e.copy;n.setReal=e.copy;function c(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[4],s=r[5],c=r[6],f=r[7],M=n[4],h=n[5],l=n[6],v=n[7],d=r[0],b=r[1],m=r[2],p=r[3];return t[0]=a*p+o*d+e*m-u*b,t[1]=e*p+o*b+u*d-a*m,t[2]=u*p+o*m+a*b-e*d,t[3]=o*p-a*d-e*b-u*m,t[4]=a*f+o*i+e*c-u*s+M*p+v*d+h*m-l*b,t[5]=e*f+o*s+u*i-a*c+h*p+v*b+l*d-M*m,t[6]=u*f+o*c+a*s-e*i+l*p+v*m+M*b-h*d,t[7]=o*f-a*i-e*s-u*c+v*p-M*d-h*b-l*m,t}n.mul=c;var f=n.dot=e.dot;var M=n.length=e.length,h=(n.len=M,n.squaredLength=e.squaredLength);n.sqrLen=h},function(t,n,r){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.sub=n.mul=void 0,n.create=function(){var t=new a.ARRAY_TYPE(6);a.ARRAY_TYPE!=Float32Array&&(t[1]=0,t[2]=0,t[4]=0,t[5]=0);return t[0]=1,t[3]=1,t},n.clone=function(t){var n=new a.ARRAY_TYPE(6);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n},n.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t},n.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},n.fromValues=function(t,n,r,e,u,o){var i=new a.ARRAY_TYPE(6);return i[0]=t,i[1]=n,i[2]=r,i[3]=e,i[4]=u,i[5]=o,i},n.set=function(t,n,r,a,e,u,o){return t[0]=n,t[1]=r,t[2]=a,t[3]=e,t[4]=u,t[5]=o,t},n.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],s=r*u-a*e;if(!s)return null;return s=1/s,t[0]=u*s,t[1]=-a*s,t[2]=-e*s,t[3]=r*s,t[4]=(e*i-u*o)*s,t[5]=(a*o-r*i)*s,t},n.determinant=function(t){return t[0]*t[3]-t[1]*t[2]},n.multiply=e,n.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],s=n[5],c=Math.sin(r),f=Math.cos(r);return t[0]=a*f+u*c,t[1]=e*f+o*c,t[2]=a*-c+u*f,t[3]=e*-c+o*f,t[4]=i,t[5]=s,t},n.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],s=n[5],c=r[0],f=r[1];return t[0]=a*c,t[1]=e*c,t[2]=u*f,t[3]=o*f,t[4]=i,t[5]=s,t},n.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],s=n[5],c=r[0],f=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=a*c+u*f+i,t[5]=e*c+o*f+s,t},n.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t[4]=0,t[5]=0,t},n.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t[4]=0,t[5]=0,t},n.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=n[0],t[5]=n[1],t},n.str=function(t){return"mat2d("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+")"},n.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+1)},n.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t[4]=n[4]+r[4],t[5]=n[5]+r[5],t},n.subtract=u,n.multiplyScalar=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t[4]=n[4]*r,t[5]=n[5]*r,t},n.multiplyScalarAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t[4]=n[4]+r[4]*a,t[5]=n[5]+r[5]*a,t},n.exactEquals=function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]&&t[4]===n[4]&&t[5]===n[5]},n.equals=function(t,n){var r=t[0],e=t[1],u=t[2],o=t[3],i=t[4],s=t[5],c=n[0],f=n[1],M=n[2],h=n[3],l=n[4],v=n[5];return Math.abs(r-c)<=a.EPSILON*Math.max(1,Math.abs(r),Math.abs(c))&&Math.abs(e-f)<=a.EPSILON*Math.max(1,Math.abs(e),Math.abs(f))&&Math.abs(u-M)<=a.EPSILON*Math.max(1,Math.abs(u),Math.abs(M))&&Math.abs(o-h)<=a.EPSILON*Math.max(1,Math.abs(o),Math.abs(h))&&Math.abs(i-l)<=a.EPSILON*Math.max(1,Math.abs(i),Math.abs(l))&&Math.abs(s-v)<=a.EPSILON*Math.max(1,Math.abs(s),Math.abs(v))};var a=function(t){if(t&&t.__esModule)return t;var n={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.default=t,n}(r(0));function e(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],s=n[5],c=r[0],f=r[1],M=r[2],h=r[3],l=r[4],v=r[5];return t[0]=a*c+u*f,t[1]=e*c+o*f,t[2]=a*M+u*h,t[3]=e*M+o*h,t[4]=a*l+u*v+i,t[5]=e*l+o*v+s,t}function u(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t[4]=n[4]-r[4],t[5]=n[5]-r[5],t}n.mul=e,n.sub=u},function(t,n,r){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.sub=n.mul=void 0,n.create=function(){var t=new a.ARRAY_TYPE(4);a.ARRAY_TYPE!=Float32Array&&(t[1]=0,t[2]=0);return t[0]=1,t[3]=1,t},n.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},n.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},n.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},n.fromValues=function(t,n,r,e){var u=new a.ARRAY_TYPE(4);return u[0]=t,u[1]=n,u[2]=r,u[3]=e,u},n.set=function(t,n,r,a,e){return t[0]=n,t[1]=r,t[2]=a,t[3]=e,t},n.transpose=function(t,n){if(t===n){var r=n[1];t[1]=n[2],t[2]=r}else t[0]=n[0],t[1]=n[2],t[2]=n[1],t[3]=n[3];return t},n.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*u-e*a;if(!o)return null;return o=1/o,t[0]=u*o,t[1]=-a*o,t[2]=-e*o,t[3]=r*o,t},n.adjoint=function(t,n){var r=n[0];return t[0]=n[3],t[1]=-n[1],t[2]=-n[2],t[3]=r,t},n.determinant=function(t){return t[0]*t[3]-t[2]*t[1]},n.multiply=e,n.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),s=Math.cos(r);return t[0]=a*s+u*i,t[1]=e*s+o*i,t[2]=a*-i+u*s,t[3]=e*-i+o*s,t},n.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],s=r[1];return t[0]=a*i,t[1]=e*i,t[2]=u*s,t[3]=o*s,t},n.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t},n.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t},n.str=function(t){return"mat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},n.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2))},n.LDU=function(t,n,r,a){return t[2]=a[2]/a[0],r[0]=a[0],r[1]=a[1],r[3]=a[3]-t[2]*r[1],[t,n,r]},n.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t},n.subtract=u,n.exactEquals=function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]},n.equals=function(t,n){var r=t[0],e=t[1],u=t[2],o=t[3],i=n[0],s=n[1],c=n[2],f=n[3];return Math.abs(r-i)<=a.EPSILON*Math.max(1,Math.abs(r),Math.abs(i))&&Math.abs(e-s)<=a.EPSILON*Math.max(1,Math.abs(e),Math.abs(s))&&Math.abs(u-c)<=a.EPSILON*Math.max(1,Math.abs(u),Math.abs(c))&&Math.abs(o-f)<=a.EPSILON*Math.max(1,Math.abs(o),Math.abs(f))},n.multiplyScalar=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t},n.multiplyScalarAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t};var a=function(t){if(t&&t.__esModule)return t;var n={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.default=t,n}(r(0));function e(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],s=r[1],c=r[2],f=r[3];return t[0]=a*i+u*s,t[1]=e*i+o*s,t[2]=a*c+u*f,t[3]=e*c+o*f,t}function u(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t}n.mul=e,n.sub=u},function(t,n,r){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.vec4=n.vec3=n.vec2=n.quat2=n.quat=n.mat4=n.mat3=n.mat2d=n.mat2=n.glMatrix=void 0;var a=l(r(0)),e=l(r(9)),u=l(r(8)),o=l(r(5)),i=l(r(4)),s=l(r(3)),c=l(r(7)),f=l(r(6)),M=l(r(2)),h=l(r(1));function l(t){if(t&&t.__esModule)return t;var n={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r]);return n.default=t,n}n.glMatrix=a,n.mat2=e,n.mat2d=u,n.mat3=o,n.mat4=i,n.quat=s,n.quat2=c,n.vec2=f,n.vec3=M,n.vec4=h}])}); \ No newline at end of file diff --git a/toolkit/components/resistfingerprinting/content/moz.yaml b/toolkit/components/resistfingerprinting/content/moz.yaml deleted file mode 100644 index 903f6a5173f4..000000000000 --- a/toolkit/components/resistfingerprinting/content/moz.yaml +++ /dev/null @@ -1,20 +0,0 @@ -schema: 1 - -bugzilla: - product: "Core" - component: "Privacy: Anti-Tracking" - -origin: - name: "gl-matrix" - description: "High performance matrix and vector operations" - - url: "https://github.com/toji/gl-matrix/tree/master" - license: "MIT" - license-file: "gl-matrix.LICENSE" - - release: 2.7.0 - revision: b836df92c5a959ebf766b53d50148123d0844db4 - - notes: > - This library is not exposed to attacker input and indeed only given fixed input from usercharacteristics.js - so although it is out of date, this is not a concern. diff --git a/toolkit/components/resistfingerprinting/content/usercharacteristics.css b/toolkit/components/resistfingerprinting/content/usercharacteristics.css deleted file mode 100644 index 2294c5ade3d7..000000000000 --- a/toolkit/components/resistfingerprinting/content/usercharacteristics.css +++ /dev/null @@ -1,7 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -.testcanvas { - border: 1px solid #2600ff; -} diff --git a/toolkit/components/resistfingerprinting/content/usercharacteristics.html b/toolkit/components/resistfingerprinting/content/usercharacteristics.html index b0ed33df076f..50071bb21e4c 100644 --- a/toolkit/components/resistfingerprinting/content/usercharacteristics.html +++ b/toolkit/components/resistfingerprinting/content/usercharacteristics.html @@ -8,263 +8,11 @@ - about:fingerprintingprotection - - + about:fingerprinting -
-

Test Canvases

-
-

Canvas 1

- - - - - - -
ImageData: - -
-
-
-

Canvas 2

- - - - - - -
ImageData: - -
-
-
-

Canvas 3

- - - - - - -
ImageData: - -
-
-
-

Canvas 4

- - - - - - -
ImageData: - -
-
-
-

Canvas 5

- - - - - - -
ImageData: - -
-
-
-

Canvas 6

- - - - - - -
ImageData: - -
-
-
-

Canvas 7

- - - - - - -
ImageData: - -
-
-
-

Canvas 8

- - - - - - -
ImageData: - -
-
-
-

Canvas 9

- - - - - - -
ImageData: - -
-
-
-

Canvas 10

- - - - - - -
ImageData: - -
-
-
-

WebGL Canvas

- - - - - - -
ImageData: - -
-
-
-

FingerprintJS Canvas 1 (Text)

- - - - - - -
ImageData: - -
-
-
-

FingerprintJS Canvas 2 (Geometry)

- - - - - - -
ImageData: - -
-
-
- - diff --git a/toolkit/components/resistfingerprinting/content/usercharacteristics.js b/toolkit/components/resistfingerprinting/content/usercharacteristics.js index 201a4098ed38..23651a07208f 100644 --- a/toolkit/components/resistfingerprinting/content/usercharacteristics.js +++ b/toolkit/components/resistfingerprinting/content/usercharacteristics.js @@ -2,12 +2,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -// Defined by gl-matrix.js -/* global mat4 */ - -// ============================================================= -// Utility Functions - var debugMsgs = []; function debug(...args) { let msg = ""; @@ -26,582 +20,10 @@ function debug(...args) { let stringifiedArgs = args.map(stringify); msg += stringifiedArgs.join(" "); debugMsgs.push(msg); - - // Also echo it locally - /* eslint-disable-next-line no-console */ - console.log(msg); } -// ============================================================== -// Regular Canvases - -function populateTestCanvases() { - let promisesToResolve = []; - const kImageBlob = - "data:content/type;base64,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"; - - // Canvas 1 is just a box, this is a basic check that we can draw, it does - // not attempt any fingerprinting. - var canvas1 = document.getElementById("canvas1"); - var c1 = canvas1.getContext("2d"); - c1.fillStyle = "orange"; - c1.fillRect(100, 100, 50, 50); - document.getElementById("canvas1data").value = canvas1.toDataURL(); - - // Canvas 2 is a polygon with lines, this fingerprints a little via - // floating point rounding. - var canvas2 = document.getElementById("canvas2"); - var c2 = canvas2.getContext("2d"); - c2.fillStyle = "blue"; - c2.beginPath(); - c2.moveTo(50, 50); - c2.lineTo(200, 200); - c2.lineTo(175, 100); - c2.closePath(); - c2.fill(); - c2.strokeStyle = "red"; - c2.lineWidth = 5; - c2.stroke(); - document.getElementById("canvas2data").value = canvas2.toDataURL(); - - // Canvas 3 renders an image at a reduced resolution, this also - // fingerprints via floating point rounding. - var canvas3 = document.getElementById("canvas3"); - var c3 = canvas3.getContext("2d"); - let loadPromise = new Promise((resolve, reject) => { - const image = new Image(); - // CC Public Domain - https://www.flickr.com/photos/birds_and_critters/53695948491/ - image.src = kImageBlob; - image.onload = () => { - c3.drawImage(image, 0, 0, canvas3.width, canvas3.height); - document.getElementById("canvas3data").value = canvas3.toDataURL(); - resolve(); - }; - image.onerror = e => { - reject(e); - }; - }); - promisesToResolve.push(loadPromise); - - // Canvas 4 renders two rotated semi-transparent boxes. - var canvas4 = document.getElementById("canvas4"); - var c4 = canvas4.getContext("2d"); - c4.fillStyle = "orange"; - c4.globalAlpha = 0.5; - c4.translate(100, 100); - c4.rotate((45.0 * Math.PI) / 180.0); - c4.fillRect(0, 0, 50, 50); - c4.rotate((-15.0 * Math.PI) / 180.0); - c4.fillRect(0, 0, 50, 50); - document.getElementById("canvas4data").value = canvas4.toDataURL(); - - // Canvas 5 renders text with a local font the user might have in a pretty standard configuration - var canvas5 = document.getElementById("canvas5"); - var c5 = canvas5.getContext("2d"); - c5.fillStyle = "green"; - c5.font = "italic 30px Georgia"; - c5.fillText("The quick brown", 15, 100); - c5.fillText("fox jumps over", 15, 150); - c5.fillText("the lazy dog", 15, 200); - document.getElementById("canvas5data").value = canvas5.toDataURL(); - - // Canvas 6 renders text with a local font the user might have but translated, rotated, and with a blurred shadow - var canvas6 = document.getElementById("canvas6"); - var c6 = canvas6.getContext("2d"); - c6.fillStyle = "green"; - c6.translate(10, 100); - c6.rotate((45.0 * Math.PI) / 180.0); - c6.shadowColor = "blue"; - c6.shadowBlur = 50; - c6.font = "italic 40px Georgia"; - c6.fillText("The quick", 0, 0); - document.getElementById("canvas6data").value = canvas6.toDataURL(); - - // Canvas 7 renders text with a system font. - var canvas7 = document.getElementById("canvas7"); - var c7 = canvas7.getContext("2d"); - c7.fillStyle = "green"; - c7.font = "italic 30px system-ui"; - c7.fillText("The quick brown", 15, 100); - c7.fillText("fox jumps over", 15, 150); - c7.fillText("the lazy dog", 15, 200); - document.getElementById("canvas7data").value = canvas7.toDataURL(); - - // Canvas 8 renders text with a system font. - var canvas8 = document.getElementById("canvas8"); - var c8 = canvas8.getContext("2d"); - c8.fillStyle = "green"; - c8.translate(10, 100); - c8.rotate((45.0 * Math.PI) / 180.0); - c8.shadowColor = "blue"; - c8.shadowBlur = 50; - c8.font = "italic 40px system-ui"; - c8.fillText("The quick", 0, 0); - document.getElementById("canvas8data").value = canvas8.toDataURL(); - - // Canvas 9 renders text with a supplied font. - var canvas9 = document.getElementById("canvas9"); - var c9 = canvas9.getContext("2d"); - c9.fillStyle = "green"; - c9.font = "italic 30px LocalFiraSans"; - c9.fillText("The quick brown", 15, 100); - c9.fillText("fox jumps over", 15, 150); - c9.fillText("the lazy dog", 15, 200); - document.getElementById("canvas9data").value = canvas9.toDataURL(); - - // Canvas 10 renders text with a supplied font. - var canvas10 = document.getElementById("canvas10"); - var c10 = canvas10.getContext("2d"); - c10.fillStyle = "green"; - c10.translate(10, 100); - c10.rotate((45.0 * Math.PI) / 180.0); - c10.shadowColor = "blue"; - c10.shadowBlur = 50; - c10.font = "italic 40px LocalFiraSans"; - c10.fillText("The quick", 0, 0); - document.getElementById("canvas10data").value = canvas10.toDataURL(); - - return promisesToResolve; -} - -// ======================================================================= -// WebGL Canvases - -function populateWebGLCanvases() { - // The following WebGL code came from https://github.com/mdn/dom-examples/blob/4f305d21de796432dac2e9f2961591e4b7f913c0/webgl-examples/tutorial/sample3/webgl-demo.js - // with some minor modifications - - let promisesToResolve = []; - - // -------------------------------------------------------------------- - // initBuffers - // - // Initialize the buffers we'll need. For this demo, we just - // have one object -- a simple two-dimensional square. - // - function initBuffers(gl) { - // Create a buffer for the square's positions. - - const positionBuffer = gl.createBuffer(); - - // Select the positionBuffer as the one to apply buffer - // operations to from here out. - - gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); - - // Now create an array of positions for the square. - - const positions = [1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0]; - - // Now pass the list of positions into WebGL to build the - // shape. We do this by creating a Float32Array from the - // JavaScript array, then use it to fill the current buffer. - - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); - - // Now set up the colors for the vertices - - var colors = [ - 1.0, - 1.0, - 1.0, - 1.0, // white - 1.0, - 0.0, - 0.0, - 1.0, // red - 0.0, - 1.0, - 0.0, - 1.0, // green - 0.0, - 0.0, - 1.0, - 1.0, // blue - ]; - - const colorBuffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); - - return { - position: positionBuffer, - color: colorBuffer, - }; - } - - // -------------------------------------------------------------------- - // Draw the scene. - function drawScene(gl, programInfo, buffers) { - gl.clearColor(0.0, 0.0, 0.0, 1.0); // Clear to black, fully opaque - gl.clearDepth(1.0); // Clear everything - gl.enable(gl.DEPTH_TEST); // Enable depth testing - gl.depthFunc(gl.LEQUAL); // Near things obscure far things - - // Clear the canvas before we start drawing on it. - - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - - // Create a perspective matrix, a special matrix that is - // used to simulate the distortion of perspective in a camera. - // Our field of view is 45 degrees, with a width/height - // ratio that matches the display size of the canvas - // and we only want to see objects between 0.1 units - // and 100 units away from the camera. - - const fieldOfView = (45 * Math.PI) / 180; // in radians - const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight; - const zNear = 0.1; - const zFar = 100.0; - const projectionMatrix = mat4.create(); - - // note: glmatrix.js always has the first argument - // as the destination to receive the result. - mat4.perspective(projectionMatrix, fieldOfView, aspect, zNear, zFar); - - // Set the drawing position to the "identity" point, which is - // the center of the scene. - const modelViewMatrix = mat4.create(); - - var squareRotation = 1.0; - - // Now move the drawing position a bit to where we want to - // start drawing the square. - - mat4.translate( - modelViewMatrix, // destination matrix - modelViewMatrix, // matrix to translate - [-0.0, 0.0, -6.0] - ); // amount to translate - mat4.rotate( - modelViewMatrix, // destination matrix - modelViewMatrix, // matrix to rotate - squareRotation, // amount to rotate in radians - [0, 0, 1] - ); // axis to rotate around - - // Tell WebGL how to pull out the positions from the position - // buffer into the vertexPosition attribute - { - const numComponents = 2; - const type = gl.FLOAT; - const normalize = false; - const stride = 0; - const offset = 0; - gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position); - gl.vertexAttribPointer( - programInfo.attribLocations.vertexPosition, - numComponents, - type, - normalize, - stride, - offset - ); - gl.enableVertexAttribArray(programInfo.attribLocations.vertexPosition); - } - - // Tell WebGL how to pull out the colors from the color buffer - // into the vertexColor attribute. - { - const numComponents = 4; - const type = gl.FLOAT; - const normalize = false; - const stride = 0; - const offset = 0; - gl.bindBuffer(gl.ARRAY_BUFFER, buffers.color); - gl.vertexAttribPointer( - programInfo.attribLocations.vertexColor, - numComponents, - type, - normalize, - stride, - offset - ); - gl.enableVertexAttribArray(programInfo.attribLocations.vertexColor); - } - - // Tell WebGL to use our program when drawing - - gl.useProgram(programInfo.program); - - // Set the shader uniforms - - gl.uniformMatrix4fv( - programInfo.uniformLocations.projectionMatrix, - false, - projectionMatrix - ); - gl.uniformMatrix4fv( - programInfo.uniformLocations.modelViewMatrix, - false, - modelViewMatrix - ); - - { - const offset = 0; - const vertexCount = 4; - gl.drawArrays(gl.TRIANGLE_STRIP, offset, vertexCount); - } - } - - // -------------------------------------------------------------------- - // Initialize a shader program, so WebGL knows how to draw our data - function initShaderProgram(gl, vsSource, fsSource) { - const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource); - const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource); - - // Create the shader program - - const shaderProgram = gl.createProgram(); - gl.attachShader(shaderProgram, vertexShader); - gl.attachShader(shaderProgram, fragmentShader); - gl.linkProgram(shaderProgram); - - // If creating the shader program failed, alert - - if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { - alert( - "Unable to initialize the shader program: " + - gl.getProgramInfoLog(shaderProgram) - ); - return null; - } - - return shaderProgram; - } - - // -------------------------------------------------------------------- - // - // creates a shader of the given type, uploads the source and - // compiles it. - // - function loadShader(gl, type, source) { - const shader = gl.createShader(type); - - // Send the source to the shader object - gl.shaderSource(shader, source); - - // Compile the shader program - gl.compileShader(shader); - - // See if it compiled successfully - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - alert( - "An error occurred compiling the shaders: " + - gl.getShaderInfoLog(shader) - ); - gl.deleteShader(shader); - return null; - } - - return shader; - } - - // -------------------------------------------------------------------- - const canvas = document.getElementById("glcanvas"); - const gl = canvas.getContext("webgl"); - - // If we don't have a GL context, give up now - - if (!gl) { - alert( - "Unable to initialize WebGL. Your browser or machine may not support it." - ); - return []; - } - - // Vertex shader program - - const vsSource = ` - attribute vec4 aVertexPosition; - attribute vec4 aVertexColor; - - uniform mat4 uModelViewMatrix; - uniform mat4 uProjectionMatrix; - - varying lowp vec4 vColor; - - void main(void) { - gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition; - vColor = aVertexColor; - } - `; - - // Fragment shader program - - const fsSource = ` - varying lowp vec4 vColor; - - void main(void) { - gl_FragColor = vColor; - } - `; - - // Initialize a shader program; this is where all the lighting - // for the vertices and so forth is established. - const shaderProgram = initShaderProgram(gl, vsSource, fsSource); - - // Collect all the info needed to use the shader program. - // Look up which attributes our shader program is using - // for aVertexPosition, aVevrtexColor and also - // look up uniform locations. - const programInfo = { - program: shaderProgram, - attribLocations: { - vertexPosition: gl.getAttribLocation(shaderProgram, "aVertexPosition"), - vertexColor: gl.getAttribLocation(shaderProgram, "aVertexColor"), - }, - uniformLocations: { - projectionMatrix: gl.getUniformLocation( - shaderProgram, - "uProjectionMatrix" - ), - modelViewMatrix: gl.getUniformLocation(shaderProgram, "uModelViewMatrix"), - }, - }; - - // Here's where we call the routine that builds all the - // objects we'll be drawing. - const buffers = initBuffers(gl); - - // Draw the scene - drawScene(gl, programInfo, buffers); - - // Write to the fields - document.getElementById("glcanvasdata").value = canvas.toDataURL(); - - return promisesToResolve; -} - -// ============================================================== -// Fingerprint JS Canvases -function populateFingerprintJSCanvases() { - let promisesToResolve = []; - - // fingerprintjs - // Their fingerprinting code went to the BSL license from MIT in - // https://github.com/fingerprintjs/fingerprintjs/commit/572fd98f9e4f27b4e854137ea0d53231b3b4eb6e - // So use the version of the code in the parent commit which is still MIT - // https://github.com/fingerprintjs/fingerprintjs/blob/aca79b37f7956eee58018e4a317a2bdf8be62d0f/src/sources/canvas.ts - - function renderTextImage(canvas, context) { - context.textBaseline = "alphabetic"; - context.fillStyle = "#f60"; - context.fillRect(100, 1, 62, 20); - - context.fillStyle = "#069"; - // It's important to use explicit built-in fonts in order to exclude the affect of font preferences - // (there is a separate entropy source for them). - context.font = '11pt "Times New Roman"'; - // The choice of emojis has a gigantic impact on rendering performance (especially in FF). - // Some newer emojis cause it to slow down 50-200 times. - // There must be no text to the right of the emoji, see https://github.com/fingerprintjs/fingerprintjs/issues/574 - // A bare emoji shouldn't be used because the canvas will change depending on the script encoding: - // https://github.com/fingerprintjs/fingerprintjs/issues/66 - // Escape sequence shouldn't be used too because Terser will turn it into a bare unicode. - const printedText = `Cwm fjordbank gly ${ - String.fromCharCode(55357, 56835) /* 😃 */ - }`; - context.fillText(printedText, 2, 15); - context.fillStyle = "rgba(102, 204, 0, 0.2)"; - context.font = "18pt Arial"; - context.fillText(printedText, 4, 45); - } - - function renderGeometryImage(canvas, context) { - // Canvas blending - // https://web.archive.org/web/20170826194121/http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/ - // http://jsfiddle.net/NDYV8/16/ - context.globalCompositeOperation = "multiply"; - for (const [color, x, y] of [ - ["#f2f", 40, 40], - ["#2ff", 80, 40], - ["#ff2", 60, 80], - ]) { - context.fillStyle = color; - context.beginPath(); - context.arc(x, y, 40, 0, Math.PI * 2, true); - context.closePath(); - context.fill(); - } - - // Canvas winding - // https://web.archive.org/web/20130913061632/http://blogs.adobe.com/webplatform/2013/01/30/winding-rules-in-canvas/ - // http://jsfiddle.net/NDYV8/19/ - context.fillStyle = "#f9c"; - context.arc(60, 60, 60, 0, Math.PI * 2, true); - context.arc(60, 60, 20, 0, Math.PI * 2, true); - context.fill("evenodd"); - } - - const canvas1 = document.getElementById("fingerprintjscanvas1"); - const context1 = canvas1.getContext("2d"); - renderTextImage(canvas1, context1); - document.getElementById("fingerprintjscanvas1data").value = - canvas1.toDataURL(); - - const canvas2 = document.getElementById("fingerprintjscanvas2"); - const context2 = canvas2.getContext("2d"); - renderGeometryImage(canvas2, context2); - document.getElementById("fingerprintjscanvas2data").value = - canvas2.toDataURL(); - - return promisesToResolve; -} - -// ======================================================================= -// Setup & Populating - -/* Pick any local font, we just don't want to needlessly increase binary size */ -const LocalFiraSans = new FontFace( - "LocalFiraSans", - "url('chrome://pocket/content/panels/fonts/FiraSans-Regular.woff') format('woff')" -); -LocalFiraSans.load().then(font => { - document.fonts.add(font); - - let promises = []; - promises = promises.concat(populateTestCanvases()); - promises = promises.concat(populateWebGLCanvases()); - promises = promises.concat(populateFingerprintJSCanvases()); - - debug("Awaiting", promises.length, "promises."); - - Promise.allSettled(promises).then(() => { - let output = {}; - - debug("Sizes of extractions:"); - for (let id of [ - "canvas1data", - "canvas2data", - "canvas3data", - "canvas4data", - "canvas5data", - "canvas6data", - "canvas7data", - "canvas8data", - "canvas9data", - "canvas10data", - "glcanvasdata", - "fingerprintjscanvas1data", - "fingerprintjscanvas2data", - ]) { - let obj = document.getElementById(id); - debug(id, obj.value.length); - output[id] = obj.value; - } - - document.dispatchEvent( - new CustomEvent("UserCharacteristicsDataDone", { - bubbles: true, - detail: { - debug: debugMsgs, - output, - }, - }) - ); - }); -}); +debug("Debug Line"); +debug("Another debug line, with", { an: "object" }); // A hacky way to ensure all GamePad related services are running by the time we // want to know about GamePads. This will attach a listener for this window to @@ -613,3 +35,18 @@ LocalFiraSans.load().then(font => { // for gamepads attached to the machine. We need to give that background thread // time to run so all the data is there when we request it. navigator.getGamepads(); + +// The first time we put a real value in here, please update browser_usercharacteristics.js +let output = { + foo: "Hello World", +}; + +document.dispatchEvent( + new CustomEvent("UserCharacteristicsDataDone", { + bubbles: true, + detail: { + debug: debugMsgs, + output, + }, + }) +); diff --git a/toolkit/components/resistfingerprinting/jar.mn b/toolkit/components/resistfingerprinting/jar.mn index d36ac9bc1c74..657797b6d090 100644 --- a/toolkit/components/resistfingerprinting/jar.mn +++ b/toolkit/components/resistfingerprinting/jar.mn @@ -3,7 +3,5 @@ # file, You can obtain one at https://mozilla.org/MPL/2.0/. toolkit.jar: - content/global/usercharacteristics/gl-matrix.js (content/gl-matrix.js) - content/global/usercharacteristics/usercharacteristics.css (content/usercharacteristics.css) content/global/usercharacteristics/usercharacteristics.html (content/usercharacteristics.html) content/global/usercharacteristics/usercharacteristics.js (content/usercharacteristics.js) diff --git a/toolkit/components/resistfingerprinting/metrics.yaml b/toolkit/components/resistfingerprinting/metrics.yaml index 757f15e6995a..13cd7a495aa0 100644 --- a/toolkit/components/resistfingerprinting/metrics.yaml +++ b/toolkit/components/resistfingerprinting/metrics.yaml @@ -1047,266 +1047,6 @@ characteristics: data_sensitivity: - interaction - canvasdata1: - type: text - description: > - The base64 encoded form of an image rendered on a canvas. The image is a simple organge box and used as a control image - lifetime: application - send_in_pings: - - user-characteristics - notification_emails: - - tom@mozilla.com - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1879151 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1894958 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=xxx - expires: never - data_sensitivity: - # Text metrics are _required_ to be web_activity or highly_sensitive, so even though this - # is more like 'technical' (per the Data Review), I'm marking highly sensitive. - - highly_sensitive - - canvasdata2: - type: text - description: > - The base64 encoded form of an image rendered on a canvas. The image is a bordered triage, and used to test point interpolation - lifetime: application - send_in_pings: - - user-characteristics - notification_emails: - - tom@mozilla.com - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1879151 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1894958 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=xxx - expires: never - data_sensitivity: - # Text metrics are _required_ to be web_activity or highly_sensitive, so even though this - # is more like 'technical' (per the Data Review), I'm marking highly sensitive. - - highly_sensitive - - canvasdata3: - type: text - description: > - The base64 encoded form of an image rendered on a canvas. The image is a stretched photographic image, used to test image operations. - lifetime: application - send_in_pings: - - user-characteristics - notification_emails: - - tom@mozilla.com - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1879151 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1894958 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=xxx - expires: never - data_sensitivity: - # Text metrics are _required_ to be web_activity or highly_sensitive, so even though this - # is more like 'technical' (per the Data Review), I'm marking highly sensitive. - - highly_sensitive - - canvasdata4: - type: text - description: > - The base64 encoded form of an image rendered on a canvas. The image is two rotated, semi-transparenct overlapping squares, used to test transparency and point interpolation. - lifetime: application - send_in_pings: - - user-characteristics - notification_emails: - - tom@mozilla.com - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1879151 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1894958 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=xxx - expires: never - data_sensitivity: - # Text metrics are _required_ to be web_activity or highly_sensitive, so even though this - # is more like 'technical' (per the Data Review), I'm marking highly sensitive. - - highly_sensitive - - canvasdata5: - type: text - description: > - The base64 encoded form of an image rendered on a canvas. The image is a local font rendered normally. - lifetime: application - send_in_pings: - - user-characteristics - notification_emails: - - tom@mozilla.com - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1879151 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1894958 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=xxx - expires: never - data_sensitivity: - # Text metrics are _required_ to be web_activity or highly_sensitive, so even though this - # is more like 'technical' (per the Data Review), I'm marking highly sensitive. - - highly_sensitive - - canvasdata6: - type: text - description: > - The base64 encoded form of an image rendered on a canvas. The image is a local font rendered with italics, rotation, and shadow-blur. - lifetime: application - send_in_pings: - - user-characteristics - notification_emails: - - tom@mozilla.com - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1879151 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1894958 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=xxx - expires: never - data_sensitivity: - # Text metrics are _required_ to be web_activity or highly_sensitive, so even though this - # is more like 'technical' (per the Data Review), I'm marking highly sensitive. - - highly_sensitive - - canvasdata7: - type: text - description: > - The base64 encoded form of an image rendered on a canvas. The image is a system-ui font rendered normally. - lifetime: application - send_in_pings: - - user-characteristics - notification_emails: - - tom@mozilla.com - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1879151 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1894958 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=xxx - expires: never - data_sensitivity: - # Text metrics are _required_ to be web_activity or highly_sensitive, so even though this - # is more like 'technical' (per the Data Review), I'm marking highly sensitive. - - highly_sensitive - - canvasdata8: - type: text - description: > - The base64 encoded form of an image rendered on a canvas. The image is a system-ui font rendered with italics, rotation, and shadow-blur. - lifetime: application - send_in_pings: - - user-characteristics - notification_emails: - - tom@mozilla.com - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1879151 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1894958 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=xxx - expires: never - data_sensitivity: - # Text metrics are _required_ to be web_activity or highly_sensitive, so even though this - # is more like 'technical' (per the Data Review), I'm marking highly sensitive. - - highly_sensitive - - canvasdata9: - type: text - description: > - The base64 encoded form of an image rendered on a canvas. The image is a font shipped with Firefox rendered normally. - lifetime: application - send_in_pings: - - user-characteristics - notification_emails: - - tom@mozilla.com - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1879151 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1894958 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=xxx - expires: never - data_sensitivity: - # Text metrics are _required_ to be web_activity or highly_sensitive, so even though this - # is more like 'technical' (per the Data Review), I'm marking highly sensitive. - - highly_sensitive - - canvasdata10: - type: text - description: > - The base64 encoded form of an image rendered on a canvas. The image is a font shipped with Firefox rendered with italics, rotation, and shadow-blur. - lifetime: application - send_in_pings: - - user-characteristics - notification_emails: - - tom@mozilla.com - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1879151 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1894958 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=xxx - expires: never - data_sensitivity: - # Text metrics are _required_ to be web_activity or highly_sensitive, so even though this - # is more like 'technical' (per the Data Review), I'm marking highly sensitive. - - highly_sensitive - - canvasdata11_webgl: - type: text - description: > - The base64 encoded form of an image rendered on a WebGL canvas (instead of Canvas2D). IT is a RGB gradient cube. - lifetime: application - send_in_pings: - - user-characteristics - notification_emails: - - tom@mozilla.com - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1879151 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1894958 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=xxx - expires: never - data_sensitivity: - # Text metrics are _required_ to be web_activity or highly_sensitive, so even though this - # is more like 'technical' (per the Data Review), I'm marking highly sensitive. - - highly_sensitive - - canvasdata12_fingerprintjs1: - type: text - description: > - The base64 encoded form of an image rendered on a canvas, it is a copy of fingerprintjs' text canvas - lifetime: application - send_in_pings: - - user-characteristics - notification_emails: - - tom@mozilla.com - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1879151 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1894958 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=xxx - expires: never - data_sensitivity: - # Text metrics are _required_ to be web_activity or highly_sensitive, so even though this - # is more like 'technical' (per the Data Review), I'm marking highly sensitive. - - highly_sensitive - - canvasdata13_fingerprintjs2: - type: text - description: > - The base64 encoded form of an image rendered on a canvas, it is a copy of fingerprintjs' geometry canvas - lifetime: application - send_in_pings: - - user-characteristics - notification_emails: - - tom@mozilla.com - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1879151 - - https://bugzilla.mozilla.org/show_bug.cgi?id=1894958 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=xxx - expires: never - data_sensitivity: - # Text metrics are _required_ to be web_activity or highly_sensitive, so even though this - # is more like 'technical' (per the Data Review), I'm marking highly sensitive. - - highly_sensitive - font_size_monospace_modified: type: quantity unit: int diff --git a/toolkit/components/resistfingerprinting/tests/browser/browser_usercharacteristics.js b/toolkit/components/resistfingerprinting/tests/browser/browser_usercharacteristics.js index c0ec4a23bd83..989694831166 100644 --- a/toolkit/components/resistfingerprinting/tests/browser/browser_usercharacteristics.js +++ b/toolkit/components/resistfingerprinting/tests/browser/browser_usercharacteristics.js @@ -16,8 +16,13 @@ function promiseObserverNotification() { GleanPings.userCharacteristics.testBeforeNextSubmit(_ => { submitted = true; - // Did we assign a value we got out of about:fingerprintingprotection? - Assert.notEqual("", Glean.characteristics.canvasdata1.testGetValue()); + // Did we assign a value we got out of about:fingerprinting? + // For now, we are sticking the test value in a random telemetry + // metric, but once we have a real metric, we'll update this + Assert.equal( + "Hello World", + Glean.characteristics.timezone.testGetValue() + ); }); GleanPings.userCharacteristics.submit(); diff --git a/toolkit/content/license.html b/toolkit/content/license.html index 4470fc905ec7..3f05da0118ff 100644 --- a/toolkit/content/license.html +++ b/toolkit/content/license.html @@ -3628,7 +3628,6 @@ SOFTWARE.
  • third_party/rust/void
  • js/src/zydis (unless otherwise specified)
  • js/src/vm/Float16.h(the code contained in the half namespace)
  • -
  • toolkit/components/resistfingerprinting/content/gl-matrix.js
  • See the individual LICENSE files or headers for copyright owners.

    diff --git a/tools/rewriting/ThirdPartyPaths.txt b/tools/rewriting/ThirdPartyPaths.txt index 16361813fb0e..8a0a3b9daacd 100644 --- a/tools/rewriting/ThirdPartyPaths.txt +++ b/tools/rewriting/ThirdPartyPaths.txt @@ -189,7 +189,6 @@ toolkit/components/normandy/vendor/ toolkit/components/passwordmgr/PasswordRulesParser.sys.mjs toolkit/components/protobuf/ toolkit/components/reader/readability/ -toolkit/components/resistfingerprinting/content/gl-matrix.js toolkit/components/translation/cld2/ toolkit/components/translations/bergamot-translator/thirdparty toolkit/components/translations/bergamot-translator/bergamot-translator.js