diff --git a/.cursorrules b/.cursorrules new file mode 100644 index 00000000..ddb3f37c --- /dev/null +++ b/.cursorrules @@ -0,0 +1,2 @@ +- Check AGENTS.md for instructions specifically for AI +- Check README.md for instructions diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..992c6d64 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,24 @@ +module.exports = { + env: { + browser: true, + commonjs: true, + es6: true, + node: true, + }, + extends: "eslint:recommended", + ignorePatterns: ["dist/"], + globals: { + Atomics: "readonly", + SharedArrayBuffer: "readonly", + }, + parserOptions: { + ecmaVersion: 2020, + }, + overrides: [ + { + files: ["test/**/*.js"], + env: { mocha: true }, + }, + ], + rules: {}, +}; diff --git a/.github/workflows/browserstack.yml b/.github/workflows/browserstack.yml deleted file mode 100644 index 2a9d738f..00000000 --- a/.github/workflows/browserstack.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: Browserstack - -on: - pull_request: - types: [opened, synchronize] - push: - branches: - - master - - main - -jobs: - build: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [16.16] - - steps: - - name: "BrowserStack Env Setup" - uses: "browserstack/github-actions/setup-env@master" - with: - username: ${{ secrets.BROWSERSTACK_USERNAME }} - access-key: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} - - - name: "Start BrowserStackLocal Tunnel" - uses: "browserstack/github-actions/setup-local@master" - with: - local-testing: "start" - local-logging-level: "all-logs" - local-identifier: "random" - - - uses: actions/checkout@v3 - with: - ref: ${{ github.head_ref }} - set-safe-directory: "/github/workspace" - - - name: Prettier Action on PR - uses: creyD/prettier_action@v4.3 - with: - prettier_options: "--write {**/*,*}.{js,hbs,html,json,md,yml,css,scss} !.github/workflows/**/* !dist/**/*" - commit_message: "Run prettier via GitHub Action" - file_pattern: "." - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - - name: Run npm ci - run: sudo npm ci - - - name: Run npm test with BrowserStack Local - run: npm run build && node ./test/index.js - env: - CI: true - NODE_ENV: test - DEBUG: false - LOCATION: ${{ secrets.LOCATION }} - BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} - BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} - - - name: "Stop BrowserStackLocal" - uses: "browserstack/github-actions/setup-local@master" - with: - local-testing: "stop" diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml new file mode 100644 index 00000000..27ff514b --- /dev/null +++ b/.github/workflows/testing.yml @@ -0,0 +1,133 @@ +name: Testing Suite + +on: + pull_request: + types: [opened, synchronize] + push: + branches: + - main + workflow_dispatch: + +env: + NODE_VERSION: 22.16 + +jobs: + linting: + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + + steps: + - uses: actions/checkout@v4 + + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Run npm ci + run: npm ci + + - name: Run npm prettier + continue-on-error: true + run: | + ./node_modules/.bin/prettier --check . || echo "::warning::Prettier found formatting issues. Fix it locally by running './node_modules/.bin/prettier --write .'" + + - name: Run ESLint + run: ./node_modules/.bin/eslint --ext .js . + + unit-tests: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Run npm ci + run: npm ci + + - name: Build project + run: npm run build + + - name: Run unit tests + run: npm run test:unit + env: + CI: true + NODE_ENV: test + + build: + runs-on: ubuntu-latest + needs: unit-tests + if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || github.event_name == 'workflow_dispatch' + + steps: + - uses: actions/checkout@v4 + + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Run npm ci + run: npm ci + + - name: Build project + run: npm run build + + - name: Commit build changes + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add dist/ + git diff --staged --quiet || git commit -m "Update build artifacts [skip ci]" + git push + + browserstack: + runs-on: ubuntu-latest + needs: [unit-tests, linting, build] + if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || github.event_name == 'workflow_dispatch' + + steps: + - name: "BrowserStack Env Setup" + uses: "browserstack/github-actions/setup-env@master" + with: + username: ${{ secrets.BROWSERSTACK_USERNAME }} + access-key: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} + + - name: "Start BrowserStackLocal Tunnel" + uses: "browserstack/github-actions/setup-local@master" + with: + local-testing: "start" + local-logging-level: "all-logs" + local-identifier: "random" + + - uses: actions/checkout@v4 + + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Run npm ci + run: npm ci + + - name: Build project + run: npm run build + + - name: Run BrowserStack tests + run: node ./test/index.js + env: + CI: true + NODE_ENV: test + DEBUG: false + LOCATION: ${{ secrets.LOCATION }} + BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} + BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} + + - name: "Stop BrowserStackLocal" + uses: "browserstack/github-actions/setup-local@master" + with: + local-testing: "stop" diff --git a/.nvmrc b/.nvmrc index d4b25d08..f2a2bc61 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16.16 +22.16 diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 00000000..757fd64c --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "trailingComma": "es5" +} diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..57a07594 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,21 @@ +# Agent Instructions + +This repository contains the public scripts for Simple Analytics. When making changes keep the following points in mind. + +## Development + +- Use **Node.js 22.16** (see `.nvmrc`). +- Run `npm run build` to compile the scripts. This generates the files in `dist/` which should be committed. +- Format code with Prettier before committing. You can run `npx prettier -w .` or validate with `npm run prettier`. + +## Testing + +- Execute `npm run test:unit` to run the unit tests +- When adding a new feature or fixing a bug, please add a test. +- For every change, run `npm run build` to ensure the test uses the latest compiled version. +- Ignore most files in the `dist/` directory when checking for diffs, just check `dist/latest/latest.dev.js` and `dist/latest/auto-events.js` (whichever is relevant). +- Only tests in `test/unit/` are relevant for the AI and agents (it can run without internet access). + +## References + +Most work happens in `src/` with `compile.js` creating the distributable versions. Read `README.md` for more details about contributing and running scripts locally. diff --git a/README.md b/README.md index e2d265fe..aeff5a37 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,10 @@ Just run `npm run watch` and every file will be validated and compiled on save. The most important file of the repository is [`/src/default.js`](src/default.js) +## Unit tests + +Run `npm run test:unit` to execute a small set of tests without BrowserStack. + ## Device testing is sponsored by BrowserStack We run our public script with more than [50 browsers on many different (real) devices](https://github.com/simpleanalytics/scripts/blob/main/test/helpers/get-browsers.js). We support Internet Explorer 9 (not sure who is still using that) and up. Including many mobile browsers and less common devices. We get amazing sponsorship from [BrowserStack](https://www.browserstack.com/). Thanks, BrowserStack! diff --git a/compile.js b/compile.js index 52f4bbf1..1a8f2caf 100644 --- a/compile.js +++ b/compile.js @@ -3,12 +3,13 @@ const UglifyJS = require("uglify-js"); const fs = require("fs"); const esprima = require("esprima"); const path = require("path"); +const acorn = require("acorn"); const GREEN = "\x1b[32m%s\x1b[0m"; const YELLOW = "\x1b[33m%s\x1b[0m"; const RED = "\x1b[31m%s\x1b[0m"; -const VERSION = 11; +const VERSION = 12; Handlebars.registerHelper("or", function (param1, param2) { return param1 || param2; @@ -320,7 +321,7 @@ for (const file of files) { .digest("hex") .slice(0, 4); - const prepend = `/* Simple Analytics - Privacy friendly analytics (docs.simpleanalytics.com/script; ${date}; ${hash}${ + const prepend = `/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; ${date}; ${hash}${ variables.sri ? `; SRI-version` : "" }${variables.version ? `; v${variables.version}` : ""}) */\n`; @@ -358,6 +359,31 @@ for (const file of files) { for (const warning of warnings || []) console.warn(YELLOW, `[${name}] ${warning}`); + try { + acorn.parse(rawCode, { ecmaVersion: 5 }); + } catch (error) { + // console.log("acorn", error); + + // error object: + // pos: 147, + // loc: Position { line: 12, column: 0 }, + // raisedAt: 148 + + // Find part of the code that is causing the error + const lines = rawCode.split("\n"); + const line = error.loc.line; + const column = error.loc.column; + const start = Math.max(0, line - 3); + const end = Math.min(lines.length, line + 3); + const codeSnippet = lines.slice(start, end).join("\n"); + const sentence = lines[error.loc.line - 1]; + + // console.log({ codeSnippet, line: lines[error.loc.line - 1] }); + + throw new Error( + `${error.message} at line ${sentence} position ${column}: ${codeSnippet}` + ); + } const code = fillTemplate(codeTemplate, variables); const validate = template({ diff --git a/dist/latest/auto-events.js b/dist/latest/auto-events.js index df23dcae..d3657139 100644 --- a/dist/latest/auto-events.js +++ b/dist/latest/auto-events.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy friendly analytics (docs.simpleanalytics.com/script; 2023-05-03; 19c1; v11) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; 7048; v12) */ -function r(t,e){var a,o=!1;h.downloads&&/^https?:\/\//i.test(t.href)&&new RegExp("\\.("+(h.downloadsExtensions||[]).join("|")+")$","i").test(t.pathname)?o="download":h.outbound&&/^https?:\/\//i.test(t.href)&&t.hostname!==m.location.hostname?o="outbound":h.emails&&/^mailto:/i.test(t.href)&&(o="email"),o&&(e?(a="saAutomatedLink(this, '"+o+"');",t.hasAttribute("target")&&"_self"!==t.getAttribute("target")||(a+=" return false;"),t.setAttribute("onclick",a)):t.addEventListener("click",function(t){saAutomatedLink(t.target,o)}))}function e(){try{for(var t=document.getElementsByTagName("a"),e=0;e -1,\n emails: collectTypes.indexOf(\"emails\") > -1,\n downloads: collectTypes.indexOf(\"downloads\") > -1,\n // Downloads: enter file extensions you want to collect\n downloadsExtensions: setting(\"extensions\", \"array\", [\n \"pdf\",\n \"csv\",\n \"docx\",\n \"xlsx\",\n \"zip\",\n \"doc\",\n \"xls\",\n ]),\n\n // All: use title attribute if set for event name (for all events)\n // THIS TAKES PRECEDENCE OVER OTHER SETTINGS BELOW\n title: setting(\"useTitle\", \"bool\", true),\n // Outbound: use full URL of the links? false for just the hostname\n outboundFullUrl: fullUrls,\n // Downloads: if taking event name from URL, use full URL or just filename (default)\n downloadsFullUrl: fullUrls,\n };\n\n var saGlobal = setting(\"saGlobal\", \"string\", \"sa_event\");\n\n // For compiling the script\n var optionsLink = options;\n\n if (typeof optionsLink === \"undefined\")\n log(\"options object not found, please specify\", \"warn\");\n\n window.saAutomatedLink = function saAutomatedLink(element, type) {\n try {\n if (!element) return log(\"no element found\");\n var sent = false;\n\n var callback = function () {\n if (!sent && !element.hasAttribute(\"target\"))\n document.location = element.getAttribute(\"href\");\n sent = true;\n };\n\n if (window[saGlobal] && window[saGlobal + \"_loaded\"]) {\n var hostname = element.hostname;\n var pathname = element.pathname;\n\n var event;\n var metadata = {\n title: element.getAttribute(\"title\") || undefined,\n };\n var url = element.href || undefined;\n\n var useTitle = false;\n if (optionsLink.title && element.hasAttribute(\"title\")) {\n var theTitle = element.getAttribute(\"title\").trim();\n if (theTitle != \"\") useTitle = true;\n }\n\n if (useTitle) {\n event = theTitle;\n } else {\n switch (type) {\n case \"outbound\": {\n event = hostname + (optionsLink.outboundFullUrl ? pathname : \"\");\n metadata.url = url;\n break;\n }\n case \"download\": {\n event = optionsLink.downloadsFullUrl\n ? hostname + pathname\n : pathname.split(\"/\").pop();\n metadata.url = url;\n break;\n }\n case \"email\": {\n var href = element.getAttribute(\"href\");\n event = (href.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.email = event;\n break;\n }\n }\n }\n\n var clean =\n type +\n \"_\" +\n event.replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_+|_+$)/g, \"\");\n\n window[saGlobal](clean, metadata, callback);\n\n log(\"collected \" + clean);\n\n return type === \"email\"\n ? callback()\n : window.setTimeout(callback, 5000);\n } else {\n log(saGlobal + \" is not defined\", \"warn\");\n return callback();\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n };\n\n function collectLink(link, onclick) {\n var collect = false;\n\n // Collect download clicks\n if (\n optionsLink.downloads &&\n /^https?:\\/\\//i.test(link.href) &&\n new RegExp(\n \"\\\\.(\" + (optionsLink.downloadsExtensions || []).join(\"|\") + \")$\",\n \"i\"\n ).test(link.pathname)\n ) {\n collect = \"download\";\n\n // Collect outbound links clicks\n } else if (\n optionsLink.outbound &&\n /^https?:\\/\\//i.test(link.href) &&\n link.hostname !== window.location.hostname\n ) {\n collect = \"outbound\";\n\n // Collect email clicks\n } else if (optionsLink.emails && /^mailto:/i.test(link.href)) {\n collect = \"email\";\n }\n\n if (!collect) return;\n\n if (onclick) {\n var onClickAttribute = \"saAutomatedLink(this, '\" + collect + \"');\";\n\n if (\n !link.hasAttribute(\"target\") ||\n link.getAttribute(\"target\") === \"_self\"\n )\n onClickAttribute += \" return false;\";\n\n link.setAttribute(\"onclick\", onClickAttribute);\n } else {\n link.addEventListener(\"click\", function (element) {\n saAutomatedLink(element.target, collect);\n });\n }\n }\n\n function onDOMContentLoaded() {\n try {\n var a = document.getElementsByTagName(\"a\");\n\n // Loop over all links on the page\n for (var i = 0; i < a.length; i++) {\n var link = a[i];\n var href = link.getAttribute(\"href\");\n\n // Skip links that don't have an href\n if (!href) continue;\n\n // We don't want to overwrite website behaviour so we check for the onclick attribute\n if (!link.getAttribute(\"onclick\") && !/^mailto:/.test(href)) {\n collectLink(link, true);\n } else {\n collectLink(link, false);\n }\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n }\n\n if (doc.readyState === \"ready\" || doc.readyState === \"complete\") {\n onDOMContentLoaded();\n } else {\n document.addEventListener(\"readystatechange\", function (event) {\n if (event.target.readyState === \"complete\") onDOMContentLoaded();\n });\n }\n})(window);\n"],"names":["collectLink","link","onclick","onClickAttribute","collect","optionsLink","downloads","test","href","RegExp","downloadsExtensions","join","pathname","outbound","hostname","window","location","emails","hasAttribute","getAttribute","setAttribute","addEventListener","element","saAutomatedLink","target","onDOMContentLoaded","a","document","getElementsByTagName","i","length","error","log","message","doc","scriptElement","setting","collectTypes","fullUrls","options","saGlobal","type","logger","console","warn","info","currentScript","querySelector","attribute","defaultValue","value","dataset","split","map","item","trim","filter","Boolean","indexOf","title","outboundFullUrl","downloadsFullUrl","sent","callback","theTitle","metadata","undefined","url","useTitle","event","pop","email","clean","replace","setTimeout","readyState"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"auto-events.source.js","sources":["auto-events.source.js"],"sourcesContent":["(function saAutomatedEvents(window) {\n // Skip server side rendered pages\n if (typeof window === \"undefined\") return;\n\n var log = function (message, type) {\n var logger = type === \"warn\" ? console.warn : console.info;\n return logger && logger(\"Simple Analytics auto events:\", message);\n };\n\n var doc = window.document;\n\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"auto-events.js\"]');\n\n var setting = function (attribute, type, defaultValue) {\n var value = scriptElement && scriptElement.dataset[attribute];\n\n // Booleans\n if (type === \"bool\" && (value === \"true\" || value === \"false\"))\n return value === \"true\";\n else if (type === \"bool\") return defaultValue;\n\n // Arrays\n if (type === \"array\" && value)\n return value\n .split(\",\")\n .map(function (item) {\n return item.trim();\n })\n .filter(Boolean);\n else if (type === \"array\") return defaultValue;\n\n return value || defaultValue;\n };\n\n var collectTypes = setting(\"collect\", \"array\", [\n \"outbound\",\n \"emails\",\n \"downloads\",\n ]);\n var fullUrls = setting(\"fullUrls\", \"bool\", false);\n\n var options = {\n // What to collect\n outbound: collectTypes.indexOf(\"outbound\") > -1,\n emails: collectTypes.indexOf(\"emails\") > -1,\n downloads: collectTypes.indexOf(\"downloads\") > -1,\n // Downloads: enter file extensions you want to collect\n downloadsExtensions: setting(\"extensions\", \"array\", [\n \"pdf\",\n \"csv\",\n \"docx\",\n \"xlsx\",\n \"zip\",\n \"doc\",\n \"xls\",\n ]),\n\n // All: use title attribute if set for event name (for all events)\n // THIS TAKES PRECEDENCE OVER OTHER SETTINGS BELOW\n title: setting(\"useTitle\", \"bool\", true),\n // Outbound: use full URL of the links? false for just the hostname\n outboundFullUrl: fullUrls,\n // Downloads: if taking event name from URL, use full URL or just filename (default)\n downloadsFullUrl: fullUrls,\n };\n\n var saGlobal = setting(\"saGlobal\", \"string\", \"sa_event\");\n\n // For compiling the script\n var optionsLink = options;\n\n if (typeof optionsLink === \"undefined\")\n log(\"options object not found, please specify\", \"warn\");\n\n var saAutomatedLink = function saAutomatedLink(element, type) {\n try {\n if (!element) return log(\"no element found\");\n var sent = false;\n\n var callback = function () {\n if (!sent && !element.hasAttribute(\"target\"))\n document.location = element.getAttribute(\"href\");\n sent = true;\n };\n\n if (window[saGlobal] && window[saGlobal + \"_loaded\"]) {\n var hostname = element.hostname;\n var pathname = element.pathname;\n\n var event;\n var metadata = {\n title: element.getAttribute(\"title\") || undefined,\n };\n var url = element.href || undefined;\n\n var useTitle = false;\n if (optionsLink.title && element.hasAttribute(\"title\")) {\n var theTitle = element.getAttribute(\"title\").trim();\n if (theTitle != \"\") useTitle = true;\n }\n\n if (useTitle) {\n event = theTitle;\n } else {\n switch (type) {\n case \"outbound\": {\n event = hostname + (optionsLink.outboundFullUrl ? pathname : \"\");\n metadata.url = url;\n break;\n }\n case \"download\": {\n event = optionsLink.downloadsFullUrl\n ? hostname + pathname\n : pathname.split(\"/\").pop();\n metadata.url = url;\n break;\n }\n case \"email\": {\n var href = element.getAttribute(\"href\");\n event = (href.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.email = event;\n break;\n }\n }\n }\n\n var clean =\n type +\n \"_\" +\n event.replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_+|_+$)/g, \"\");\n\n window[saGlobal](clean, metadata, callback);\n\n log(\"collected \" + clean);\n\n return type === \"email\"\n ? callback()\n : window.setTimeout(callback, 5000);\n } else {\n log(saGlobal + \" is not defined\", \"warn\");\n return callback();\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n };\n\n window.saAutomatedLink = saAutomatedLink;\n\n function collectLink(link, onclick) {\n if (link.hasAttribute(\"data-simple-event\")) return;\n var collect = false;\n\n // Collect download clicks\n if (\n optionsLink.downloads &&\n /^https?:\\/\\//i.test(link.href) &&\n new RegExp(\n \"\\\\.(\" + (optionsLink.downloadsExtensions || []).join(\"|\") + \")$\",\n \"i\"\n ).test(link.pathname)\n ) {\n collect = \"download\";\n\n // Collect outbound links clicks\n } else if (\n optionsLink.outbound &&\n /^https?:\\/\\//i.test(link.href) &&\n link.hostname !== window.location.hostname\n ) {\n collect = \"outbound\";\n\n // Collect email clicks\n } else if (optionsLink.emails && /^mailto:/i.test(link.href)) {\n collect = \"email\";\n }\n\n if (!collect) return;\n\n if (onclick) {\n var onClickAttribute = \"saAutomatedLink(this, '\" + collect + \"');\";\n\n if (\n !link.hasAttribute(\"target\") ||\n link.getAttribute(\"target\") === \"_self\"\n )\n onClickAttribute += \" return false;\";\n\n link.setAttribute(\"onclick\", onClickAttribute);\n } else {\n link.addEventListener(\"click\", function () {\n saAutomatedLink(link, collect);\n });\n }\n }\n\n function onDOMContentLoaded() {\n try {\n var a = document.getElementsByTagName(\"a\");\n\n // Loop over all links on the page\n for (var i = 0; i < a.length; i++) {\n var link = a[i];\n var href = link.getAttribute(\"href\");\n\n // Skip links that don't have an href\n if (!href) continue;\n\n // We don't want to overwrite website behaviour so we check for the onclick attribute\n if (!link.getAttribute(\"onclick\") && !/^mailto:/.test(href)) {\n collectLink(link, true);\n } else {\n collectLink(link, false);\n }\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n }\n\n if (doc.readyState === \"ready\" || doc.readyState === \"complete\") {\n onDOMContentLoaded();\n } else {\n document.addEventListener(\"readystatechange\", function (event) {\n if (event.target.readyState === \"complete\") onDOMContentLoaded();\n });\n }\n})(window);\n"],"names":["collectLink","link","onclick","collect","onClickAttribute","hasAttribute","optionsLink","downloads","test","href","RegExp","downloadsExtensions","join","pathname","outbound","hostname","window","location","emails","getAttribute","setAttribute","addEventListener","saAutomatedLink","onDOMContentLoaded","a","document","getElementsByTagName","i","length","error","log","message","doc","scriptElement","setting","collectTypes","fullUrls","options","saGlobal","type","logger","console","warn","info","currentScript","querySelector","attribute","defaultValue","value","dataset","split","map","item","trim","filter","Boolean","indexOf","title","outboundFullUrl","downloadsFullUrl","element","sent","callback","theTitle","metadata","undefined","url","useTitle","event","pop","email","clean","replace","setTimeout","readyState","target"],"mappings":"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"} \ No newline at end of file diff --git a/dist/latest/cloudflare.js b/dist/latest/cloudflare.js index 9142e785..e036bbea 100644 --- a/dist/latest/cloudflare.js +++ b/dist/latest/cloudflare.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy friendly analytics (docs.simpleanalytics.com/script; 2023-05-03; 0dec; v11) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; 3257; v12) */ /* eslint-env browser */ (function ( @@ -112,8 +112,8 @@ return Array.isArray(csv) ? csv : isString(csv) && csv.length - ? csv.split(/, ?/) - : []; + ? csv.split(/, ?/) + : []; }; var isObject = function (object) { @@ -193,11 +193,17 @@ attr(scriptElement, namespaceText) || defaultNamespace; - var metadataObject = window[namespace + "_metadata"]; var appendMetadata = function (metadata, data) { + var metadataObject = window[namespace + "_metadata"]; if (isObject(metadataObject)) metadata = assign(metadata, metadataObject); var metadataCollectorFunction = window[metadataCollector]; - if (!isFunction(metadataCollectorFunction)) return metadata; + if (!isFunction(metadataCollectorFunction)) { + if (metadataCollector) + warn( + metadataCollector + " not found, set window." + metadataCollector + ); + return metadata; + } try { return assign( metadata, @@ -218,9 +224,9 @@ overwriteOptions.strictUtm || attr(scriptElement, "strict-utm") == trueText; - var getQueryParams = function (ignoreSource) { + var getQueryParams = function (ignoreSource, overwriteSearch) { return ( - loc.search + (overwriteSearch || loc.search) .slice(1) .split("&") .filter(function (keyValue) { @@ -433,12 +439,13 @@ // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS // + var phantom = window.phantom; var bot = nav.webdriver || window.__nightmare || window.callPhantom || window._phantom || - window.phantom || + (phantom && !phantom.solana) || window.__polypane || window._bot || isBotAgent || @@ -512,8 +519,12 @@ var lastSendPath; var getReferrer = function () { + // Customers can overwrite their referrer, here we check for that + var overwrittenReferrer = + overwriteOptions.referrer || attr(scriptElement, "referrer"); + return ( - (doc.referrer || "") + (overwrittenReferrer || doc.referrer || "") .replace(locationHostname, definedHostname) .replace(/^https?:\/\/((m|l|w{2,3}([0-9]+)?)\.)?([^?#]+)(.*)$/, "$4") .replace(/^([^/]+)$/, "$1") || undefinedVar @@ -554,7 +565,12 @@ // sendData will assign payload to request sendData(append, undefinedVar, trueVar); } else { - nav.sendBeacon(fullApiUrl + "/append", stringify(append)); + try { + nav.sendBeacon.bind(nav)(fullApiUrl + "/append", stringify(append)); + } catch (e) { + // Fallback for browsers throwing "Illegal invocation" when the URL is invalid + sendData(append, undefinedVar, trueVar); + } } }; @@ -651,21 +667,26 @@ isPushState, deleteSourceInfo, sameSite, - metadata + query, + metadata, + callback ) { if (isPushState) sendOnLeave("" + payload.page_id, trueVar); if (collectDataOnLeave) payload.page_id = uuid(); var currentPage = definedHostname + getPath(); - sendData({ - id: payload.page_id, - type: pageviewText, - referrer: !deleteSourceInfo || sameSite ? referrer : null, - query: getQueryParams(deleteSourceInfo), + sendData( + { + id: payload.page_id, + type: pageviewText, + referrer: !deleteSourceInfo || sameSite ? referrer : null, + query: query || getQueryParams(deleteSourceInfo), - metadata: stringify(metadata), - }); + metadata: stringify(metadata), + }, + callback + ); previousReferrer = referrer; referrer = currentPage; @@ -675,7 +696,21 @@ var sameSite, userNavigated; - var pageview = function (isPushState, pathOverwrite, metadata) { + var pageview = function ( + isPushState, + pathOverwrite, + metadata, + callbackRaw + ) { + if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata; + var callback = isFunction(callbackRaw) ? callbackRaw : function () {}; + var querySearch; + if (isString(pathOverwrite) && pathOverwrite.indexOf("?") > -1) { + // keep query from manual path + var parts = pathOverwrite.split("?"); + pathOverwrite = parts.shift(); + querySearch = "?" + parts.join("?"); + } // Obfuscate personal data in URL by dropping the search and hash var path = getPath(pathOverwrite); @@ -738,7 +773,10 @@ : falseVar; // We set unique variable based on pushstate or back navigation, if no match we check the referrer - page.unique = isPushState || userNavigated ? falseVar : !sameSite; + page.unique = + /__cf_/.test(getReferrer()) || isPushState || userNavigated + ? falseVar + : !sameSite; metadata = appendMetadata(metadata, { type: pageviewText, @@ -747,11 +785,15 @@ var triggerSendPageView = function () { fetchedHighEntropyValues = trueVar; + var delSrc = + isPushState || userNavigated || !collectMetricByString("r"); sendPageView( isPushState, - isPushState || userNavigated || !collectMetricByString("r"), // r = referrers + delSrc, // r = referrers sameSite, - metadata + querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar, + metadata, + callback ); }; @@ -841,11 +883,11 @@ } if (autoCollect) pageview(); - else { - window.sa_pageview = function (path, metadata) { - pageview(0, path, metadata); - }; - } + + window.sa_pageview = function (path, metadata, callback) { + pageview(0, path, metadata, callback); + }; + ///////////////////// // EVENTS @@ -938,6 +980,6 @@ {"hostname":INSTALL_OPTIONS.hostname,"collectDnt":typeof INSTALL_OPTIONS.collect_dnt === 'boolean' ? INSTALL_OPTIONS.collect_dnt : null,"mode":INSTALL_OPTIONS.hash_mode ? 'hash' : 'normal',"strictUtm":INSTALL_OPTIONS.advanced_settings_toggle && INSTALL_OPTIONS.strict_utm,"allowParams":INSTALL_OPTIONS.advanced_settings_toggle && INSTALL_OPTIONS.allow_url_parameters,"nonUniqueHostnames":INSTALL_OPTIONS.advanced_settings_toggle && INSTALL_OPTIONS.non_unique_hostnames,"ignorePages":INSTALL_OPTIONS.advanced_settings_toggle && INSTALL_OPTIONS.ignore_pages,"namespace":INSTALL_OPTIONS.overwrite_namespace && INSTALL_OPTIONS.namespace}, INSTALL_OPTIONS.custom_domain || "queue.simpleanalyticscdn.com", "", - "cloudflare_11", + "cloudflare_12", "sa" ); diff --git a/dist/latest/custom/app.js b/dist/latest/custom/app.js index a3febd38..b0fc1b1e 100644 --- a/dist/latest/custom/app.js +++ b/dist/latest/custom/app.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy friendly analytics (docs.simpleanalytics.com/script; 2023-05-03; 527b; v11) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; b78b; v12) */ -!function(l,t,e,n,p){try{var h=undefined,f=!0,d=!1,r="true",a="https:",m="pageview",u="event",i="error",o=l.console,c="doNotTrack",g=l.navigator,s=l.location,v=s.host,y=l.document,_=g.userAgent,w="Not sending request ",b=w+"when ",E=d,O=encodeURIComponent,x=decodeURIComponent,S=JSON.stringify,M=l.addEventListener,k="https://"+e,A=y.documentElement||{},q="language",$="Height",j="scroll",D=g.userAgentData,C=j+$,H="offset"+$,R="client"+$,P="pagehide",T="platform",U="platformVersion",I="https://docs.simpleanalytics.com",V=0,B=/(bot|spider|crawl)/i.test(_)&&!/(cubot)/i.test(_),N=l.screen,z=y.currentScript||y.querySelector('script[src*="'+e+'"]');p=function(){var t=[].slice.call(arguments);return t.unshift("Simple Analytics:"),Function.prototype.apply.call(o.warn,o,t)};var F=function(t,e){p("Error in your "+t+" function:",e)},W=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},G=function(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},J=function(t,e){return t&&t.getAttribute("data-"+e)},L=function(t){return Array.isArray(t)?t:"string"==typeof t&&t.length?t.split(/, ?/):[]},Y=function(t){return t&&t.constructor===Object},Z=function(){for(var t={},e=arguments,n=0;n>t/4).toString(16)})}catch(r){return t.replace(n,function(t){var e=16*Math.random()|0;return(t<2?e:3&e|8).toString(16)})}},rt=function(t){return"function"==typeof t},at="namespace",it=t[at]||J(z,at)||"sa",ot=l[it+"_metadata"],ct=function(t,e){Y(ot)&&(t=Z(t,ot));var n=l[Mt];if(!rt(n))return t;try{return Z(t,n.call(l,Z(t,e)))}catch(r){F("metadata",r)}},st=t.strictUtm||J(z,"strict-utm")==r,ut=function(a){return s.search.slice(1).split("&").filter(function(t){var e=a||!tt("ut"),n=Ot.map(G).join("|"),r=e?"^("+n+")=":"^((utm_)"+(st?"":"?")+"(source|medium|content|term|campaign)"+(st?"":"|ref")+"|"+n+")=";return e&&!Ot.length?d:new RegExp(r).test(t)}).join("&")||h},lt=it+"_loaded";if(l[lt]==f)return p(w+"twice");l.sa_event_loaded=f,l[lt]=f;var pt=function(e,t,n){e=n?e:Z(qt,Dt,e),g.brave&&!n&&(e.brave=f),g._duckduckgoloader_&&!n&&(e.duck=f);var r=new Image;t&&(r.onerror=t,r.onload=t),r.src=k+"/simple.gif?"+Object.keys(e).filter(function(t){return e[t]!=h}).map(function(t){return O(t)+"="+O(e[t])}).join("&")+"&time="+Date.now()},ht=t.hostname||J(z,"hostname"),ft=ht||v,dt={version:"custom_app_11",hostname:ft};n=function(t){t=t.stack?t+" "+t.stack:t,p(t),pt(Z(dt,{type:i,error:t,path:s.pathname}),h,f)},M(i,function(t){t.filename&&-1"); +!function(d,t,e,n,m){try{var g=undefined,v=!0,y=!1,r="true",a="https:",_="pageview",u="event",i="error",o=d.console,c="doNotTrack",w=d.navigator,s=d.location,b=s.host,l=d.document,p=w.userAgent,f="Not sending request ",h=f+"when ",O=y,E=encodeURIComponent,x=decodeURIComponent,S=JSON.stringify,M=d.addEventListener,k="https://"+e,A=l.documentElement||{},q="language",$="Height",j="scroll",D=w.userAgentData,C=j+$,H="offset"+$,R="client"+$,P="pagehide",T="platform",U="platformVersion",I="https://docs.simpleanalytics.com",V=0,B=/(bot|spider|crawl)/i.test(p)&&!/(cubot)/i.test(p),N=d.screen,z=l.currentScript||l.querySelector('script[src*="'+e+'"]');m=function(){var t=[].slice.call(arguments);return t.unshift("Simple Analytics:"),Function.prototype.apply.call(o.warn,o,t)};var F=function(t,e){m("Error in your "+t+" function:",e)},W=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},G=function(t){return"string"==typeof t},J=function(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},L=function(t,e){return t&&t.getAttribute("data-"+e)},Y=function(t){return Array.isArray(t)?t:G(t)&&t.length?t.split(/, ?/):[]},Z=function(t){return t&&t.constructor===Object},K=function(){for(var t={},e=arguments,n=0;n>t/4).toString(16)})}catch(r){return t.replace(n,function(t){var e=16*Math.random()|0;return(t<2?e:3&e|8).toString(16)})}},at=function(t){return"function"==typeof t},it="namespace",ot=t[it]||L(z,it)||"sa",ct=function(t,e){var n=d[ot+"_metadata"];Z(n)&&(t=K(t,n));var r=d[Mt];if(!at(r))return Mt&&m(Mt+" not found, set window."+Mt),t;try{return K(t,r.call(d,K(t,e)))}catch(a){F("metadata",a)}},st=t.strictUtm||L(z,"strict-utm")==r,ut=function(a,t){return(t||s.search).slice(1).split("&").filter(function(t){var e=a||!et("ut"),n=Et.map(J).join("|"),r=e?"^("+n+")=":"^((utm_)"+(st?"":"?")+"(source|medium|content|term|campaign)"+(st?"":"|ref")+"|"+n+")=";return e&&!Et.length?y:new RegExp(r).test(t)}).join("&")||g},lt=ot+"_loaded";if(d[lt]==v)return m(f+"twice");d.sa_event_loaded=v,d[lt]=v;var pt=function(e,t,n){e=n?e:K($t,Ct,e),w.brave&&!n&&(e.brave=v),w._duckduckgoloader_&&!n&&(e.duck=v);var r=new Image;t&&(r.onerror=t,r.onload=t),r.src=k+"/simple.gif?"+Object.keys(e).filter(function(t){return e[t]!=g}).map(function(t){return E(t)+"="+E(e[t])}).join("&")+"&time="+Date.now()},ft=t.hostname||L(z,"hostname"),ht=ft||b,dt={version:"custom_app_12",hostname:ht};n=function(t){t=t.stack?t+" "+t.stack:t,m(t),pt(K(dt,{type:i,error:t,path:s.pathname}),g,v)},M(i,function(t){t.filename&&-1"); //# sourceMappingURL=app.js.map \ No newline at end of file diff --git a/dist/latest/custom/app.js.map b/dist/latest/custom/app.js.map index ea3f10aa..7cbc2558 100644 --- a/dist/latest/custom/app.js.map +++ b/dist/latest/custom/app.js.map @@ -1 +1 @@ -{"version":3,"file":"app.source.js","sources":["app.source.js"],"sourcesContent":["/* eslint-env browser */\n\n(function (\n window,\n overwriteOptions,\n baseUrl,\n apiUrlPrefix,\n version,\n defaultNamespace,\n sendError,\n warn\n) {\n try {\n /////////////////////\n // PREDEFINED VARIABLES FOR BETTER MINIFICATION\n //\n\n // This seems like a lot of repetition, but it makes our script available for\n // multple destination which prevents us to need multiple scripts. The minified\n // version stays small.\n var undefinedVar = undefined;\n var trueVar = true;\n var falseVar = false;\n var trueText = \"true\";\n var https = \"https:\";\n var pageviewText = \"pageview\";\n var eventText = \"event\";\n var errorText = \"error\";\n var slash = \"/\";\n var protocol = https + \"//\";\n var con = window.console;\n var doNotTrack = \"doNotTrack\";\n var nav = window.navigator;\n var loc = window.location;\n var locationHostname = loc.host;\n var doc = window.document;\n var userAgent = nav.userAgent;\n var notSending = \"Not sending request \";\n var notSendingWhen = notSending + \"when \";\n var fetchedHighEntropyValues = falseVar;\n var encodeURIComponentFunc = encodeURIComponent;\n var decodeURIComponentFunc = decodeURIComponent;\n var stringify = JSON.stringify;\n var thousand = 1000;\n var addEventListenerFunc = window.addEventListener;\n var fullApiUrl = protocol + apiUrlPrefix + baseUrl;\n var documentElement = doc.documentElement || {};\n var language = \"language\";\n var Height = \"Height\";\n var Width = \"Width\";\n var scroll = \"scroll\";\n var uaData = nav.userAgentData;\n var scrollHeight = scroll + Height;\n var offsetHeight = \"offset\" + Height;\n var clientHeight = \"client\" + Height;\n var clientWidth = \"client\" + Width;\n var pagehide = \"pagehide\";\n var platformText = \"platform\";\n var platformVersionText = \"platformVersion\";\n var docsUrl = \"https://docs.simpleanalytics.com\";\n var pages = 0;\n var isBotAgent =\n /(bot|spider|crawl)/i.test(userAgent) && !/(cubot)/i.test(userAgent);\n var screen = window.screen;\n\n\n // Find the script element where options can be set on\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"' + baseUrl + '\"]');\n\n /////////////////////\n // HELPER FUNCTIONS\n //\n\n // A simple log function so the user knows why a request is not being send\n warn = function () {\n // 1. Convert args to a normal array\n var args = [].slice.call(arguments);\n\n // 2. Prepend log prefix\n args.unshift(\"Simple Analytics:\");\n\n // 3. Pass along arguments to console.warn\n // Function.prototype.apply.call is needed for Internet Explorer\n return Function.prototype.apply.call(con.warn, con, args);\n };\n\n var warnInFunction = function (name, error) {\n warn(\"Error in your \" + name + \" function:\", error);\n };\n\n var hasProp = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n\n var isString = function (string) {\n return typeof string == \"string\";\n };\n\n var filterRegex = function (item) {\n return item.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n var attr = function (scriptElement, attribute) {\n return scriptElement && scriptElement.getAttribute(\"data-\" + attribute);\n };\n\n var convertCommaSeparatedToArray = function (csv) {\n return Array.isArray(csv)\n ? csv\n : isString(csv) && csv.length\n ? csv.split(/, ?/)\n : [];\n };\n\n var isObject = function (object) {\n return object && object.constructor === Object;\n };\n\n var assign = function () {\n var to = {};\n var arg = arguments;\n for (var index = 0; index < arg.length; index++) {\n var nextSource = arg[index];\n if (isObject(nextSource)) {\n for (var nextKey in nextSource) {\n if (hasProp(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n\n var settings = window.sa_settings;\n var logSettings = settings || Object.keys(overwriteOptions).length;\n\n // Merge overwriteOptions with sa_settings\n overwriteOptions = assign(overwriteOptions, settings);\n\n if (logSettings) warn(\"Settings\", overwriteOptions);\n\n // Customers can skip data points\n var ignoreMetrics = convertCommaSeparatedToArray(\n overwriteOptions.ignoreMetrics || attr(scriptElement, \"ignore-metrics\")\n );\n\n var collectMetricByString = function (metricAbbreviation) {\n // Can't use Array.find() here because we need to support IE9\n return (\n ignoreMetrics.filter(function (item) {\n return new RegExp(\"^\" + metricAbbreviation).test(item);\n }).length === 0\n );\n };\n\n var now = Date.now;\n\n var uuid = function () {\n var cryptoObject = window.crypto || window.msCrypto;\n var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;\n var uuidRegex = /[018]/g;\n\n try {\n return emptyUUID.replace(uuidRegex, function (c) {\n return (\n c ^\n (cryptoObject.getRandomValues(new Uint8Array(1))[0] &\n (15 >> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n var metadataObject = window[namespace + \"_metadata\"];\n var appendMetadata = function (metadata, data) {\n if (isObject(metadataObject)) metadata = assign(metadata, metadataObject);\n var metadataCollectorFunction = window[metadataCollector];\n if (!isFunction(metadataCollectorFunction)) return metadata;\n try {\n return assign(\n metadata,\n metadataCollectorFunction.call(window, assign(metadata, data))\n );\n } catch (error) {\n warnInFunction(\"metadata\", error);\n }\n };\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource) {\n return (\n loc.search\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n var paramsRegexList = allowParams.map(filterRegex).join(\"|\");\n var regex = ignore\n ? \"^(\" + paramsRegexList + \")=\"\n : \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \"|\" +\n paramsRegexList +\n \")=\";\n if (ignore && !allowParams.length) return falseVar;\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n // Ignore pages specified in data-ignore-pages\n var shouldIgnore = function (path) {\n for (var i in ignorePages) {\n var ignorePageRaw = ignorePages[i];\n if (!ignorePageRaw) continue;\n\n // Prepend a slash when it's missing\n var ignorePage =\n ignorePageRaw[0] == slash ? ignorePageRaw : slash + ignorePageRaw;\n\n if (\n ignorePage === path ||\n new RegExp(\n \"^\" + filterRegex(ignorePage).replace(/\\\\\\*/gi, \"(.*)\") + \"$\",\n \"i\"\n ).test(path)\n )\n return trueVar;\n }\n return falseVar;\n };\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n if (callback) {\n image.onerror = callback;\n image.onload = callback;\n }\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n /////////////////////\n // ERROR FUNCTIONS\n //\n\n // Send errors\n // no var because it's scoped outside of the try/catch\n sendError = function (errorOrMessage) {\n errorOrMessage = errorOrMessage.stack\n ? errorOrMessage + \" \" + errorOrMessage.stack\n : errorOrMessage;\n warn(errorOrMessage);\n sendData(\n assign(basePayload, {\n type: errorText,\n error: errorOrMessage,\n path: loc.pathname,\n }),\n undefinedVar,\n trueVar\n );\n };\n\n // We listen for the error events and only send errors that are\n // from our script (checked by filename) to our server.\n addEventListenerFunc(\n errorText,\n function (event) {\n if (event.filename && event.filename.indexOf(baseUrl) > -1) {\n sendError(event.message);\n }\n },\n falseVar\n );\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n var start = now();\n\n var scrolled = 0;\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n // Should we record Do Not Track visits?\n var collectDnt = isBoolean(overwriteOptions.collectDnt)\n ? overwriteOptions.collectDnt\n : attr(scriptElement, \"ignore-dnt\") == trueText ||\n attr(scriptElement, \"skip-dnt\") == trueText ||\n attr(scriptElement, \"collect-dnt\") == trueText;\n\n // Some customers want to collect page views manually\n var autoCollect = !(\n attr(scriptElement, \"auto-collect\") == \"false\" ||\n overwriteOptions.autoCollect === falseVar\n );\n\n // Event function name\n var eventFunctionName =\n overwriteOptions.saGlobal ||\n attr(scriptElement, \"sa-global\") ||\n namespace + \"_\" + eventText;\n\n // Customers can ignore certain pages\n var ignorePages = convertCommaSeparatedToArray(\n overwriteOptions.ignorePages || attr(scriptElement, \"ignore-pages\")\n );\n\n // Customers can allow params\n var allowParams = convertCommaSeparatedToArray(\n overwriteOptions.allowParams || attr(scriptElement, \"allow-params\")\n );\n\n // Customers can allow params\n var nonUniqueHostnames = convertCommaSeparatedToArray(\n overwriteOptions.nonUniqueHostnames ||\n attr(scriptElement, \"non-unique-hostnames\")\n );\n\n // Customers can overwrite certain values\n var pathOverwriter =\n overwriteOptions.pathOverwriter || attr(scriptElement, \"path-overwriter\");\n\n // Customers can add metadata to events and pageviews via a function\n var metadataCollector =\n overwriteOptions.metadataCollector ||\n attr(scriptElement, \"metadata-collector\");\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var bot =\n nav.webdriver ||\n window.__nightmare ||\n window.callPhantom ||\n window._phantom ||\n window.phantom ||\n window.__polypane ||\n window._bot ||\n isBotAgent ||\n Math.random() == Math.random();\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = falseVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n // Warn when no document.doctype is defined (this breaks some documentElement dimensions)\n if (!doc.doctype) warn(\"Add DOCTYPE html for accurate dimensions\");\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (!collectDnt && doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n return (\n (doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n // t = timeonpage\n if (collectMetricByString(\"t\")) {\n append.duration = Math.round((now() - start - msHidden) / thousand);\n }\n msHidden = 0;\n start = now();\n\n // scro = scrolled\n if (collectMetricByString(\"scro\")) {\n append.scrolled = Math.max(0, scrolled, position());\n }\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n nav.sendBeacon(fullApiUrl + \"/append\", stringify(append));\n }\n };\n\n var hiddenStart;\n addEventListenerFunc(\n \"visibilitychange\",\n function () {\n if (doc.hidden) {\n if (!(\"on\" + pagehide in window)) sendOnLeave();\n hiddenStart = now();\n } else msHidden += now() - hiddenStart;\n },\n falseVar\n );\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n var body = doc.body || {};\n var position = function () {\n try {\n var documentClientHeight = documentElement[clientHeight] || 0;\n var height = Math.max(\n body[scrollHeight] || 0,\n body[offsetHeight] || 0,\n documentElement[clientHeight] || 0,\n documentElement[scrollHeight] || 0,\n documentElement[offsetHeight] || 0\n );\n return Math.min(\n 100,\n Math.round(\n (100 * ((documentElement.scrollTop || 0) + documentClientHeight)) /\n height /\n 5\n ) * 5\n );\n } catch (error) {\n warn(error);\n return 0;\n }\n };\n\n addEventListenerFunc(\"load\", function () {\n scrolled = position();\n addEventListenerFunc(\n scroll,\n function () {\n if (scrolled < position()) scrolled = position();\n },\n falseVar\n );\n });\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n var pathOverwriterFunction = window[pathOverwriter];\n if (isFunction(pathOverwriterFunction)) {\n try {\n path = pathOverwriterFunction.call(window, { path: path }) || path;\n } catch (error) {\n warnInFunction(\"path\", error);\n }\n }\n\n // Ignore pages specified in data-ignore-pages\n if (shouldIgnore(path)) {\n warn(notSendingWhen + \"ignoring \" + path);\n return;\n }\n\n // Add hash to path when script is put in to hash mode\n if (mode == \"hash\" && loc.hash) path += loc.hash.split(\"?\")[0];\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n metadata\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData({\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: getQueryParams(deleteSourceInfo),\n\n metadata: stringify(metadata),\n });\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (isPushState, pathOverwrite, metadata) {\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n // v = viewportsizes\n if (collectMetricByString(\"v\")) {\n page.viewport_width =\n Math.max(documentElement[clientWidth] || 0, window.innerWidth || 0) ||\n null;\n page.viewport_height =\n Math.max(\n documentElement[clientHeight] || 0,\n window.innerHeight || 0\n ) || null;\n }\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n // sc = screensizes\n if (screen && collectMetricByString(\"sc\")) {\n page.screen_width = screen.width;\n page.screen_height = screen.height;\n }\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n var currentReferrerHostname = referrer\n ? referrer.split(slash)[0]\n : undefinedVar;\n sameSite = referrer\n ? nonUniqueHostnames.indexOf(currentReferrerHostname) > -1 ||\n currentReferrerHostname == locationHostname\n : falseVar;\n\n // We set unique variable based on pushstate or back navigation, if no match we check the referrer\n page.unique = isPushState || userNavigated ? falseVar : !sameSite;\n\n metadata = appendMetadata(metadata, {\n type: pageviewText,\n path: page.path,\n });\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n sendPageView(\n isPushState,\n isPushState || userNavigated || !collectMetricByString(\"r\"), // r = referrers\n sameSite,\n metadata\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n /////////////////////\n // AUTOMATED PAGE VIEW COLLECTION\n //\n\n var his = window.history;\n var hisPushState = his ? his.pushState : undefinedVar;\n var dis = window.dispatchEvent;\n var pushStateText = \"pushState\";\n\n // Overwrite history pushState function to\n // allow listening on the pushState event\n if (autoCollect && hisPushState && Event && dis) {\n var stateListener = function (type) {\n var orig = his[type];\n return function () {\n var arg = arguments;\n var rv = orig.apply(this, arg);\n var event;\n if (isFunction(Event)) {\n event = new Event(type);\n } else {\n // Fix for IE\n // https://github.com/simpleanalytics/scripts/issues/8\n event = doc.createEvent(\"Event\");\n event.initEvent(type, trueVar, trueVar);\n }\n event.arguments = arg;\n dis(event);\n return rv;\n };\n };\n\n his.pushState = stateListener(pushStateText);\n\n addEventListenerFunc(\n pushStateText,\n function () {\n pageview(1);\n },\n falseVar\n );\n\n addEventListenerFunc(\n \"popstate\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n // When in hash mode, we record a pageview based on the onhashchange function\n if (autoCollect && mode == \"hash\" && \"onhashchange\" in window) {\n addEventListenerFunc(\n \"hashchange\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n if (autoCollect) pageview();\n else {\n window.sa_pageview = function (path, metadata) {\n pageview(0, path, metadata);\n };\n }\n\n /////////////////////\n // EVENTS\n //\n\n var validTypes = [\"string\", \"number\"];\n\n var sendEvent = function (event, metadata, callbackRaw) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n\n var eventIsFunction = isFunction(event);\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var eventType = typeof event;\n\n if (validTypes.indexOf(eventType) < 0 && !eventIsFunction) {\n warnInFunction(eventFunctionName, eventText + \" can't be \" + eventType);\n return callback();\n }\n\n try {\n if (eventIsFunction) {\n var eventOutput = event();\n if (validTypes.indexOf(typeof eventOutput) < 0) {\n warnInFunction(\n eventFunctionName,\n event + \" returns no string: \" + eventOutput\n );\n return callback();\n }\n event = eventOutput;\n }\n } catch (error) {\n warnInFunction(eventFunctionName, error);\n return callback();\n }\n\n event = (\"\" + event).replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_|_$)/g, \"\");\n\n var eventParams = { type: eventText, event: event };\n var firstPage = !userNavigated && pages < 2;\n\n metadata = appendMetadata(metadata, eventParams);\n\n if (event) {\n sendData(\n assign(eventParams, {\n id: uuid(),\n query: getQueryParams(!firstPage),\n referrer:\n (firstPage || sameSite) && collectMetricByString(\"r\")\n ? previousReferrer\n : null,\n\n metadata: stringify(metadata),\n }),\n callback\n );\n }\n };\n\n var defaultEventFunc = function (event, metadata, callback) {\n sendEvent(event, metadata, callback);\n };\n\n // Set default function if user didn't define a function\n if (!window[eventFunctionName])\n window[eventFunctionName] = defaultEventFunc;\n\n var eventFunc = window[eventFunctionName];\n\n // Read queue of the user defined function\n var queue = eventFunc && eventFunc.q ? eventFunc.q : [];\n\n // Overwrite user defined function\n window[eventFunctionName] = defaultEventFunc;\n\n // Post events from the queue of the user defined function\n for (var event in queue) {\n if (hasProp(queue, event)) {\n Array.isArray(queue[event])\n ? sendEvent.apply(null, queue[event])\n : sendEvent(queue[event]);\n }\n }\n } catch (e) {\n sendError(e);\n }\n})(\n window,\n {},\n \"\",\n \"\",\n \"custom_app_11\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","sendError","warn","undefinedVar","undefined","trueVar","falseVar","trueText","https","pageviewText","eventText","errorText","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","notSendingWhen","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","documentElement","language","Height","scroll","uaData","userAgentData","scrollHeight","offsetHeight","clientHeight","pagehide","platformText","platformVersionText","docsUrl","pages","isBotAgent","test","screen","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","warnInFunction","name","error","hasProp","obj","prop","Object","hasOwnProperty","filterRegex","item","replace","attr","attribute","getAttribute","convertCommaSeparatedToArray","csv","Array","isArray","length","split","isObject","object","constructor","assign","to","arg","index","nextSource","nextKey","settings","sa_settings","logSettings","keys","ignoreMetrics","collectMetricByString","metricAbbreviation","filter","RegExp","now","Date","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","c","getRandomValues","Uint8Array","toString","r","Math","random","isFunction","func","namespaceText","namespace","metadataObject","appendMetadata","metadata","data","metadataCollectorFunction","metadataCollector","strictUtm","getQueryParams","ignoreSource","search","keyValue","ignore","paramsRegexList","allowParams","map","join","regex","loadedVariable","sa_event_loaded","sendData","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","image","Image","onerror","onload","src","key","overwrittenHostname","hostname","definedHostname","basePayload","version","errorOrMessage","stack","type","path","pathname","event","filename","indexOf","message","timezone","start","scrolled","mode","collectDnt","value","autoCollect","eventFunctionName","saGlobal","ignorePages","nonUniqueHostnames","pathOverwriter","Intl","DateTimeFormat","resolvedOptions","timeZone","bot","webdriver","__nightmare","callPhantom","_phantom","phantom","__polypane","_bot","collectDataOnLeave","ua","protocol","page_id","session_id","sri","mobile","brands","doctype","hostname_original","lastSendPath","hiddenStart","referrer","msHidden","sendOnLeave","id","push","append","original_id","duration","round","max","position","sendBeacon","hidden","body","documentClientHeight","height","min","scrollTop","previousReferrer","sameSite","userNavigated","getPath","overwrite","pathOverwriterFunction","i","ignorePageRaw","ignorePage","shouldIgnore","hash","pageview","isPushState","pathOverwrite","viewport_width","innerWidth","viewport_height","innerHeight","screen_width","width","screen_height","performaceEntryType","perf","performance","navigationText","getEntriesByType","currentReferrerHostname","unique","triggerSendPageView","deleteSourceInfo","currentPage","query","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","e","his","history","hisPushState","pushState","dis","dispatchEvent","pushStateText","Event","orig","rv","this","createEvent","initEvent","sa_pageview","validTypes","sendEvent","callbackRaw","eventIsFunction","eventType","eventOutput","eventParams","firstPage","defaultEventFunc","eventFunc","queue","q"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"app.source.js","sources":["app.source.js"],"sourcesContent":["/* eslint-env browser */\n\n(function (\n window,\n overwriteOptions,\n baseUrl,\n apiUrlPrefix,\n version,\n defaultNamespace,\n sendError,\n warn\n) {\n try {\n /////////////////////\n // PREDEFINED VARIABLES FOR BETTER MINIFICATION\n //\n\n // This seems like a lot of repetition, but it makes our script available for\n // multple destination which prevents us to need multiple scripts. The minified\n // version stays small.\n var undefinedVar = undefined;\n var trueVar = true;\n var falseVar = false;\n var trueText = \"true\";\n var https = \"https:\";\n var pageviewText = \"pageview\";\n var eventText = \"event\";\n var errorText = \"error\";\n var slash = \"/\";\n var protocol = https + \"//\";\n var con = window.console;\n var doNotTrack = \"doNotTrack\";\n var nav = window.navigator;\n var loc = window.location;\n var locationHostname = loc.host;\n var doc = window.document;\n var userAgent = nav.userAgent;\n var notSending = \"Not sending request \";\n var notSendingWhen = notSending + \"when \";\n var fetchedHighEntropyValues = falseVar;\n var encodeURIComponentFunc = encodeURIComponent;\n var decodeURIComponentFunc = decodeURIComponent;\n var stringify = JSON.stringify;\n var thousand = 1000;\n var addEventListenerFunc = window.addEventListener;\n var fullApiUrl = protocol + apiUrlPrefix + baseUrl;\n var documentElement = doc.documentElement || {};\n var language = \"language\";\n var Height = \"Height\";\n var Width = \"Width\";\n var scroll = \"scroll\";\n var uaData = nav.userAgentData;\n var scrollHeight = scroll + Height;\n var offsetHeight = \"offset\" + Height;\n var clientHeight = \"client\" + Height;\n var clientWidth = \"client\" + Width;\n var pagehide = \"pagehide\";\n var platformText = \"platform\";\n var platformVersionText = \"platformVersion\";\n var docsUrl = \"https://docs.simpleanalytics.com\";\n var pages = 0;\n var isBotAgent =\n /(bot|spider|crawl)/i.test(userAgent) && !/(cubot)/i.test(userAgent);\n var screen = window.screen;\n\n\n // Find the script element where options can be set on\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"' + baseUrl + '\"]');\n\n /////////////////////\n // HELPER FUNCTIONS\n //\n\n // A simple log function so the user knows why a request is not being send\n warn = function () {\n // 1. Convert args to a normal array\n var args = [].slice.call(arguments);\n\n // 2. Prepend log prefix\n args.unshift(\"Simple Analytics:\");\n\n // 3. Pass along arguments to console.warn\n // Function.prototype.apply.call is needed for Internet Explorer\n return Function.prototype.apply.call(con.warn, con, args);\n };\n\n var warnInFunction = function (name, error) {\n warn(\"Error in your \" + name + \" function:\", error);\n };\n\n var hasProp = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n\n var isString = function (string) {\n return typeof string == \"string\";\n };\n\n var filterRegex = function (item) {\n return item.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n var attr = function (scriptElement, attribute) {\n return scriptElement && scriptElement.getAttribute(\"data-\" + attribute);\n };\n\n var convertCommaSeparatedToArray = function (csv) {\n return Array.isArray(csv)\n ? csv\n : isString(csv) && csv.length\n ? csv.split(/, ?/)\n : [];\n };\n\n var isObject = function (object) {\n return object && object.constructor === Object;\n };\n\n var assign = function () {\n var to = {};\n var arg = arguments;\n for (var index = 0; index < arg.length; index++) {\n var nextSource = arg[index];\n if (isObject(nextSource)) {\n for (var nextKey in nextSource) {\n if (hasProp(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n\n var settings = window.sa_settings;\n var logSettings = settings || Object.keys(overwriteOptions).length;\n\n // Merge overwriteOptions with sa_settings\n overwriteOptions = assign(overwriteOptions, settings);\n\n if (logSettings) warn(\"Settings\", overwriteOptions);\n\n // Customers can skip data points\n var ignoreMetrics = convertCommaSeparatedToArray(\n overwriteOptions.ignoreMetrics || attr(scriptElement, \"ignore-metrics\")\n );\n\n var collectMetricByString = function (metricAbbreviation) {\n // Can't use Array.find() here because we need to support IE9\n return (\n ignoreMetrics.filter(function (item) {\n return new RegExp(\"^\" + metricAbbreviation).test(item);\n }).length === 0\n );\n };\n\n var now = Date.now;\n\n var uuid = function () {\n var cryptoObject = window.crypto || window.msCrypto;\n var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;\n var uuidRegex = /[018]/g;\n\n try {\n return emptyUUID.replace(uuidRegex, function (c) {\n return (\n c ^\n (cryptoObject.getRandomValues(new Uint8Array(1))[0] &\n (15 >> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n var appendMetadata = function (metadata, data) {\n var metadataObject = window[namespace + \"_metadata\"];\n if (isObject(metadataObject)) metadata = assign(metadata, metadataObject);\n var metadataCollectorFunction = window[metadataCollector];\n if (!isFunction(metadataCollectorFunction)) {\n if (metadataCollector)\n warn(\n metadataCollector + \" not found, set window.\" + metadataCollector\n );\n return metadata;\n }\n try {\n return assign(\n metadata,\n metadataCollectorFunction.call(window, assign(metadata, data))\n );\n } catch (error) {\n warnInFunction(\"metadata\", error);\n }\n };\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource, overwriteSearch) {\n return (\n (overwriteSearch || loc.search)\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n var paramsRegexList = allowParams.map(filterRegex).join(\"|\");\n var regex = ignore\n ? \"^(\" + paramsRegexList + \")=\"\n : \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \"|\" +\n paramsRegexList +\n \")=\";\n if (ignore && !allowParams.length) return falseVar;\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n // Ignore pages specified in data-ignore-pages\n var shouldIgnore = function (path) {\n for (var i in ignorePages) {\n var ignorePageRaw = ignorePages[i];\n if (!ignorePageRaw) continue;\n\n // Prepend a slash when it's missing\n var ignorePage =\n ignorePageRaw[0] == slash ? ignorePageRaw : slash + ignorePageRaw;\n\n if (\n ignorePage === path ||\n new RegExp(\n \"^\" + filterRegex(ignorePage).replace(/\\\\\\*/gi, \"(.*)\") + \"$\",\n \"i\"\n ).test(path)\n )\n return trueVar;\n }\n return falseVar;\n };\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n if (callback) {\n image.onerror = callback;\n image.onload = callback;\n }\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n /////////////////////\n // ERROR FUNCTIONS\n //\n\n // Send errors\n // no var because it's scoped outside of the try/catch\n sendError = function (errorOrMessage) {\n errorOrMessage = errorOrMessage.stack\n ? errorOrMessage + \" \" + errorOrMessage.stack\n : errorOrMessage;\n warn(errorOrMessage);\n sendData(\n assign(basePayload, {\n type: errorText,\n error: errorOrMessage,\n path: loc.pathname,\n }),\n undefinedVar,\n trueVar\n );\n };\n\n // We listen for the error events and only send errors that are\n // from our script (checked by filename) to our server.\n addEventListenerFunc(\n errorText,\n function (event) {\n if (event.filename && event.filename.indexOf(baseUrl) > -1) {\n sendError(event.message);\n }\n },\n falseVar\n );\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n var start = now();\n\n var scrolled = 0;\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n // Should we record Do Not Track visits?\n var collectDnt = isBoolean(overwriteOptions.collectDnt)\n ? overwriteOptions.collectDnt\n : attr(scriptElement, \"ignore-dnt\") == trueText ||\n attr(scriptElement, \"skip-dnt\") == trueText ||\n attr(scriptElement, \"collect-dnt\") == trueText;\n\n // Some customers want to collect page views manually\n var autoCollect = !(\n attr(scriptElement, \"auto-collect\") == \"false\" ||\n overwriteOptions.autoCollect === falseVar\n );\n\n // Event function name\n var eventFunctionName =\n overwriteOptions.saGlobal ||\n attr(scriptElement, \"sa-global\") ||\n namespace + \"_\" + eventText;\n\n // Customers can ignore certain pages\n var ignorePages = convertCommaSeparatedToArray(\n overwriteOptions.ignorePages || attr(scriptElement, \"ignore-pages\")\n );\n\n // Customers can allow params\n var allowParams = convertCommaSeparatedToArray(\n overwriteOptions.allowParams || attr(scriptElement, \"allow-params\")\n );\n\n // Customers can allow params\n var nonUniqueHostnames = convertCommaSeparatedToArray(\n overwriteOptions.nonUniqueHostnames ||\n attr(scriptElement, \"non-unique-hostnames\")\n );\n\n // Customers can overwrite certain values\n var pathOverwriter =\n overwriteOptions.pathOverwriter || attr(scriptElement, \"path-overwriter\");\n\n // Customers can add metadata to events and pageviews via a function\n var metadataCollector =\n overwriteOptions.metadataCollector ||\n attr(scriptElement, \"metadata-collector\");\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var phantom = window.phantom;\n var bot =\n nav.webdriver ||\n window.__nightmare ||\n window.callPhantom ||\n window._phantom ||\n (phantom && !phantom.solana) ||\n window.__polypane ||\n window._bot ||\n isBotAgent ||\n Math.random() == Math.random();\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = falseVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n // Warn when no document.doctype is defined (this breaks some documentElement dimensions)\n if (!doc.doctype) warn(\"Add DOCTYPE html for accurate dimensions\");\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (!collectDnt && doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n // Customers can overwrite their referrer, here we check for that\n var overwrittenReferrer =\n overwriteOptions.referrer || attr(scriptElement, \"referrer\");\n\n return (\n (overwrittenReferrer || doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n // t = timeonpage\n if (collectMetricByString(\"t\")) {\n append.duration = Math.round((now() - start - msHidden) / thousand);\n }\n msHidden = 0;\n start = now();\n\n // scro = scrolled\n if (collectMetricByString(\"scro\")) {\n append.scrolled = Math.max(0, scrolled, position());\n }\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n try {\n nav.sendBeacon.bind(nav)(fullApiUrl + \"/append\", stringify(append));\n } catch (e) {\n // Fallback for browsers throwing \"Illegal invocation\" when the URL is invalid\n sendData(append, undefinedVar, trueVar);\n }\n }\n };\n\n var hiddenStart;\n addEventListenerFunc(\n \"visibilitychange\",\n function () {\n if (doc.hidden) {\n if (!(\"on\" + pagehide in window)) sendOnLeave();\n hiddenStart = now();\n } else msHidden += now() - hiddenStart;\n },\n falseVar\n );\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n var body = doc.body || {};\n var position = function () {\n try {\n var documentClientHeight = documentElement[clientHeight] || 0;\n var height = Math.max(\n body[scrollHeight] || 0,\n body[offsetHeight] || 0,\n documentElement[clientHeight] || 0,\n documentElement[scrollHeight] || 0,\n documentElement[offsetHeight] || 0\n );\n return Math.min(\n 100,\n Math.round(\n (100 * ((documentElement.scrollTop || 0) + documentClientHeight)) /\n height /\n 5\n ) * 5\n );\n } catch (error) {\n warn(error);\n return 0;\n }\n };\n\n addEventListenerFunc(\"load\", function () {\n scrolled = position();\n addEventListenerFunc(\n scroll,\n function () {\n if (scrolled < position()) scrolled = position();\n },\n falseVar\n );\n });\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n var pathOverwriterFunction = window[pathOverwriter];\n if (isFunction(pathOverwriterFunction)) {\n try {\n path = pathOverwriterFunction.call(window, { path: path }) || path;\n } catch (error) {\n warnInFunction(\"path\", error);\n }\n }\n\n // Ignore pages specified in data-ignore-pages\n if (shouldIgnore(path)) {\n warn(notSendingWhen + \"ignoring \" + path);\n return;\n }\n\n // Add hash to path when script is put in to hash mode\n if (mode == \"hash\" && loc.hash) path += loc.hash.split(\"?\")[0];\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n query,\n metadata,\n callback\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData(\n {\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: query || getQueryParams(deleteSourceInfo),\n\n metadata: stringify(metadata),\n },\n callback\n );\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (\n isPushState,\n pathOverwrite,\n metadata,\n callbackRaw\n ) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var querySearch;\n if (isString(pathOverwrite) && pathOverwrite.indexOf(\"?\") > -1) {\n // keep query from manual path\n var parts = pathOverwrite.split(\"?\");\n pathOverwrite = parts.shift();\n querySearch = \"?\" + parts.join(\"?\");\n }\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n // v = viewportsizes\n if (collectMetricByString(\"v\")) {\n page.viewport_width =\n Math.max(documentElement[clientWidth] || 0, window.innerWidth || 0) ||\n null;\n page.viewport_height =\n Math.max(\n documentElement[clientHeight] || 0,\n window.innerHeight || 0\n ) || null;\n }\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n // sc = screensizes\n if (screen && collectMetricByString(\"sc\")) {\n page.screen_width = screen.width;\n page.screen_height = screen.height;\n }\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n var currentReferrerHostname = referrer\n ? referrer.split(slash)[0]\n : undefinedVar;\n sameSite = referrer\n ? nonUniqueHostnames.indexOf(currentReferrerHostname) > -1 ||\n currentReferrerHostname == locationHostname\n : falseVar;\n\n // We set unique variable based on pushstate or back navigation, if no match we check the referrer\n page.unique =\n /__cf_/.test(getReferrer()) || isPushState || userNavigated\n ? falseVar\n : !sameSite;\n\n metadata = appendMetadata(metadata, {\n type: pageviewText,\n path: page.path,\n });\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n var delSrc =\n isPushState || userNavigated || !collectMetricByString(\"r\");\n sendPageView(\n isPushState,\n delSrc, // r = referrers\n sameSite,\n querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar,\n metadata,\n callback\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n /////////////////////\n // AUTOMATED PAGE VIEW COLLECTION\n //\n\n var his = window.history;\n var hisPushState = his ? his.pushState : undefinedVar;\n var dis = window.dispatchEvent;\n var pushStateText = \"pushState\";\n\n // Overwrite history pushState function to\n // allow listening on the pushState event\n if (autoCollect && hisPushState && Event && dis) {\n var stateListener = function (type) {\n var orig = his[type];\n return function () {\n var arg = arguments;\n var rv = orig.apply(this, arg);\n var event;\n if (isFunction(Event)) {\n event = new Event(type);\n } else {\n // Fix for IE\n // https://github.com/simpleanalytics/scripts/issues/8\n event = doc.createEvent(\"Event\");\n event.initEvent(type, trueVar, trueVar);\n }\n event.arguments = arg;\n dis(event);\n return rv;\n };\n };\n\n his.pushState = stateListener(pushStateText);\n\n addEventListenerFunc(\n pushStateText,\n function () {\n pageview(1);\n },\n falseVar\n );\n\n addEventListenerFunc(\n \"popstate\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n // When in hash mode, we record a pageview based on the onhashchange function\n if (autoCollect && mode == \"hash\" && \"onhashchange\" in window) {\n addEventListenerFunc(\n \"hashchange\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n if (autoCollect) pageview();\n\n window.sa_pageview = function (path, metadata, callback) {\n pageview(0, path, metadata, callback);\n };\n\n\n /////////////////////\n // EVENTS\n //\n\n var validTypes = [\"string\", \"number\"];\n\n var sendEvent = function (event, metadata, callbackRaw) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n\n var eventIsFunction = isFunction(event);\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var eventType = typeof event;\n\n if (validTypes.indexOf(eventType) < 0 && !eventIsFunction) {\n warnInFunction(eventFunctionName, eventText + \" can't be \" + eventType);\n return callback();\n }\n\n try {\n if (eventIsFunction) {\n var eventOutput = event();\n if (validTypes.indexOf(typeof eventOutput) < 0) {\n warnInFunction(\n eventFunctionName,\n event + \" returns no string: \" + eventOutput\n );\n return callback();\n }\n event = eventOutput;\n }\n } catch (error) {\n warnInFunction(eventFunctionName, error);\n return callback();\n }\n\n event = (\"\" + event).replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_|_$)/g, \"\");\n\n var eventParams = { type: eventText, event: event };\n var firstPage = !userNavigated && pages < 2;\n\n metadata = appendMetadata(metadata, eventParams);\n\n if (event) {\n sendData(\n assign(eventParams, {\n id: uuid(),\n query: getQueryParams(!firstPage),\n referrer:\n (firstPage || sameSite) && collectMetricByString(\"r\")\n ? previousReferrer\n : null,\n\n metadata: stringify(metadata),\n }),\n callback\n );\n }\n };\n\n var defaultEventFunc = function (event, metadata, callback) {\n sendEvent(event, metadata, callback);\n };\n\n // Set default function if user didn't define a function\n if (!window[eventFunctionName])\n window[eventFunctionName] = defaultEventFunc;\n\n var eventFunc = window[eventFunctionName];\n\n // Read queue of the user defined function\n var queue = eventFunc && eventFunc.q ? eventFunc.q : [];\n\n // Overwrite user defined function\n window[eventFunctionName] = defaultEventFunc;\n\n // Post events from the queue of the user defined function\n for (var event in queue) {\n if (hasProp(queue, event)) {\n Array.isArray(queue[event])\n ? sendEvent.apply(null, queue[event])\n : sendEvent(queue[event]);\n }\n }\n } catch (e) {\n sendError(e);\n }\n})(\n window,\n {},\n \"\",\n \"\",\n \"custom_app_12\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","sendError","warn","undefinedVar","undefined","trueVar","falseVar","trueText","https","pageviewText","eventText","errorText","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","notSendingWhen","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","documentElement","language","Height","scroll","uaData","userAgentData","scrollHeight","offsetHeight","clientHeight","pagehide","platformText","platformVersionText","docsUrl","pages","isBotAgent","test","screen","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","warnInFunction","name","error","hasProp","obj","prop","Object","hasOwnProperty","isString","string","filterRegex","item","replace","attr","attribute","getAttribute","convertCommaSeparatedToArray","csv","Array","isArray","length","split","isObject","object","constructor","assign","to","arg","index","nextSource","nextKey","settings","sa_settings","logSettings","keys","ignoreMetrics","collectMetricByString","metricAbbreviation","filter","RegExp","now","Date","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","c","getRandomValues","Uint8Array","toString","r","Math","random","isFunction","func","namespaceText","namespace","appendMetadata","metadata","data","metadataObject","metadataCollectorFunction","metadataCollector","strictUtm","getQueryParams","ignoreSource","overwriteSearch","search","keyValue","ignore","paramsRegexList","allowParams","map","join","regex","loadedVariable","sa_event_loaded","sendData","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","image","Image","onerror","onload","src","key","overwrittenHostname","hostname","definedHostname","basePayload","version","errorOrMessage","stack","type","path","pathname","event","filename","indexOf","message","timezone","start","scrolled","mode","collectDnt","value","autoCollect","eventFunctionName","saGlobal","ignorePages","nonUniqueHostnames","pathOverwriter","Intl","DateTimeFormat","resolvedOptions","timeZone","phantom","bot","webdriver","__nightmare","callPhantom","_phantom","solana","__polypane","_bot","collectDataOnLeave","ua","protocol","page_id","session_id","sri","mobile","brands","doctype","hostname_original","lastSendPath","hiddenStart","getReferrer","referrer","msHidden","sendOnLeave","id","push","append","original_id","duration","round","max","position","sendBeacon","bind","e","hidden","body","documentClientHeight","height","min","scrollTop","previousReferrer","sameSite","userNavigated","getPath","overwrite","pathOverwriterFunction","i","ignorePageRaw","ignorePage","shouldIgnore","hash","pageview","isPushState","pathOverwrite","callbackRaw","querySearch","parts","shift","viewport_width","innerWidth","viewport_height","innerHeight","screen_width","width","screen_height","performaceEntryType","perf","performance","navigationText","getEntriesByType","currentReferrerHostname","unique","triggerSendPageView","delSrc","deleteSourceInfo","query","currentPage","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","his","history","hisPushState","pushState","dis","dispatchEvent","pushStateText","Event","orig","rv","this","createEvent","initEvent","sa_pageview","validTypes","sendEvent","eventIsFunction","eventType","eventOutput","eventParams","firstPage","defaultEventFunc","eventFunc","queue","q"],"mappings":"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"} \ No newline at end of file diff --git a/dist/latest/custom/auto-events.js b/dist/latest/custom/auto-events.js index df23dcae..d3657139 100644 --- a/dist/latest/custom/auto-events.js +++ b/dist/latest/custom/auto-events.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy friendly analytics (docs.simpleanalytics.com/script; 2023-05-03; 19c1; v11) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; 7048; v12) */ -function r(t,e){var a,o=!1;h.downloads&&/^https?:\/\//i.test(t.href)&&new RegExp("\\.("+(h.downloadsExtensions||[]).join("|")+")$","i").test(t.pathname)?o="download":h.outbound&&/^https?:\/\//i.test(t.href)&&t.hostname!==m.location.hostname?o="outbound":h.emails&&/^mailto:/i.test(t.href)&&(o="email"),o&&(e?(a="saAutomatedLink(this, '"+o+"');",t.hasAttribute("target")&&"_self"!==t.getAttribute("target")||(a+=" return false;"),t.setAttribute("onclick",a)):t.addEventListener("click",function(t){saAutomatedLink(t.target,o)}))}function e(){try{for(var t=document.getElementsByTagName("a"),e=0;e -1,\n emails: collectTypes.indexOf(\"emails\") > -1,\n downloads: collectTypes.indexOf(\"downloads\") > -1,\n // Downloads: enter file extensions you want to collect\n downloadsExtensions: setting(\"extensions\", \"array\", [\n \"pdf\",\n \"csv\",\n \"docx\",\n \"xlsx\",\n \"zip\",\n \"doc\",\n \"xls\",\n ]),\n\n // All: use title attribute if set for event name (for all events)\n // THIS TAKES PRECEDENCE OVER OTHER SETTINGS BELOW\n title: setting(\"useTitle\", \"bool\", true),\n // Outbound: use full URL of the links? false for just the hostname\n outboundFullUrl: fullUrls,\n // Downloads: if taking event name from URL, use full URL or just filename (default)\n downloadsFullUrl: fullUrls,\n };\n\n var saGlobal = setting(\"saGlobal\", \"string\", \"sa_event\");\n\n // For compiling the script\n var optionsLink = options;\n\n if (typeof optionsLink === \"undefined\")\n log(\"options object not found, please specify\", \"warn\");\n\n window.saAutomatedLink = function saAutomatedLink(element, type) {\n try {\n if (!element) return log(\"no element found\");\n var sent = false;\n\n var callback = function () {\n if (!sent && !element.hasAttribute(\"target\"))\n document.location = element.getAttribute(\"href\");\n sent = true;\n };\n\n if (window[saGlobal] && window[saGlobal + \"_loaded\"]) {\n var hostname = element.hostname;\n var pathname = element.pathname;\n\n var event;\n var metadata = {\n title: element.getAttribute(\"title\") || undefined,\n };\n var url = element.href || undefined;\n\n var useTitle = false;\n if (optionsLink.title && element.hasAttribute(\"title\")) {\n var theTitle = element.getAttribute(\"title\").trim();\n if (theTitle != \"\") useTitle = true;\n }\n\n if (useTitle) {\n event = theTitle;\n } else {\n switch (type) {\n case \"outbound\": {\n event = hostname + (optionsLink.outboundFullUrl ? pathname : \"\");\n metadata.url = url;\n break;\n }\n case \"download\": {\n event = optionsLink.downloadsFullUrl\n ? hostname + pathname\n : pathname.split(\"/\").pop();\n metadata.url = url;\n break;\n }\n case \"email\": {\n var href = element.getAttribute(\"href\");\n event = (href.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.email = event;\n break;\n }\n }\n }\n\n var clean =\n type +\n \"_\" +\n event.replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_+|_+$)/g, \"\");\n\n window[saGlobal](clean, metadata, callback);\n\n log(\"collected \" + clean);\n\n return type === \"email\"\n ? callback()\n : window.setTimeout(callback, 5000);\n } else {\n log(saGlobal + \" is not defined\", \"warn\");\n return callback();\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n };\n\n function collectLink(link, onclick) {\n var collect = false;\n\n // Collect download clicks\n if (\n optionsLink.downloads &&\n /^https?:\\/\\//i.test(link.href) &&\n new RegExp(\n \"\\\\.(\" + (optionsLink.downloadsExtensions || []).join(\"|\") + \")$\",\n \"i\"\n ).test(link.pathname)\n ) {\n collect = \"download\";\n\n // Collect outbound links clicks\n } else if (\n optionsLink.outbound &&\n /^https?:\\/\\//i.test(link.href) &&\n link.hostname !== window.location.hostname\n ) {\n collect = \"outbound\";\n\n // Collect email clicks\n } else if (optionsLink.emails && /^mailto:/i.test(link.href)) {\n collect = \"email\";\n }\n\n if (!collect) return;\n\n if (onclick) {\n var onClickAttribute = \"saAutomatedLink(this, '\" + collect + \"');\";\n\n if (\n !link.hasAttribute(\"target\") ||\n link.getAttribute(\"target\") === \"_self\"\n )\n onClickAttribute += \" return false;\";\n\n link.setAttribute(\"onclick\", onClickAttribute);\n } else {\n link.addEventListener(\"click\", function (element) {\n saAutomatedLink(element.target, collect);\n });\n }\n }\n\n function onDOMContentLoaded() {\n try {\n var a = document.getElementsByTagName(\"a\");\n\n // Loop over all links on the page\n for (var i = 0; i < a.length; i++) {\n var link = a[i];\n var href = link.getAttribute(\"href\");\n\n // Skip links that don't have an href\n if (!href) continue;\n\n // We don't want to overwrite website behaviour so we check for the onclick attribute\n if (!link.getAttribute(\"onclick\") && !/^mailto:/.test(href)) {\n collectLink(link, true);\n } else {\n collectLink(link, false);\n }\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n }\n\n if (doc.readyState === \"ready\" || doc.readyState === \"complete\") {\n onDOMContentLoaded();\n } else {\n document.addEventListener(\"readystatechange\", function (event) {\n if (event.target.readyState === \"complete\") onDOMContentLoaded();\n });\n }\n})(window);\n"],"names":["collectLink","link","onclick","onClickAttribute","collect","optionsLink","downloads","test","href","RegExp","downloadsExtensions","join","pathname","outbound","hostname","window","location","emails","hasAttribute","getAttribute","setAttribute","addEventListener","element","saAutomatedLink","target","onDOMContentLoaded","a","document","getElementsByTagName","i","length","error","log","message","doc","scriptElement","setting","collectTypes","fullUrls","options","saGlobal","type","logger","console","warn","info","currentScript","querySelector","attribute","defaultValue","value","dataset","split","map","item","trim","filter","Boolean","indexOf","title","outboundFullUrl","downloadsFullUrl","sent","callback","theTitle","metadata","undefined","url","useTitle","event","pop","email","clean","replace","setTimeout","readyState"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"auto-events.source.js","sources":["auto-events.source.js"],"sourcesContent":["(function saAutomatedEvents(window) {\n // Skip server side rendered pages\n if (typeof window === \"undefined\") return;\n\n var log = function (message, type) {\n var logger = type === \"warn\" ? console.warn : console.info;\n return logger && logger(\"Simple Analytics auto events:\", message);\n };\n\n var doc = window.document;\n\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"auto-events.js\"]');\n\n var setting = function (attribute, type, defaultValue) {\n var value = scriptElement && scriptElement.dataset[attribute];\n\n // Booleans\n if (type === \"bool\" && (value === \"true\" || value === \"false\"))\n return value === \"true\";\n else if (type === \"bool\") return defaultValue;\n\n // Arrays\n if (type === \"array\" && value)\n return value\n .split(\",\")\n .map(function (item) {\n return item.trim();\n })\n .filter(Boolean);\n else if (type === \"array\") return defaultValue;\n\n return value || defaultValue;\n };\n\n var collectTypes = setting(\"collect\", \"array\", [\n \"outbound\",\n \"emails\",\n \"downloads\",\n ]);\n var fullUrls = setting(\"fullUrls\", \"bool\", false);\n\n var options = {\n // What to collect\n outbound: collectTypes.indexOf(\"outbound\") > -1,\n emails: collectTypes.indexOf(\"emails\") > -1,\n downloads: collectTypes.indexOf(\"downloads\") > -1,\n // Downloads: enter file extensions you want to collect\n downloadsExtensions: setting(\"extensions\", \"array\", [\n \"pdf\",\n \"csv\",\n \"docx\",\n \"xlsx\",\n \"zip\",\n \"doc\",\n \"xls\",\n ]),\n\n // All: use title attribute if set for event name (for all events)\n // THIS TAKES PRECEDENCE OVER OTHER SETTINGS BELOW\n title: setting(\"useTitle\", \"bool\", true),\n // Outbound: use full URL of the links? false for just the hostname\n outboundFullUrl: fullUrls,\n // Downloads: if taking event name from URL, use full URL or just filename (default)\n downloadsFullUrl: fullUrls,\n };\n\n var saGlobal = setting(\"saGlobal\", \"string\", \"sa_event\");\n\n // For compiling the script\n var optionsLink = options;\n\n if (typeof optionsLink === \"undefined\")\n log(\"options object not found, please specify\", \"warn\");\n\n var saAutomatedLink = function saAutomatedLink(element, type) {\n try {\n if (!element) return log(\"no element found\");\n var sent = false;\n\n var callback = function () {\n if (!sent && !element.hasAttribute(\"target\"))\n document.location = element.getAttribute(\"href\");\n sent = true;\n };\n\n if (window[saGlobal] && window[saGlobal + \"_loaded\"]) {\n var hostname = element.hostname;\n var pathname = element.pathname;\n\n var event;\n var metadata = {\n title: element.getAttribute(\"title\") || undefined,\n };\n var url = element.href || undefined;\n\n var useTitle = false;\n if (optionsLink.title && element.hasAttribute(\"title\")) {\n var theTitle = element.getAttribute(\"title\").trim();\n if (theTitle != \"\") useTitle = true;\n }\n\n if (useTitle) {\n event = theTitle;\n } else {\n switch (type) {\n case \"outbound\": {\n event = hostname + (optionsLink.outboundFullUrl ? pathname : \"\");\n metadata.url = url;\n break;\n }\n case \"download\": {\n event = optionsLink.downloadsFullUrl\n ? hostname + pathname\n : pathname.split(\"/\").pop();\n metadata.url = url;\n break;\n }\n case \"email\": {\n var href = element.getAttribute(\"href\");\n event = (href.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.email = event;\n break;\n }\n }\n }\n\n var clean =\n type +\n \"_\" +\n event.replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_+|_+$)/g, \"\");\n\n window[saGlobal](clean, metadata, callback);\n\n log(\"collected \" + clean);\n\n return type === \"email\"\n ? callback()\n : window.setTimeout(callback, 5000);\n } else {\n log(saGlobal + \" is not defined\", \"warn\");\n return callback();\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n };\n\n window.saAutomatedLink = saAutomatedLink;\n\n function collectLink(link, onclick) {\n if (link.hasAttribute(\"data-simple-event\")) return;\n var collect = false;\n\n // Collect download clicks\n if (\n optionsLink.downloads &&\n /^https?:\\/\\//i.test(link.href) &&\n new RegExp(\n \"\\\\.(\" + (optionsLink.downloadsExtensions || []).join(\"|\") + \")$\",\n \"i\"\n ).test(link.pathname)\n ) {\n collect = \"download\";\n\n // Collect outbound links clicks\n } else if (\n optionsLink.outbound &&\n /^https?:\\/\\//i.test(link.href) &&\n link.hostname !== window.location.hostname\n ) {\n collect = \"outbound\";\n\n // Collect email clicks\n } else if (optionsLink.emails && /^mailto:/i.test(link.href)) {\n collect = \"email\";\n }\n\n if (!collect) return;\n\n if (onclick) {\n var onClickAttribute = \"saAutomatedLink(this, '\" + collect + \"');\";\n\n if (\n !link.hasAttribute(\"target\") ||\n link.getAttribute(\"target\") === \"_self\"\n )\n onClickAttribute += \" return false;\";\n\n link.setAttribute(\"onclick\", onClickAttribute);\n } else {\n link.addEventListener(\"click\", function () {\n saAutomatedLink(link, collect);\n });\n }\n }\n\n function onDOMContentLoaded() {\n try {\n var a = document.getElementsByTagName(\"a\");\n\n // Loop over all links on the page\n for (var i = 0; i < a.length; i++) {\n var link = a[i];\n var href = link.getAttribute(\"href\");\n\n // Skip links that don't have an href\n if (!href) continue;\n\n // We don't want to overwrite website behaviour so we check for the onclick attribute\n if (!link.getAttribute(\"onclick\") && !/^mailto:/.test(href)) {\n collectLink(link, true);\n } else {\n collectLink(link, false);\n }\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n }\n\n if (doc.readyState === \"ready\" || doc.readyState === \"complete\") {\n onDOMContentLoaded();\n } else {\n document.addEventListener(\"readystatechange\", function (event) {\n if (event.target.readyState === \"complete\") onDOMContentLoaded();\n });\n }\n})(window);\n"],"names":["collectLink","link","onclick","collect","onClickAttribute","hasAttribute","optionsLink","downloads","test","href","RegExp","downloadsExtensions","join","pathname","outbound","hostname","window","location","emails","getAttribute","setAttribute","addEventListener","saAutomatedLink","onDOMContentLoaded","a","document","getElementsByTagName","i","length","error","log","message","doc","scriptElement","setting","collectTypes","fullUrls","options","saGlobal","type","logger","console","warn","info","currentScript","querySelector","attribute","defaultValue","value","dataset","split","map","item","trim","filter","Boolean","indexOf","title","outboundFullUrl","downloadsFullUrl","element","sent","callback","theTitle","metadata","undefined","url","useTitle","event","pop","email","clean","replace","setTimeout","readyState","target"],"mappings":"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"} \ No newline at end of file diff --git a/dist/latest/custom/e.js b/dist/latest/custom/e.js index 2313f007..f9faf4e8 100644 --- a/dist/latest/custom/e.js +++ b/dist/latest/custom/e.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy friendly analytics (docs.simpleanalytics.com/script; 2023-05-03; e5db; v11) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; eb12; v12) */ -!function(l,t,e,n,p){try{var h=undefined,f=!0,d=!1,r="true",a="https:",m="pageview",u="event",i="error",o=l.console,c="doNotTrack",g=l.navigator,s=l.location,v=s.host,y=l.document,_=g.userAgent,w="Not sending request ",b=w+"when ",E=d,O=encodeURIComponent,x=decodeURIComponent,S=JSON.stringify,M=l.addEventListener,k="https://"+e,A=y.documentElement||{},q="language",$="Height",j="scroll",D=g.userAgentData,C=j+$,H="offset"+$,R="client"+$,P="pagehide",T="platform",U="platformVersion",I="https://docs.simpleanalytics.com",V=0,B=/(bot|spider|crawl)/i.test(_)&&!/(cubot)/i.test(_),N=l.screen,z=y.currentScript||y.querySelector('script[src*="'+e+'"]');p=function(){var t=[].slice.call(arguments);return t.unshift("Simple Analytics:"),Function.prototype.apply.call(o.warn,o,t)};var F=function(t,e){p("Error in your "+t+" function:",e)},W=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},G=function(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},J=function(t,e){return t&&t.getAttribute("data-"+e)},L=function(t){return Array.isArray(t)?t:"string"==typeof t&&t.length?t.split(/, ?/):[]},Y=function(t){return t&&t.constructor===Object},Z=function(){for(var t={},e=arguments,n=0;n>t/4).toString(16)})}catch(r){return t.replace(n,function(t){var e=16*Math.random()|0;return(t<2?e:3&e|8).toString(16)})}},rt=function(t){return"function"==typeof t},at="namespace",it=t[at]||J(z,at)||"sa",ot=l[it+"_metadata"],ct=function(t,e){Y(ot)&&(t=Z(t,ot));var n=l[Mt];if(!rt(n))return t;try{return Z(t,n.call(l,Z(t,e)))}catch(r){F("metadata",r)}},st=t.strictUtm||J(z,"strict-utm")==r,ut=function(a){return s.search.slice(1).split("&").filter(function(t){var e=a||!tt("ut"),n=Ot.map(G).join("|"),r=e?"^("+n+")=":"^((utm_)"+(st?"":"?")+"(source|medium|content|term|campaign)"+(st?"":"|ref")+"|"+n+")=";return e&&!Ot.length?d:new RegExp(r).test(t)}).join("&")||h},lt=it+"_loaded";if(l[lt]==f)return p(w+"twice");l.sa_event_loaded=f,l[lt]=f;var pt=function(e,t,n){e=n?e:Z(qt,Dt,e),g.brave&&!n&&(e.brave=f),g._duckduckgoloader_&&!n&&(e.duck=f);var r=new Image;t&&(r.onerror=t,r.onload=t),r.src=k+"/simple.gif?"+Object.keys(e).filter(function(t){return e[t]!=h}).map(function(t){return O(t)+"="+O(e[t])}).join("&")+"&time="+Date.now()},ht=t.hostname||J(z,"hostname"),ft=ht||v,dt={version:"custom_events_11",hostname:ft};n=function(t){t=t.stack?t+" "+t.stack:t,p(t),pt(Z(dt,{type:i,error:t,path:s.pathname}),h,f)},M(i,function(t){t.filename&&-1"); +!function(d,t,e,n,m){try{var v=undefined,g=!0,y=!1,r="true",a="https:",_="pageview",u="event",i="error",o=d.console,c="doNotTrack",w=d.navigator,s=d.location,b=s.host,l=d.document,p=w.userAgent,f="Not sending request ",h=f+"when ",O=y,E=encodeURIComponent,x=decodeURIComponent,S=JSON.stringify,M=d.addEventListener,k="https://"+e,A=l.documentElement||{},q="language",$="Height",j="scroll",D=w.userAgentData,C=j+$,H="offset"+$,R="client"+$,P="pagehide",T="platform",U="platformVersion",I="https://docs.simpleanalytics.com",V=0,B=/(bot|spider|crawl)/i.test(p)&&!/(cubot)/i.test(p),N=d.screen,z=l.currentScript||l.querySelector('script[src*="'+e+'"]');m=function(){var t=[].slice.call(arguments);return t.unshift("Simple Analytics:"),Function.prototype.apply.call(o.warn,o,t)};var F=function(t,e){m("Error in your "+t+" function:",e)},W=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},G=function(t){return"string"==typeof t},J=function(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},L=function(t,e){return t&&t.getAttribute("data-"+e)},Y=function(t){return Array.isArray(t)?t:G(t)&&t.length?t.split(/, ?/):[]},Z=function(t){return t&&t.constructor===Object},K=function(){for(var t={},e=arguments,n=0;n>t/4).toString(16)})}catch(r){return t.replace(n,function(t){var e=16*Math.random()|0;return(t<2?e:3&e|8).toString(16)})}},at=function(t){return"function"==typeof t},it="namespace",ot=t[it]||L(z,it)||"sa",ct=function(t,e){var n=d[ot+"_metadata"];Z(n)&&(t=K(t,n));var r=d[Mt];if(!at(r))return Mt&&m(Mt+" not found, set window."+Mt),t;try{return K(t,r.call(d,K(t,e)))}catch(a){F("metadata",a)}},st=t.strictUtm||L(z,"strict-utm")==r,ut=function(a,t){return(t||s.search).slice(1).split("&").filter(function(t){var e=a||!et("ut"),n=Et.map(J).join("|"),r=e?"^("+n+")=":"^((utm_)"+(st?"":"?")+"(source|medium|content|term|campaign)"+(st?"":"|ref")+"|"+n+")=";return e&&!Et.length?y:new RegExp(r).test(t)}).join("&")||v},lt=ot+"_loaded";if(d[lt]==g)return m(f+"twice");d.sa_event_loaded=g,d[lt]=g;var pt=function(e,t,n){e=n?e:K($t,Ct,e),w.brave&&!n&&(e.brave=g),w._duckduckgoloader_&&!n&&(e.duck=g);var r=new Image;t&&(r.onerror=t,r.onload=t),r.src=k+"/simple.gif?"+Object.keys(e).filter(function(t){return e[t]!=v}).map(function(t){return E(t)+"="+E(e[t])}).join("&")+"&time="+Date.now()},ft=t.hostname||L(z,"hostname"),ht=ft||b,dt={version:"custom_events_12",hostname:ht};n=function(t){t=t.stack?t+" "+t.stack:t,m(t),pt(K(dt,{type:i,error:t,path:s.pathname}),v,g)},M(i,function(t){t.filename&&-1"); //# sourceMappingURL=e.js.map \ No newline at end of file diff --git a/dist/latest/custom/e.js.map b/dist/latest/custom/e.js.map index 3563f4bb..87606e34 100644 --- a/dist/latest/custom/e.js.map +++ b/dist/latest/custom/e.js.map @@ -1 +1 @@ -{"version":3,"file":"e.source.js","sources":["e.source.js"],"sourcesContent":["/* eslint-env browser */\n\n(function (\n window,\n overwriteOptions,\n baseUrl,\n apiUrlPrefix,\n version,\n defaultNamespace,\n sendError,\n warn\n) {\n try {\n /////////////////////\n // PREDEFINED VARIABLES FOR BETTER MINIFICATION\n //\n\n // This seems like a lot of repetition, but it makes our script available for\n // multple destination which prevents us to need multiple scripts. The minified\n // version stays small.\n var undefinedVar = undefined;\n var trueVar = true;\n var falseVar = false;\n var trueText = \"true\";\n var https = \"https:\";\n var pageviewText = \"pageview\";\n var eventText = \"event\";\n var errorText = \"error\";\n var slash = \"/\";\n var protocol = https + \"//\";\n var con = window.console;\n var doNotTrack = \"doNotTrack\";\n var nav = window.navigator;\n var loc = window.location;\n var locationHostname = loc.host;\n var doc = window.document;\n var userAgent = nav.userAgent;\n var notSending = \"Not sending request \";\n var notSendingWhen = notSending + \"when \";\n var fetchedHighEntropyValues = falseVar;\n var encodeURIComponentFunc = encodeURIComponent;\n var decodeURIComponentFunc = decodeURIComponent;\n var stringify = JSON.stringify;\n var thousand = 1000;\n var addEventListenerFunc = window.addEventListener;\n var fullApiUrl = protocol + apiUrlPrefix + baseUrl;\n var documentElement = doc.documentElement || {};\n var language = \"language\";\n var Height = \"Height\";\n var Width = \"Width\";\n var scroll = \"scroll\";\n var uaData = nav.userAgentData;\n var scrollHeight = scroll + Height;\n var offsetHeight = \"offset\" + Height;\n var clientHeight = \"client\" + Height;\n var clientWidth = \"client\" + Width;\n var pagehide = \"pagehide\";\n var platformText = \"platform\";\n var platformVersionText = \"platformVersion\";\n var docsUrl = \"https://docs.simpleanalytics.com\";\n var pages = 0;\n var isBotAgent =\n /(bot|spider|crawl)/i.test(userAgent) && !/(cubot)/i.test(userAgent);\n var screen = window.screen;\n\n\n // Find the script element where options can be set on\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"' + baseUrl + '\"]');\n\n /////////////////////\n // HELPER FUNCTIONS\n //\n\n // A simple log function so the user knows why a request is not being send\n warn = function () {\n // 1. Convert args to a normal array\n var args = [].slice.call(arguments);\n\n // 2. Prepend log prefix\n args.unshift(\"Simple Analytics:\");\n\n // 3. Pass along arguments to console.warn\n // Function.prototype.apply.call is needed for Internet Explorer\n return Function.prototype.apply.call(con.warn, con, args);\n };\n\n var warnInFunction = function (name, error) {\n warn(\"Error in your \" + name + \" function:\", error);\n };\n\n var hasProp = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n\n var isString = function (string) {\n return typeof string == \"string\";\n };\n\n var filterRegex = function (item) {\n return item.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n var attr = function (scriptElement, attribute) {\n return scriptElement && scriptElement.getAttribute(\"data-\" + attribute);\n };\n\n var convertCommaSeparatedToArray = function (csv) {\n return Array.isArray(csv)\n ? csv\n : isString(csv) && csv.length\n ? csv.split(/, ?/)\n : [];\n };\n\n var isObject = function (object) {\n return object && object.constructor === Object;\n };\n\n var assign = function () {\n var to = {};\n var arg = arguments;\n for (var index = 0; index < arg.length; index++) {\n var nextSource = arg[index];\n if (isObject(nextSource)) {\n for (var nextKey in nextSource) {\n if (hasProp(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n\n var settings = window.sa_settings;\n var logSettings = settings || Object.keys(overwriteOptions).length;\n\n // Merge overwriteOptions with sa_settings\n overwriteOptions = assign(overwriteOptions, settings);\n\n if (logSettings) warn(\"Settings\", overwriteOptions);\n\n // Customers can skip data points\n var ignoreMetrics = convertCommaSeparatedToArray(\n overwriteOptions.ignoreMetrics || attr(scriptElement, \"ignore-metrics\")\n );\n\n var collectMetricByString = function (metricAbbreviation) {\n // Can't use Array.find() here because we need to support IE9\n return (\n ignoreMetrics.filter(function (item) {\n return new RegExp(\"^\" + metricAbbreviation).test(item);\n }).length === 0\n );\n };\n\n var now = Date.now;\n\n var uuid = function () {\n var cryptoObject = window.crypto || window.msCrypto;\n var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;\n var uuidRegex = /[018]/g;\n\n try {\n return emptyUUID.replace(uuidRegex, function (c) {\n return (\n c ^\n (cryptoObject.getRandomValues(new Uint8Array(1))[0] &\n (15 >> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n var metadataObject = window[namespace + \"_metadata\"];\n var appendMetadata = function (metadata, data) {\n if (isObject(metadataObject)) metadata = assign(metadata, metadataObject);\n var metadataCollectorFunction = window[metadataCollector];\n if (!isFunction(metadataCollectorFunction)) return metadata;\n try {\n return assign(\n metadata,\n metadataCollectorFunction.call(window, assign(metadata, data))\n );\n } catch (error) {\n warnInFunction(\"metadata\", error);\n }\n };\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource) {\n return (\n loc.search\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n var paramsRegexList = allowParams.map(filterRegex).join(\"|\");\n var regex = ignore\n ? \"^(\" + paramsRegexList + \")=\"\n : \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \"|\" +\n paramsRegexList +\n \")=\";\n if (ignore && !allowParams.length) return falseVar;\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n // Ignore pages specified in data-ignore-pages\n var shouldIgnore = function (path) {\n for (var i in ignorePages) {\n var ignorePageRaw = ignorePages[i];\n if (!ignorePageRaw) continue;\n\n // Prepend a slash when it's missing\n var ignorePage =\n ignorePageRaw[0] == slash ? ignorePageRaw : slash + ignorePageRaw;\n\n if (\n ignorePage === path ||\n new RegExp(\n \"^\" + filterRegex(ignorePage).replace(/\\\\\\*/gi, \"(.*)\") + \"$\",\n \"i\"\n ).test(path)\n )\n return trueVar;\n }\n return falseVar;\n };\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n if (callback) {\n image.onerror = callback;\n image.onload = callback;\n }\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n /////////////////////\n // ERROR FUNCTIONS\n //\n\n // Send errors\n // no var because it's scoped outside of the try/catch\n sendError = function (errorOrMessage) {\n errorOrMessage = errorOrMessage.stack\n ? errorOrMessage + \" \" + errorOrMessage.stack\n : errorOrMessage;\n warn(errorOrMessage);\n sendData(\n assign(basePayload, {\n type: errorText,\n error: errorOrMessage,\n path: loc.pathname,\n }),\n undefinedVar,\n trueVar\n );\n };\n\n // We listen for the error events and only send errors that are\n // from our script (checked by filename) to our server.\n addEventListenerFunc(\n errorText,\n function (event) {\n if (event.filename && event.filename.indexOf(baseUrl) > -1) {\n sendError(event.message);\n }\n },\n falseVar\n );\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n var start = now();\n\n var scrolled = 0;\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n // Should we record Do Not Track visits?\n var collectDnt = isBoolean(overwriteOptions.collectDnt)\n ? overwriteOptions.collectDnt\n : attr(scriptElement, \"ignore-dnt\") == trueText ||\n attr(scriptElement, \"skip-dnt\") == trueText ||\n attr(scriptElement, \"collect-dnt\") == trueText;\n\n // Some customers want to collect page views manually\n var autoCollect = !(\n attr(scriptElement, \"auto-collect\") == \"false\" ||\n overwriteOptions.autoCollect === falseVar\n );\n\n // Event function name\n var eventFunctionName =\n overwriteOptions.saGlobal ||\n attr(scriptElement, \"sa-global\") ||\n namespace + \"_\" + eventText;\n\n // Customers can ignore certain pages\n var ignorePages = convertCommaSeparatedToArray(\n overwriteOptions.ignorePages || attr(scriptElement, \"ignore-pages\")\n );\n\n // Customers can allow params\n var allowParams = convertCommaSeparatedToArray(\n overwriteOptions.allowParams || attr(scriptElement, \"allow-params\")\n );\n\n // Customers can allow params\n var nonUniqueHostnames = convertCommaSeparatedToArray(\n overwriteOptions.nonUniqueHostnames ||\n attr(scriptElement, \"non-unique-hostnames\")\n );\n\n // Customers can overwrite certain values\n var pathOverwriter =\n overwriteOptions.pathOverwriter || attr(scriptElement, \"path-overwriter\");\n\n // Customers can add metadata to events and pageviews via a function\n var metadataCollector =\n overwriteOptions.metadataCollector ||\n attr(scriptElement, \"metadata-collector\");\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var bot =\n nav.webdriver ||\n window.__nightmare ||\n window.callPhantom ||\n window._phantom ||\n window.phantom ||\n window.__polypane ||\n window._bot ||\n isBotAgent ||\n Math.random() == Math.random();\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = falseVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n // Warn when no document.doctype is defined (this breaks some documentElement dimensions)\n if (!doc.doctype) warn(\"Add DOCTYPE html for accurate dimensions\");\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (!collectDnt && doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n return (\n (doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n // t = timeonpage\n if (collectMetricByString(\"t\")) {\n append.duration = Math.round((now() - start - msHidden) / thousand);\n }\n msHidden = 0;\n start = now();\n\n // scro = scrolled\n if (collectMetricByString(\"scro\")) {\n append.scrolled = Math.max(0, scrolled, position());\n }\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n nav.sendBeacon(fullApiUrl + \"/append\", stringify(append));\n }\n };\n\n var hiddenStart;\n addEventListenerFunc(\n \"visibilitychange\",\n function () {\n if (doc.hidden) {\n if (!(\"on\" + pagehide in window)) sendOnLeave();\n hiddenStart = now();\n } else msHidden += now() - hiddenStart;\n },\n falseVar\n );\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n var body = doc.body || {};\n var position = function () {\n try {\n var documentClientHeight = documentElement[clientHeight] || 0;\n var height = Math.max(\n body[scrollHeight] || 0,\n body[offsetHeight] || 0,\n documentElement[clientHeight] || 0,\n documentElement[scrollHeight] || 0,\n documentElement[offsetHeight] || 0\n );\n return Math.min(\n 100,\n Math.round(\n (100 * ((documentElement.scrollTop || 0) + documentClientHeight)) /\n height /\n 5\n ) * 5\n );\n } catch (error) {\n warn(error);\n return 0;\n }\n };\n\n addEventListenerFunc(\"load\", function () {\n scrolled = position();\n addEventListenerFunc(\n scroll,\n function () {\n if (scrolled < position()) scrolled = position();\n },\n falseVar\n );\n });\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n var pathOverwriterFunction = window[pathOverwriter];\n if (isFunction(pathOverwriterFunction)) {\n try {\n path = pathOverwriterFunction.call(window, { path: path }) || path;\n } catch (error) {\n warnInFunction(\"path\", error);\n }\n }\n\n // Ignore pages specified in data-ignore-pages\n if (shouldIgnore(path)) {\n warn(notSendingWhen + \"ignoring \" + path);\n return;\n }\n\n // Add hash to path when script is put in to hash mode\n if (mode == \"hash\" && loc.hash) path += loc.hash.split(\"?\")[0];\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n metadata\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData({\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: getQueryParams(deleteSourceInfo),\n\n metadata: stringify(metadata),\n });\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (isPushState, pathOverwrite, metadata) {\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n // v = viewportsizes\n if (collectMetricByString(\"v\")) {\n page.viewport_width =\n Math.max(documentElement[clientWidth] || 0, window.innerWidth || 0) ||\n null;\n page.viewport_height =\n Math.max(\n documentElement[clientHeight] || 0,\n window.innerHeight || 0\n ) || null;\n }\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n // sc = screensizes\n if (screen && collectMetricByString(\"sc\")) {\n page.screen_width = screen.width;\n page.screen_height = screen.height;\n }\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n var currentReferrerHostname = referrer\n ? referrer.split(slash)[0]\n : undefinedVar;\n sameSite = referrer\n ? nonUniqueHostnames.indexOf(currentReferrerHostname) > -1 ||\n currentReferrerHostname == locationHostname\n : falseVar;\n\n // We set unique variable based on pushstate or back navigation, if no match we check the referrer\n page.unique = isPushState || userNavigated ? falseVar : !sameSite;\n\n metadata = appendMetadata(metadata, {\n type: pageviewText,\n path: page.path,\n });\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n sendPageView(\n isPushState,\n isPushState || userNavigated || !collectMetricByString(\"r\"), // r = referrers\n sameSite,\n metadata\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n /////////////////////\n // AUTOMATED PAGE VIEW COLLECTION\n //\n\n var his = window.history;\n var hisPushState = his ? his.pushState : undefinedVar;\n var dis = window.dispatchEvent;\n var pushStateText = \"pushState\";\n\n // Overwrite history pushState function to\n // allow listening on the pushState event\n if (autoCollect && hisPushState && Event && dis) {\n var stateListener = function (type) {\n var orig = his[type];\n return function () {\n var arg = arguments;\n var rv = orig.apply(this, arg);\n var event;\n if (isFunction(Event)) {\n event = new Event(type);\n } else {\n // Fix for IE\n // https://github.com/simpleanalytics/scripts/issues/8\n event = doc.createEvent(\"Event\");\n event.initEvent(type, trueVar, trueVar);\n }\n event.arguments = arg;\n dis(event);\n return rv;\n };\n };\n\n his.pushState = stateListener(pushStateText);\n\n addEventListenerFunc(\n pushStateText,\n function () {\n pageview(1);\n },\n falseVar\n );\n\n addEventListenerFunc(\n \"popstate\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n // When in hash mode, we record a pageview based on the onhashchange function\n if (autoCollect && mode == \"hash\" && \"onhashchange\" in window) {\n addEventListenerFunc(\n \"hashchange\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n if (autoCollect) pageview();\n else {\n window.sa_pageview = function (path, metadata) {\n pageview(0, path, metadata);\n };\n }\n\n /////////////////////\n // EVENTS\n //\n\n var validTypes = [\"string\", \"number\"];\n\n var sendEvent = function (event, metadata, callbackRaw) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n\n var eventIsFunction = isFunction(event);\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var eventType = typeof event;\n\n if (validTypes.indexOf(eventType) < 0 && !eventIsFunction) {\n warnInFunction(eventFunctionName, eventText + \" can't be \" + eventType);\n return callback();\n }\n\n try {\n if (eventIsFunction) {\n var eventOutput = event();\n if (validTypes.indexOf(typeof eventOutput) < 0) {\n warnInFunction(\n eventFunctionName,\n event + \" returns no string: \" + eventOutput\n );\n return callback();\n }\n event = eventOutput;\n }\n } catch (error) {\n warnInFunction(eventFunctionName, error);\n return callback();\n }\n\n event = (\"\" + event).replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_|_$)/g, \"\");\n\n var eventParams = { type: eventText, event: event };\n var firstPage = !userNavigated && pages < 2;\n\n metadata = appendMetadata(metadata, eventParams);\n\n if (event) {\n sendData(\n assign(eventParams, {\n id: uuid(),\n query: getQueryParams(!firstPage),\n referrer:\n (firstPage || sameSite) && collectMetricByString(\"r\")\n ? previousReferrer\n : null,\n\n metadata: stringify(metadata),\n }),\n callback\n );\n }\n };\n\n var defaultEventFunc = function (event, metadata, callback) {\n sendEvent(event, metadata, callback);\n };\n\n // Set default function if user didn't define a function\n if (!window[eventFunctionName])\n window[eventFunctionName] = defaultEventFunc;\n\n var eventFunc = window[eventFunctionName];\n\n // Read queue of the user defined function\n var queue = eventFunc && eventFunc.q ? eventFunc.q : [];\n\n // Overwrite user defined function\n window[eventFunctionName] = defaultEventFunc;\n\n // Post events from the queue of the user defined function\n for (var event in queue) {\n if (hasProp(queue, event)) {\n Array.isArray(queue[event])\n ? sendEvent.apply(null, queue[event])\n : sendEvent(queue[event]);\n }\n }\n } catch (e) {\n sendError(e);\n }\n})(\n window,\n {},\n \"\",\n \"\",\n \"custom_events_11\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","sendError","warn","undefinedVar","undefined","trueVar","falseVar","trueText","https","pageviewText","eventText","errorText","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","notSendingWhen","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","documentElement","language","Height","scroll","uaData","userAgentData","scrollHeight","offsetHeight","clientHeight","pagehide","platformText","platformVersionText","docsUrl","pages","isBotAgent","test","screen","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","warnInFunction","name","error","hasProp","obj","prop","Object","hasOwnProperty","filterRegex","item","replace","attr","attribute","getAttribute","convertCommaSeparatedToArray","csv","Array","isArray","length","split","isObject","object","constructor","assign","to","arg","index","nextSource","nextKey","settings","sa_settings","logSettings","keys","ignoreMetrics","collectMetricByString","metricAbbreviation","filter","RegExp","now","Date","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","c","getRandomValues","Uint8Array","toString","r","Math","random","isFunction","func","namespaceText","namespace","metadataObject","appendMetadata","metadata","data","metadataCollectorFunction","metadataCollector","strictUtm","getQueryParams","ignoreSource","search","keyValue","ignore","paramsRegexList","allowParams","map","join","regex","loadedVariable","sa_event_loaded","sendData","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","image","Image","onerror","onload","src","key","overwrittenHostname","hostname","definedHostname","basePayload","version","errorOrMessage","stack","type","path","pathname","event","filename","indexOf","message","timezone","start","scrolled","mode","collectDnt","value","autoCollect","eventFunctionName","saGlobal","ignorePages","nonUniqueHostnames","pathOverwriter","Intl","DateTimeFormat","resolvedOptions","timeZone","bot","webdriver","__nightmare","callPhantom","_phantom","phantom","__polypane","_bot","collectDataOnLeave","ua","protocol","page_id","session_id","sri","mobile","brands","doctype","hostname_original","lastSendPath","hiddenStart","referrer","msHidden","sendOnLeave","id","push","append","original_id","duration","round","max","position","sendBeacon","hidden","body","documentClientHeight","height","min","scrollTop","previousReferrer","sameSite","userNavigated","getPath","overwrite","pathOverwriterFunction","i","ignorePageRaw","ignorePage","shouldIgnore","hash","pageview","isPushState","pathOverwrite","viewport_width","innerWidth","viewport_height","innerHeight","screen_width","width","screen_height","performaceEntryType","perf","performance","navigationText","getEntriesByType","currentReferrerHostname","unique","triggerSendPageView","deleteSourceInfo","currentPage","query","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","e","his","history","hisPushState","pushState","dis","dispatchEvent","pushStateText","Event","orig","rv","this","createEvent","initEvent","sa_pageview","validTypes","sendEvent","callbackRaw","eventIsFunction","eventType","eventOutput","eventParams","firstPage","defaultEventFunc","eventFunc","queue","q"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"e.source.js","sources":["e.source.js"],"sourcesContent":["/* eslint-env browser */\n\n(function (\n window,\n overwriteOptions,\n baseUrl,\n apiUrlPrefix,\n version,\n defaultNamespace,\n sendError,\n warn\n) {\n try {\n /////////////////////\n // PREDEFINED VARIABLES FOR BETTER MINIFICATION\n //\n\n // This seems like a lot of repetition, but it makes our script available for\n // multple destination which prevents us to need multiple scripts. The minified\n // version stays small.\n var undefinedVar = undefined;\n var trueVar = true;\n var falseVar = false;\n var trueText = \"true\";\n var https = \"https:\";\n var pageviewText = \"pageview\";\n var eventText = \"event\";\n var errorText = \"error\";\n var slash = \"/\";\n var protocol = https + \"//\";\n var con = window.console;\n var doNotTrack = \"doNotTrack\";\n var nav = window.navigator;\n var loc = window.location;\n var locationHostname = loc.host;\n var doc = window.document;\n var userAgent = nav.userAgent;\n var notSending = \"Not sending request \";\n var notSendingWhen = notSending + \"when \";\n var fetchedHighEntropyValues = falseVar;\n var encodeURIComponentFunc = encodeURIComponent;\n var decodeURIComponentFunc = decodeURIComponent;\n var stringify = JSON.stringify;\n var thousand = 1000;\n var addEventListenerFunc = window.addEventListener;\n var fullApiUrl = protocol + apiUrlPrefix + baseUrl;\n var documentElement = doc.documentElement || {};\n var language = \"language\";\n var Height = \"Height\";\n var Width = \"Width\";\n var scroll = \"scroll\";\n var uaData = nav.userAgentData;\n var scrollHeight = scroll + Height;\n var offsetHeight = \"offset\" + Height;\n var clientHeight = \"client\" + Height;\n var clientWidth = \"client\" + Width;\n var pagehide = \"pagehide\";\n var platformText = \"platform\";\n var platformVersionText = \"platformVersion\";\n var docsUrl = \"https://docs.simpleanalytics.com\";\n var pages = 0;\n var isBotAgent =\n /(bot|spider|crawl)/i.test(userAgent) && !/(cubot)/i.test(userAgent);\n var screen = window.screen;\n\n\n // Find the script element where options can be set on\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"' + baseUrl + '\"]');\n\n /////////////////////\n // HELPER FUNCTIONS\n //\n\n // A simple log function so the user knows why a request is not being send\n warn = function () {\n // 1. Convert args to a normal array\n var args = [].slice.call(arguments);\n\n // 2. Prepend log prefix\n args.unshift(\"Simple Analytics:\");\n\n // 3. Pass along arguments to console.warn\n // Function.prototype.apply.call is needed for Internet Explorer\n return Function.prototype.apply.call(con.warn, con, args);\n };\n\n var warnInFunction = function (name, error) {\n warn(\"Error in your \" + name + \" function:\", error);\n };\n\n var hasProp = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n\n var isString = function (string) {\n return typeof string == \"string\";\n };\n\n var filterRegex = function (item) {\n return item.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n var attr = function (scriptElement, attribute) {\n return scriptElement && scriptElement.getAttribute(\"data-\" + attribute);\n };\n\n var convertCommaSeparatedToArray = function (csv) {\n return Array.isArray(csv)\n ? csv\n : isString(csv) && csv.length\n ? csv.split(/, ?/)\n : [];\n };\n\n var isObject = function (object) {\n return object && object.constructor === Object;\n };\n\n var assign = function () {\n var to = {};\n var arg = arguments;\n for (var index = 0; index < arg.length; index++) {\n var nextSource = arg[index];\n if (isObject(nextSource)) {\n for (var nextKey in nextSource) {\n if (hasProp(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n\n var settings = window.sa_settings;\n var logSettings = settings || Object.keys(overwriteOptions).length;\n\n // Merge overwriteOptions with sa_settings\n overwriteOptions = assign(overwriteOptions, settings);\n\n if (logSettings) warn(\"Settings\", overwriteOptions);\n\n // Customers can skip data points\n var ignoreMetrics = convertCommaSeparatedToArray(\n overwriteOptions.ignoreMetrics || attr(scriptElement, \"ignore-metrics\")\n );\n\n var collectMetricByString = function (metricAbbreviation) {\n // Can't use Array.find() here because we need to support IE9\n return (\n ignoreMetrics.filter(function (item) {\n return new RegExp(\"^\" + metricAbbreviation).test(item);\n }).length === 0\n );\n };\n\n var now = Date.now;\n\n var uuid = function () {\n var cryptoObject = window.crypto || window.msCrypto;\n var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;\n var uuidRegex = /[018]/g;\n\n try {\n return emptyUUID.replace(uuidRegex, function (c) {\n return (\n c ^\n (cryptoObject.getRandomValues(new Uint8Array(1))[0] &\n (15 >> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n var appendMetadata = function (metadata, data) {\n var metadataObject = window[namespace + \"_metadata\"];\n if (isObject(metadataObject)) metadata = assign(metadata, metadataObject);\n var metadataCollectorFunction = window[metadataCollector];\n if (!isFunction(metadataCollectorFunction)) {\n if (metadataCollector)\n warn(\n metadataCollector + \" not found, set window.\" + metadataCollector\n );\n return metadata;\n }\n try {\n return assign(\n metadata,\n metadataCollectorFunction.call(window, assign(metadata, data))\n );\n } catch (error) {\n warnInFunction(\"metadata\", error);\n }\n };\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource, overwriteSearch) {\n return (\n (overwriteSearch || loc.search)\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n var paramsRegexList = allowParams.map(filterRegex).join(\"|\");\n var regex = ignore\n ? \"^(\" + paramsRegexList + \")=\"\n : \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \"|\" +\n paramsRegexList +\n \")=\";\n if (ignore && !allowParams.length) return falseVar;\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n // Ignore pages specified in data-ignore-pages\n var shouldIgnore = function (path) {\n for (var i in ignorePages) {\n var ignorePageRaw = ignorePages[i];\n if (!ignorePageRaw) continue;\n\n // Prepend a slash when it's missing\n var ignorePage =\n ignorePageRaw[0] == slash ? ignorePageRaw : slash + ignorePageRaw;\n\n if (\n ignorePage === path ||\n new RegExp(\n \"^\" + filterRegex(ignorePage).replace(/\\\\\\*/gi, \"(.*)\") + \"$\",\n \"i\"\n ).test(path)\n )\n return trueVar;\n }\n return falseVar;\n };\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n if (callback) {\n image.onerror = callback;\n image.onload = callback;\n }\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n /////////////////////\n // ERROR FUNCTIONS\n //\n\n // Send errors\n // no var because it's scoped outside of the try/catch\n sendError = function (errorOrMessage) {\n errorOrMessage = errorOrMessage.stack\n ? errorOrMessage + \" \" + errorOrMessage.stack\n : errorOrMessage;\n warn(errorOrMessage);\n sendData(\n assign(basePayload, {\n type: errorText,\n error: errorOrMessage,\n path: loc.pathname,\n }),\n undefinedVar,\n trueVar\n );\n };\n\n // We listen for the error events and only send errors that are\n // from our script (checked by filename) to our server.\n addEventListenerFunc(\n errorText,\n function (event) {\n if (event.filename && event.filename.indexOf(baseUrl) > -1) {\n sendError(event.message);\n }\n },\n falseVar\n );\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n var start = now();\n\n var scrolled = 0;\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n // Should we record Do Not Track visits?\n var collectDnt = isBoolean(overwriteOptions.collectDnt)\n ? overwriteOptions.collectDnt\n : attr(scriptElement, \"ignore-dnt\") == trueText ||\n attr(scriptElement, \"skip-dnt\") == trueText ||\n attr(scriptElement, \"collect-dnt\") == trueText;\n\n // Some customers want to collect page views manually\n var autoCollect = !(\n attr(scriptElement, \"auto-collect\") == \"false\" ||\n overwriteOptions.autoCollect === falseVar\n );\n\n // Event function name\n var eventFunctionName =\n overwriteOptions.saGlobal ||\n attr(scriptElement, \"sa-global\") ||\n namespace + \"_\" + eventText;\n\n // Customers can ignore certain pages\n var ignorePages = convertCommaSeparatedToArray(\n overwriteOptions.ignorePages || attr(scriptElement, \"ignore-pages\")\n );\n\n // Customers can allow params\n var allowParams = convertCommaSeparatedToArray(\n overwriteOptions.allowParams || attr(scriptElement, \"allow-params\")\n );\n\n // Customers can allow params\n var nonUniqueHostnames = convertCommaSeparatedToArray(\n overwriteOptions.nonUniqueHostnames ||\n attr(scriptElement, \"non-unique-hostnames\")\n );\n\n // Customers can overwrite certain values\n var pathOverwriter =\n overwriteOptions.pathOverwriter || attr(scriptElement, \"path-overwriter\");\n\n // Customers can add metadata to events and pageviews via a function\n var metadataCollector =\n overwriteOptions.metadataCollector ||\n attr(scriptElement, \"metadata-collector\");\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var phantom = window.phantom;\n var bot =\n nav.webdriver ||\n window.__nightmare ||\n window.callPhantom ||\n window._phantom ||\n (phantom && !phantom.solana) ||\n window.__polypane ||\n window._bot ||\n isBotAgent ||\n Math.random() == Math.random();\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = falseVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n // Warn when no document.doctype is defined (this breaks some documentElement dimensions)\n if (!doc.doctype) warn(\"Add DOCTYPE html for accurate dimensions\");\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (!collectDnt && doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n // Customers can overwrite their referrer, here we check for that\n var overwrittenReferrer =\n overwriteOptions.referrer || attr(scriptElement, \"referrer\");\n\n return (\n (overwrittenReferrer || doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n // t = timeonpage\n if (collectMetricByString(\"t\")) {\n append.duration = Math.round((now() - start - msHidden) / thousand);\n }\n msHidden = 0;\n start = now();\n\n // scro = scrolled\n if (collectMetricByString(\"scro\")) {\n append.scrolled = Math.max(0, scrolled, position());\n }\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n try {\n nav.sendBeacon.bind(nav)(fullApiUrl + \"/append\", stringify(append));\n } catch (e) {\n // Fallback for browsers throwing \"Illegal invocation\" when the URL is invalid\n sendData(append, undefinedVar, trueVar);\n }\n }\n };\n\n var hiddenStart;\n addEventListenerFunc(\n \"visibilitychange\",\n function () {\n if (doc.hidden) {\n if (!(\"on\" + pagehide in window)) sendOnLeave();\n hiddenStart = now();\n } else msHidden += now() - hiddenStart;\n },\n falseVar\n );\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n var body = doc.body || {};\n var position = function () {\n try {\n var documentClientHeight = documentElement[clientHeight] || 0;\n var height = Math.max(\n body[scrollHeight] || 0,\n body[offsetHeight] || 0,\n documentElement[clientHeight] || 0,\n documentElement[scrollHeight] || 0,\n documentElement[offsetHeight] || 0\n );\n return Math.min(\n 100,\n Math.round(\n (100 * ((documentElement.scrollTop || 0) + documentClientHeight)) /\n height /\n 5\n ) * 5\n );\n } catch (error) {\n warn(error);\n return 0;\n }\n };\n\n addEventListenerFunc(\"load\", function () {\n scrolled = position();\n addEventListenerFunc(\n scroll,\n function () {\n if (scrolled < position()) scrolled = position();\n },\n falseVar\n );\n });\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n var pathOverwriterFunction = window[pathOverwriter];\n if (isFunction(pathOverwriterFunction)) {\n try {\n path = pathOverwriterFunction.call(window, { path: path }) || path;\n } catch (error) {\n warnInFunction(\"path\", error);\n }\n }\n\n // Ignore pages specified in data-ignore-pages\n if (shouldIgnore(path)) {\n warn(notSendingWhen + \"ignoring \" + path);\n return;\n }\n\n // Add hash to path when script is put in to hash mode\n if (mode == \"hash\" && loc.hash) path += loc.hash.split(\"?\")[0];\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n query,\n metadata,\n callback\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData(\n {\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: query || getQueryParams(deleteSourceInfo),\n\n metadata: stringify(metadata),\n },\n callback\n );\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (\n isPushState,\n pathOverwrite,\n metadata,\n callbackRaw\n ) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var querySearch;\n if (isString(pathOverwrite) && pathOverwrite.indexOf(\"?\") > -1) {\n // keep query from manual path\n var parts = pathOverwrite.split(\"?\");\n pathOverwrite = parts.shift();\n querySearch = \"?\" + parts.join(\"?\");\n }\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n // v = viewportsizes\n if (collectMetricByString(\"v\")) {\n page.viewport_width =\n Math.max(documentElement[clientWidth] || 0, window.innerWidth || 0) ||\n null;\n page.viewport_height =\n Math.max(\n documentElement[clientHeight] || 0,\n window.innerHeight || 0\n ) || null;\n }\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n // sc = screensizes\n if (screen && collectMetricByString(\"sc\")) {\n page.screen_width = screen.width;\n page.screen_height = screen.height;\n }\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n var currentReferrerHostname = referrer\n ? referrer.split(slash)[0]\n : undefinedVar;\n sameSite = referrer\n ? nonUniqueHostnames.indexOf(currentReferrerHostname) > -1 ||\n currentReferrerHostname == locationHostname\n : falseVar;\n\n // We set unique variable based on pushstate or back navigation, if no match we check the referrer\n page.unique =\n /__cf_/.test(getReferrer()) || isPushState || userNavigated\n ? falseVar\n : !sameSite;\n\n metadata = appendMetadata(metadata, {\n type: pageviewText,\n path: page.path,\n });\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n var delSrc =\n isPushState || userNavigated || !collectMetricByString(\"r\");\n sendPageView(\n isPushState,\n delSrc, // r = referrers\n sameSite,\n querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar,\n metadata,\n callback\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n /////////////////////\n // AUTOMATED PAGE VIEW COLLECTION\n //\n\n var his = window.history;\n var hisPushState = his ? his.pushState : undefinedVar;\n var dis = window.dispatchEvent;\n var pushStateText = \"pushState\";\n\n // Overwrite history pushState function to\n // allow listening on the pushState event\n if (autoCollect && hisPushState && Event && dis) {\n var stateListener = function (type) {\n var orig = his[type];\n return function () {\n var arg = arguments;\n var rv = orig.apply(this, arg);\n var event;\n if (isFunction(Event)) {\n event = new Event(type);\n } else {\n // Fix for IE\n // https://github.com/simpleanalytics/scripts/issues/8\n event = doc.createEvent(\"Event\");\n event.initEvent(type, trueVar, trueVar);\n }\n event.arguments = arg;\n dis(event);\n return rv;\n };\n };\n\n his.pushState = stateListener(pushStateText);\n\n addEventListenerFunc(\n pushStateText,\n function () {\n pageview(1);\n },\n falseVar\n );\n\n addEventListenerFunc(\n \"popstate\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n // When in hash mode, we record a pageview based on the onhashchange function\n if (autoCollect && mode == \"hash\" && \"onhashchange\" in window) {\n addEventListenerFunc(\n \"hashchange\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n if (autoCollect) pageview();\n\n window.sa_pageview = function (path, metadata, callback) {\n pageview(0, path, metadata, callback);\n };\n\n\n /////////////////////\n // EVENTS\n //\n\n var validTypes = [\"string\", \"number\"];\n\n var sendEvent = function (event, metadata, callbackRaw) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n\n var eventIsFunction = isFunction(event);\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var eventType = typeof event;\n\n if (validTypes.indexOf(eventType) < 0 && !eventIsFunction) {\n warnInFunction(eventFunctionName, eventText + \" can't be \" + eventType);\n return callback();\n }\n\n try {\n if (eventIsFunction) {\n var eventOutput = event();\n if (validTypes.indexOf(typeof eventOutput) < 0) {\n warnInFunction(\n eventFunctionName,\n event + \" returns no string: \" + eventOutput\n );\n return callback();\n }\n event = eventOutput;\n }\n } catch (error) {\n warnInFunction(eventFunctionName, error);\n return callback();\n }\n\n event = (\"\" + event).replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_|_$)/g, \"\");\n\n var eventParams = { type: eventText, event: event };\n var firstPage = !userNavigated && pages < 2;\n\n metadata = appendMetadata(metadata, eventParams);\n\n if (event) {\n sendData(\n assign(eventParams, {\n id: uuid(),\n query: getQueryParams(!firstPage),\n referrer:\n (firstPage || sameSite) && collectMetricByString(\"r\")\n ? previousReferrer\n : null,\n\n metadata: stringify(metadata),\n }),\n callback\n );\n }\n };\n\n var defaultEventFunc = function (event, metadata, callback) {\n sendEvent(event, metadata, callback);\n };\n\n // Set default function if user didn't define a function\n if (!window[eventFunctionName])\n window[eventFunctionName] = defaultEventFunc;\n\n var eventFunc = window[eventFunctionName];\n\n // Read queue of the user defined function\n var queue = eventFunc && eventFunc.q ? eventFunc.q : [];\n\n // Overwrite user defined function\n window[eventFunctionName] = defaultEventFunc;\n\n // Post events from the queue of the user defined function\n for (var event in queue) {\n if (hasProp(queue, event)) {\n Array.isArray(queue[event])\n ? sendEvent.apply(null, queue[event])\n : sendEvent(queue[event]);\n }\n }\n } catch (e) {\n sendError(e);\n }\n})(\n window,\n {},\n \"\",\n \"\",\n \"custom_events_12\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","sendError","warn","undefinedVar","undefined","trueVar","falseVar","trueText","https","pageviewText","eventText","errorText","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","notSendingWhen","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","documentElement","language","Height","scroll","uaData","userAgentData","scrollHeight","offsetHeight","clientHeight","pagehide","platformText","platformVersionText","docsUrl","pages","isBotAgent","test","screen","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","warnInFunction","name","error","hasProp","obj","prop","Object","hasOwnProperty","isString","string","filterRegex","item","replace","attr","attribute","getAttribute","convertCommaSeparatedToArray","csv","Array","isArray","length","split","isObject","object","constructor","assign","to","arg","index","nextSource","nextKey","settings","sa_settings","logSettings","keys","ignoreMetrics","collectMetricByString","metricAbbreviation","filter","RegExp","now","Date","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","c","getRandomValues","Uint8Array","toString","r","Math","random","isFunction","func","namespaceText","namespace","appendMetadata","metadata","data","metadataObject","metadataCollectorFunction","metadataCollector","strictUtm","getQueryParams","ignoreSource","overwriteSearch","search","keyValue","ignore","paramsRegexList","allowParams","map","join","regex","loadedVariable","sa_event_loaded","sendData","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","image","Image","onerror","onload","src","key","overwrittenHostname","hostname","definedHostname","basePayload","version","errorOrMessage","stack","type","path","pathname","event","filename","indexOf","message","timezone","start","scrolled","mode","collectDnt","value","autoCollect","eventFunctionName","saGlobal","ignorePages","nonUniqueHostnames","pathOverwriter","Intl","DateTimeFormat","resolvedOptions","timeZone","phantom","bot","webdriver","__nightmare","callPhantom","_phantom","solana","__polypane","_bot","collectDataOnLeave","ua","protocol","page_id","session_id","sri","mobile","brands","doctype","hostname_original","lastSendPath","hiddenStart","getReferrer","referrer","msHidden","sendOnLeave","id","push","append","original_id","duration","round","max","position","sendBeacon","bind","e","hidden","body","documentClientHeight","height","min","scrollTop","previousReferrer","sameSite","userNavigated","getPath","overwrite","pathOverwriterFunction","i","ignorePageRaw","ignorePage","shouldIgnore","hash","pageview","isPushState","pathOverwrite","callbackRaw","querySearch","parts","shift","viewport_width","innerWidth","viewport_height","innerHeight","screen_width","width","screen_height","performaceEntryType","perf","performance","navigationText","getEntriesByType","currentReferrerHostname","unique","triggerSendPageView","delSrc","deleteSourceInfo","query","currentPage","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","his","history","hisPushState","pushState","dis","dispatchEvent","pushStateText","Event","orig","rv","this","createEvent","initEvent","sa_pageview","validTypes","sendEvent","eventIsFunction","eventType","eventOutput","eventParams","firstPage","defaultEventFunc","eventFunc","queue","q"],"mappings":"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"} \ No newline at end of file diff --git a/dist/latest/custom/latest.dev.js b/dist/latest/custom/latest.dev.js index 51d316c7..d6777e9d 100644 --- a/dist/latest/custom/latest.dev.js +++ b/dist/latest/custom/latest.dev.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy friendly analytics (docs.simpleanalytics.com/script; 2023-05-03; 761d; v11) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; 67c4; v12) */ /* eslint-env browser */ (function ( @@ -110,8 +110,8 @@ return Array.isArray(csv) ? csv : isString(csv) && csv.length - ? csv.split(/, ?/) - : []; + ? csv.split(/, ?/) + : []; }; var isObject = function (object) { @@ -191,11 +191,17 @@ attr(scriptElement, namespaceText) || defaultNamespace; - var metadataObject = window[namespace + "_metadata"]; var appendMetadata = function (metadata, data) { + var metadataObject = window[namespace + "_metadata"]; if (isObject(metadataObject)) metadata = assign(metadata, metadataObject); var metadataCollectorFunction = window[metadataCollector]; - if (!isFunction(metadataCollectorFunction)) return metadata; + if (!isFunction(metadataCollectorFunction)) { + if (metadataCollector) + warn( + metadataCollector + " not found, set window." + metadataCollector + ); + return metadata; + } try { return assign( metadata, @@ -216,9 +222,9 @@ overwriteOptions.strictUtm || attr(scriptElement, "strict-utm") == trueText; - var getQueryParams = function (ignoreSource) { + var getQueryParams = function (ignoreSource, overwriteSearch) { return ( - loc.search + (overwriteSearch || loc.search) .slice(1) .split("&") .filter(function (keyValue) { @@ -432,12 +438,13 @@ // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS // + var phantom = window.phantom; var bot = nav.webdriver || window.__nightmare || window.callPhantom || window._phantom || - window.phantom || + (phantom && !phantom.solana) || window.__polypane || window._bot || isBotAgent || @@ -512,8 +519,12 @@ var lastSendPath; var getReferrer = function () { + // Customers can overwrite their referrer, here we check for that + var overwrittenReferrer = + overwriteOptions.referrer || attr(scriptElement, "referrer"); + return ( - (doc.referrer || "") + (overwrittenReferrer || doc.referrer || "") .replace(locationHostname, definedHostname) .replace(/^https?:\/\/((m|l|w{2,3}([0-9]+)?)\.)?([^?#]+)(.*)$/, "$4") .replace(/^([^/]+)$/, "$1") || undefinedVar @@ -554,7 +565,12 @@ // sendData will assign payload to request sendData(append, undefinedVar, trueVar); } else { - nav.sendBeacon(fullApiUrl + "/append", stringify(append)); + try { + nav.sendBeacon.bind(nav)(fullApiUrl + "/append", stringify(append)); + } catch (e) { + // Fallback for browsers throwing "Illegal invocation" when the URL is invalid + sendData(append, undefinedVar, trueVar); + } } }; @@ -651,21 +667,26 @@ isPushState, deleteSourceInfo, sameSite, - metadata + query, + metadata, + callback ) { if (isPushState) sendOnLeave("" + payload.page_id, trueVar); if (collectDataOnLeave) payload.page_id = uuid(); var currentPage = definedHostname + getPath(); - sendData({ - id: payload.page_id, - type: pageviewText, - referrer: !deleteSourceInfo || sameSite ? referrer : null, - query: getQueryParams(deleteSourceInfo), + sendData( + { + id: payload.page_id, + type: pageviewText, + referrer: !deleteSourceInfo || sameSite ? referrer : null, + query: query || getQueryParams(deleteSourceInfo), - metadata: stringify(metadata), - }); + metadata: stringify(metadata), + }, + callback + ); previousReferrer = referrer; referrer = currentPage; @@ -675,7 +696,21 @@ var sameSite, userNavigated; - var pageview = function (isPushState, pathOverwrite, metadata) { + var pageview = function ( + isPushState, + pathOverwrite, + metadata, + callbackRaw + ) { + if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata; + var callback = isFunction(callbackRaw) ? callbackRaw : function () {}; + var querySearch; + if (isString(pathOverwrite) && pathOverwrite.indexOf("?") > -1) { + // keep query from manual path + var parts = pathOverwrite.split("?"); + pathOverwrite = parts.shift(); + querySearch = "?" + parts.join("?"); + } // Obfuscate personal data in URL by dropping the search and hash var path = getPath(pathOverwrite); @@ -738,7 +773,10 @@ : falseVar; // We set unique variable based on pushstate or back navigation, if no match we check the referrer - page.unique = isPushState || userNavigated ? falseVar : !sameSite; + page.unique = + /__cf_/.test(getReferrer()) || isPushState || userNavigated + ? falseVar + : !sameSite; metadata = appendMetadata(metadata, { type: pageviewText, @@ -747,11 +785,15 @@ var triggerSendPageView = function () { fetchedHighEntropyValues = trueVar; + var delSrc = + isPushState || userNavigated || !collectMetricByString("r"); sendPageView( isPushState, - isPushState || userNavigated || !collectMetricByString("r"), // r = referrers + delSrc, // r = referrers sameSite, - metadata + querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar, + metadata, + callback ); }; @@ -841,11 +883,11 @@ } if (autoCollect) pageview(); - else { - window.sa_pageview = function (path, metadata) { - pageview(0, path, metadata); - }; - } + + window.sa_pageview = function (path, metadata, callback) { + pageview(0, path, metadata, callback); + }; + ///////////////////// // EVENTS @@ -938,6 +980,6 @@ {}, "", "", - "custom_latest_dev_11", + "custom_latest_dev_12", "sa" ); diff --git a/dist/latest/custom/latest.js b/dist/latest/custom/latest.js index 003984e2..ab7344a2 100644 --- a/dist/latest/custom/latest.js +++ b/dist/latest/custom/latest.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy friendly analytics (docs.simpleanalytics.com/script; 2023-05-03; b8c6; v11) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; 019f; v12) */ -!function(l,t,e,n,p){try{var h=undefined,f=!0,d=!1,r="true",a="https:",m="pageview",u="event",i="error",o=l.console,c="doNotTrack",g=l.navigator,s=l.location,v=s.host,y=l.document,_=g.userAgent,w="Not sending request ",b=w+"when ",E=d,O=encodeURIComponent,x=decodeURIComponent,S=JSON.stringify,M=l.addEventListener,k="https://"+e,A=y.documentElement||{},q="language",$="Height",j="scroll",D=g.userAgentData,C=j+$,H="offset"+$,R="client"+$,P="pagehide",T="platform",U="platformVersion",I="https://docs.simpleanalytics.com",V=0,B=/(bot|spider|crawl)/i.test(_)&&!/(cubot)/i.test(_),N=l.screen,z=y.currentScript||y.querySelector('script[src*="'+e+'"]');p=function(){var t=[].slice.call(arguments);return t.unshift("Simple Analytics:"),Function.prototype.apply.call(o.warn,o,t)};var F=function(t,e){p("Error in your "+t+" function:",e)},W=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},G=function(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},J=function(t,e){return t&&t.getAttribute("data-"+e)},L=function(t){return Array.isArray(t)?t:"string"==typeof t&&t.length?t.split(/, ?/):[]},Y=function(t){return t&&t.constructor===Object},Z=function(){for(var t={},e=arguments,n=0;n>t/4).toString(16)})}catch(r){return t.replace(n,function(t){var e=16*Math.random()|0;return(t<2?e:3&e|8).toString(16)})}},rt=function(t){return"function"==typeof t},at="namespace",it=t[at]||J(z,at)||"sa",ot=l[it+"_metadata"],ct=function(t,e){Y(ot)&&(t=Z(t,ot));var n=l[Mt];if(!rt(n))return t;try{return Z(t,n.call(l,Z(t,e)))}catch(r){F("metadata",r)}},st=t.strictUtm||J(z,"strict-utm")==r,ut=function(a){return s.search.slice(1).split("&").filter(function(t){var e=a||!tt("ut"),n=Ot.map(G).join("|"),r=e?"^("+n+")=":"^((utm_)"+(st?"":"?")+"(source|medium|content|term|campaign)"+(st?"":"|ref")+"|"+n+")=";return e&&!Ot.length?d:new RegExp(r).test(t)}).join("&")||h},lt=it+"_loaded";if(l[lt]==f)return p(w+"twice");l.sa_event_loaded=f,l[lt]=f;var pt=function(e,t,n){e=n?e:Z(qt,Dt,e),g.brave&&!n&&(e.brave=f),g._duckduckgoloader_&&!n&&(e.duck=f);var r=new Image;t&&(r.onerror=t,r.onload=t),r.src=k+"/simple.gif?"+Object.keys(e).filter(function(t){return e[t]!=h}).map(function(t){return O(t)+"="+O(e[t])}).join("&")+"&time="+Date.now()},ht=t.hostname||J(z,"hostname"),ft=ht||v,dt={version:"custom_latest_11",hostname:ft};n=function(t){t=t.stack?t+" "+t.stack:t,p(t),pt(Z(dt,{type:i,error:t,path:s.pathname}),h,f)},M(i,function(t){t.filename&&-1"); +!function(d,t,e,n,m){try{var g=undefined,v=!0,y=!1,r="true",a="https:",_="pageview",u="event",i="error",o=d.console,c="doNotTrack",w=d.navigator,s=d.location,b=s.host,l=d.document,p=w.userAgent,f="Not sending request ",h=f+"when ",O=y,E=encodeURIComponent,x=decodeURIComponent,S=JSON.stringify,M=d.addEventListener,k="https://"+e,A=l.documentElement||{},q="language",$="Height",j="scroll",D=w.userAgentData,C=j+$,H="offset"+$,R="client"+$,P="pagehide",T="platform",U="platformVersion",I="https://docs.simpleanalytics.com",V=0,B=/(bot|spider|crawl)/i.test(p)&&!/(cubot)/i.test(p),N=d.screen,z=l.currentScript||l.querySelector('script[src*="'+e+'"]');m=function(){var t=[].slice.call(arguments);return t.unshift("Simple Analytics:"),Function.prototype.apply.call(o.warn,o,t)};var F=function(t,e){m("Error in your "+t+" function:",e)},W=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},G=function(t){return"string"==typeof t},J=function(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},L=function(t,e){return t&&t.getAttribute("data-"+e)},Y=function(t){return Array.isArray(t)?t:G(t)&&t.length?t.split(/, ?/):[]},Z=function(t){return t&&t.constructor===Object},K=function(){for(var t={},e=arguments,n=0;n>t/4).toString(16)})}catch(r){return t.replace(n,function(t){var e=16*Math.random()|0;return(t<2?e:3&e|8).toString(16)})}},at=function(t){return"function"==typeof t},it="namespace",ot=t[it]||L(z,it)||"sa",ct=function(t,e){var n=d[ot+"_metadata"];Z(n)&&(t=K(t,n));var r=d[Mt];if(!at(r))return Mt&&m(Mt+" not found, set window."+Mt),t;try{return K(t,r.call(d,K(t,e)))}catch(a){F("metadata",a)}},st=t.strictUtm||L(z,"strict-utm")==r,ut=function(a,t){return(t||s.search).slice(1).split("&").filter(function(t){var e=a||!et("ut"),n=Et.map(J).join("|"),r=e?"^("+n+")=":"^((utm_)"+(st?"":"?")+"(source|medium|content|term|campaign)"+(st?"":"|ref")+"|"+n+")=";return e&&!Et.length?y:new RegExp(r).test(t)}).join("&")||g},lt=ot+"_loaded";if(d[lt]==v)return m(f+"twice");d.sa_event_loaded=v,d[lt]=v;var pt=function(e,t,n){e=n?e:K($t,Ct,e),w.brave&&!n&&(e.brave=v),w._duckduckgoloader_&&!n&&(e.duck=v);var r=new Image;t&&(r.onerror=t,r.onload=t),r.src=k+"/simple.gif?"+Object.keys(e).filter(function(t){return e[t]!=g}).map(function(t){return E(t)+"="+E(e[t])}).join("&")+"&time="+Date.now()},ft=t.hostname||L(z,"hostname"),ht=ft||b,dt={version:"custom_latest_12",hostname:ht};n=function(t){t=t.stack?t+" "+t.stack:t,m(t),pt(K(dt,{type:i,error:t,path:s.pathname}),g,v)},M(i,function(t){t.filename&&-1"); //# sourceMappingURL=latest.js.map \ No newline at end of file diff --git a/dist/latest/custom/latest.js.map b/dist/latest/custom/latest.js.map index f5c01b23..5113f1bc 100644 --- a/dist/latest/custom/latest.js.map +++ b/dist/latest/custom/latest.js.map @@ -1 +1 @@ -{"version":3,"file":"latest.source.js","sources":["latest.source.js"],"sourcesContent":["/* eslint-env browser */\n\n(function (\n window,\n overwriteOptions,\n baseUrl,\n apiUrlPrefix,\n version,\n defaultNamespace,\n sendError,\n warn\n) {\n try {\n /////////////////////\n // PREDEFINED VARIABLES FOR BETTER MINIFICATION\n //\n\n // This seems like a lot of repetition, but it makes our script available for\n // multple destination which prevents us to need multiple scripts. The minified\n // version stays small.\n var undefinedVar = undefined;\n var trueVar = true;\n var falseVar = false;\n var trueText = \"true\";\n var https = \"https:\";\n var pageviewText = \"pageview\";\n var eventText = \"event\";\n var errorText = \"error\";\n var slash = \"/\";\n var protocol = https + \"//\";\n var con = window.console;\n var doNotTrack = \"doNotTrack\";\n var nav = window.navigator;\n var loc = window.location;\n var locationHostname = loc.host;\n var doc = window.document;\n var userAgent = nav.userAgent;\n var notSending = \"Not sending request \";\n var notSendingWhen = notSending + \"when \";\n var fetchedHighEntropyValues = falseVar;\n var encodeURIComponentFunc = encodeURIComponent;\n var decodeURIComponentFunc = decodeURIComponent;\n var stringify = JSON.stringify;\n var thousand = 1000;\n var addEventListenerFunc = window.addEventListener;\n var fullApiUrl = protocol + apiUrlPrefix + baseUrl;\n var documentElement = doc.documentElement || {};\n var language = \"language\";\n var Height = \"Height\";\n var Width = \"Width\";\n var scroll = \"scroll\";\n var uaData = nav.userAgentData;\n var scrollHeight = scroll + Height;\n var offsetHeight = \"offset\" + Height;\n var clientHeight = \"client\" + Height;\n var clientWidth = \"client\" + Width;\n var pagehide = \"pagehide\";\n var platformText = \"platform\";\n var platformVersionText = \"platformVersion\";\n var docsUrl = \"https://docs.simpleanalytics.com\";\n var pages = 0;\n var isBotAgent =\n /(bot|spider|crawl)/i.test(userAgent) && !/(cubot)/i.test(userAgent);\n var screen = window.screen;\n\n\n // Find the script element where options can be set on\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"' + baseUrl + '\"]');\n\n /////////////////////\n // HELPER FUNCTIONS\n //\n\n // A simple log function so the user knows why a request is not being send\n warn = function () {\n // 1. Convert args to a normal array\n var args = [].slice.call(arguments);\n\n // 2. Prepend log prefix\n args.unshift(\"Simple Analytics:\");\n\n // 3. Pass along arguments to console.warn\n // Function.prototype.apply.call is needed for Internet Explorer\n return Function.prototype.apply.call(con.warn, con, args);\n };\n\n var warnInFunction = function (name, error) {\n warn(\"Error in your \" + name + \" function:\", error);\n };\n\n var hasProp = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n\n var isString = function (string) {\n return typeof string == \"string\";\n };\n\n var filterRegex = function (item) {\n return item.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n var attr = function (scriptElement, attribute) {\n return scriptElement && scriptElement.getAttribute(\"data-\" + attribute);\n };\n\n var convertCommaSeparatedToArray = function (csv) {\n return Array.isArray(csv)\n ? csv\n : isString(csv) && csv.length\n ? csv.split(/, ?/)\n : [];\n };\n\n var isObject = function (object) {\n return object && object.constructor === Object;\n };\n\n var assign = function () {\n var to = {};\n var arg = arguments;\n for (var index = 0; index < arg.length; index++) {\n var nextSource = arg[index];\n if (isObject(nextSource)) {\n for (var nextKey in nextSource) {\n if (hasProp(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n\n var settings = window.sa_settings;\n var logSettings = settings || Object.keys(overwriteOptions).length;\n\n // Merge overwriteOptions with sa_settings\n overwriteOptions = assign(overwriteOptions, settings);\n\n if (logSettings) warn(\"Settings\", overwriteOptions);\n\n // Customers can skip data points\n var ignoreMetrics = convertCommaSeparatedToArray(\n overwriteOptions.ignoreMetrics || attr(scriptElement, \"ignore-metrics\")\n );\n\n var collectMetricByString = function (metricAbbreviation) {\n // Can't use Array.find() here because we need to support IE9\n return (\n ignoreMetrics.filter(function (item) {\n return new RegExp(\"^\" + metricAbbreviation).test(item);\n }).length === 0\n );\n };\n\n var now = Date.now;\n\n var uuid = function () {\n var cryptoObject = window.crypto || window.msCrypto;\n var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;\n var uuidRegex = /[018]/g;\n\n try {\n return emptyUUID.replace(uuidRegex, function (c) {\n return (\n c ^\n (cryptoObject.getRandomValues(new Uint8Array(1))[0] &\n (15 >> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n var metadataObject = window[namespace + \"_metadata\"];\n var appendMetadata = function (metadata, data) {\n if (isObject(metadataObject)) metadata = assign(metadata, metadataObject);\n var metadataCollectorFunction = window[metadataCollector];\n if (!isFunction(metadataCollectorFunction)) return metadata;\n try {\n return assign(\n metadata,\n metadataCollectorFunction.call(window, assign(metadata, data))\n );\n } catch (error) {\n warnInFunction(\"metadata\", error);\n }\n };\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource) {\n return (\n loc.search\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n var paramsRegexList = allowParams.map(filterRegex).join(\"|\");\n var regex = ignore\n ? \"^(\" + paramsRegexList + \")=\"\n : \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \"|\" +\n paramsRegexList +\n \")=\";\n if (ignore && !allowParams.length) return falseVar;\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n // Ignore pages specified in data-ignore-pages\n var shouldIgnore = function (path) {\n for (var i in ignorePages) {\n var ignorePageRaw = ignorePages[i];\n if (!ignorePageRaw) continue;\n\n // Prepend a slash when it's missing\n var ignorePage =\n ignorePageRaw[0] == slash ? ignorePageRaw : slash + ignorePageRaw;\n\n if (\n ignorePage === path ||\n new RegExp(\n \"^\" + filterRegex(ignorePage).replace(/\\\\\\*/gi, \"(.*)\") + \"$\",\n \"i\"\n ).test(path)\n )\n return trueVar;\n }\n return falseVar;\n };\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n if (callback) {\n image.onerror = callback;\n image.onload = callback;\n }\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n /////////////////////\n // ERROR FUNCTIONS\n //\n\n // Send errors\n // no var because it's scoped outside of the try/catch\n sendError = function (errorOrMessage) {\n errorOrMessage = errorOrMessage.stack\n ? errorOrMessage + \" \" + errorOrMessage.stack\n : errorOrMessage;\n warn(errorOrMessage);\n sendData(\n assign(basePayload, {\n type: errorText,\n error: errorOrMessage,\n path: loc.pathname,\n }),\n undefinedVar,\n trueVar\n );\n };\n\n // We listen for the error events and only send errors that are\n // from our script (checked by filename) to our server.\n addEventListenerFunc(\n errorText,\n function (event) {\n if (event.filename && event.filename.indexOf(baseUrl) > -1) {\n sendError(event.message);\n }\n },\n falseVar\n );\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n var start = now();\n\n var scrolled = 0;\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n // Should we record Do Not Track visits?\n var collectDnt = isBoolean(overwriteOptions.collectDnt)\n ? overwriteOptions.collectDnt\n : attr(scriptElement, \"ignore-dnt\") == trueText ||\n attr(scriptElement, \"skip-dnt\") == trueText ||\n attr(scriptElement, \"collect-dnt\") == trueText;\n\n // Some customers want to collect page views manually\n var autoCollect = !(\n attr(scriptElement, \"auto-collect\") == \"false\" ||\n overwriteOptions.autoCollect === falseVar\n );\n\n // Event function name\n var eventFunctionName =\n overwriteOptions.saGlobal ||\n attr(scriptElement, \"sa-global\") ||\n namespace + \"_\" + eventText;\n\n // Customers can ignore certain pages\n var ignorePages = convertCommaSeparatedToArray(\n overwriteOptions.ignorePages || attr(scriptElement, \"ignore-pages\")\n );\n\n // Customers can allow params\n var allowParams = convertCommaSeparatedToArray(\n overwriteOptions.allowParams || attr(scriptElement, \"allow-params\")\n );\n\n // Customers can allow params\n var nonUniqueHostnames = convertCommaSeparatedToArray(\n overwriteOptions.nonUniqueHostnames ||\n attr(scriptElement, \"non-unique-hostnames\")\n );\n\n // Customers can overwrite certain values\n var pathOverwriter =\n overwriteOptions.pathOverwriter || attr(scriptElement, \"path-overwriter\");\n\n // Customers can add metadata to events and pageviews via a function\n var metadataCollector =\n overwriteOptions.metadataCollector ||\n attr(scriptElement, \"metadata-collector\");\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var bot =\n nav.webdriver ||\n window.__nightmare ||\n window.callPhantom ||\n window._phantom ||\n window.phantom ||\n window.__polypane ||\n window._bot ||\n isBotAgent ||\n Math.random() == Math.random();\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = falseVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n // Warn when no document.doctype is defined (this breaks some documentElement dimensions)\n if (!doc.doctype) warn(\"Add DOCTYPE html for accurate dimensions\");\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (!collectDnt && doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n return (\n (doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n // t = timeonpage\n if (collectMetricByString(\"t\")) {\n append.duration = Math.round((now() - start - msHidden) / thousand);\n }\n msHidden = 0;\n start = now();\n\n // scro = scrolled\n if (collectMetricByString(\"scro\")) {\n append.scrolled = Math.max(0, scrolled, position());\n }\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n nav.sendBeacon(fullApiUrl + \"/append\", stringify(append));\n }\n };\n\n var hiddenStart;\n addEventListenerFunc(\n \"visibilitychange\",\n function () {\n if (doc.hidden) {\n if (!(\"on\" + pagehide in window)) sendOnLeave();\n hiddenStart = now();\n } else msHidden += now() - hiddenStart;\n },\n falseVar\n );\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n var body = doc.body || {};\n var position = function () {\n try {\n var documentClientHeight = documentElement[clientHeight] || 0;\n var height = Math.max(\n body[scrollHeight] || 0,\n body[offsetHeight] || 0,\n documentElement[clientHeight] || 0,\n documentElement[scrollHeight] || 0,\n documentElement[offsetHeight] || 0\n );\n return Math.min(\n 100,\n Math.round(\n (100 * ((documentElement.scrollTop || 0) + documentClientHeight)) /\n height /\n 5\n ) * 5\n );\n } catch (error) {\n warn(error);\n return 0;\n }\n };\n\n addEventListenerFunc(\"load\", function () {\n scrolled = position();\n addEventListenerFunc(\n scroll,\n function () {\n if (scrolled < position()) scrolled = position();\n },\n falseVar\n );\n });\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n var pathOverwriterFunction = window[pathOverwriter];\n if (isFunction(pathOverwriterFunction)) {\n try {\n path = pathOverwriterFunction.call(window, { path: path }) || path;\n } catch (error) {\n warnInFunction(\"path\", error);\n }\n }\n\n // Ignore pages specified in data-ignore-pages\n if (shouldIgnore(path)) {\n warn(notSendingWhen + \"ignoring \" + path);\n return;\n }\n\n // Add hash to path when script is put in to hash mode\n if (mode == \"hash\" && loc.hash) path += loc.hash.split(\"?\")[0];\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n metadata\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData({\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: getQueryParams(deleteSourceInfo),\n\n metadata: stringify(metadata),\n });\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (isPushState, pathOverwrite, metadata) {\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n // v = viewportsizes\n if (collectMetricByString(\"v\")) {\n page.viewport_width =\n Math.max(documentElement[clientWidth] || 0, window.innerWidth || 0) ||\n null;\n page.viewport_height =\n Math.max(\n documentElement[clientHeight] || 0,\n window.innerHeight || 0\n ) || null;\n }\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n // sc = screensizes\n if (screen && collectMetricByString(\"sc\")) {\n page.screen_width = screen.width;\n page.screen_height = screen.height;\n }\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n var currentReferrerHostname = referrer\n ? referrer.split(slash)[0]\n : undefinedVar;\n sameSite = referrer\n ? nonUniqueHostnames.indexOf(currentReferrerHostname) > -1 ||\n currentReferrerHostname == locationHostname\n : falseVar;\n\n // We set unique variable based on pushstate or back navigation, if no match we check the referrer\n page.unique = isPushState || userNavigated ? falseVar : !sameSite;\n\n metadata = appendMetadata(metadata, {\n type: pageviewText,\n path: page.path,\n });\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n sendPageView(\n isPushState,\n isPushState || userNavigated || !collectMetricByString(\"r\"), // r = referrers\n sameSite,\n metadata\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n /////////////////////\n // AUTOMATED PAGE VIEW COLLECTION\n //\n\n var his = window.history;\n var hisPushState = his ? his.pushState : undefinedVar;\n var dis = window.dispatchEvent;\n var pushStateText = \"pushState\";\n\n // Overwrite history pushState function to\n // allow listening on the pushState event\n if (autoCollect && hisPushState && Event && dis) {\n var stateListener = function (type) {\n var orig = his[type];\n return function () {\n var arg = arguments;\n var rv = orig.apply(this, arg);\n var event;\n if (isFunction(Event)) {\n event = new Event(type);\n } else {\n // Fix for IE\n // https://github.com/simpleanalytics/scripts/issues/8\n event = doc.createEvent(\"Event\");\n event.initEvent(type, trueVar, trueVar);\n }\n event.arguments = arg;\n dis(event);\n return rv;\n };\n };\n\n his.pushState = stateListener(pushStateText);\n\n addEventListenerFunc(\n pushStateText,\n function () {\n pageview(1);\n },\n falseVar\n );\n\n addEventListenerFunc(\n \"popstate\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n // When in hash mode, we record a pageview based on the onhashchange function\n if (autoCollect && mode == \"hash\" && \"onhashchange\" in window) {\n addEventListenerFunc(\n \"hashchange\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n if (autoCollect) pageview();\n else {\n window.sa_pageview = function (path, metadata) {\n pageview(0, path, metadata);\n };\n }\n\n /////////////////////\n // EVENTS\n //\n\n var validTypes = [\"string\", \"number\"];\n\n var sendEvent = function (event, metadata, callbackRaw) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n\n var eventIsFunction = isFunction(event);\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var eventType = typeof event;\n\n if (validTypes.indexOf(eventType) < 0 && !eventIsFunction) {\n warnInFunction(eventFunctionName, eventText + \" can't be \" + eventType);\n return callback();\n }\n\n try {\n if (eventIsFunction) {\n var eventOutput = event();\n if (validTypes.indexOf(typeof eventOutput) < 0) {\n warnInFunction(\n eventFunctionName,\n event + \" returns no string: \" + eventOutput\n );\n return callback();\n }\n event = eventOutput;\n }\n } catch (error) {\n warnInFunction(eventFunctionName, error);\n return callback();\n }\n\n event = (\"\" + event).replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_|_$)/g, \"\");\n\n var eventParams = { type: eventText, event: event };\n var firstPage = !userNavigated && pages < 2;\n\n metadata = appendMetadata(metadata, eventParams);\n\n if (event) {\n sendData(\n assign(eventParams, {\n id: uuid(),\n query: getQueryParams(!firstPage),\n referrer:\n (firstPage || sameSite) && collectMetricByString(\"r\")\n ? previousReferrer\n : null,\n\n metadata: stringify(metadata),\n }),\n callback\n );\n }\n };\n\n var defaultEventFunc = function (event, metadata, callback) {\n sendEvent(event, metadata, callback);\n };\n\n // Set default function if user didn't define a function\n if (!window[eventFunctionName])\n window[eventFunctionName] = defaultEventFunc;\n\n var eventFunc = window[eventFunctionName];\n\n // Read queue of the user defined function\n var queue = eventFunc && eventFunc.q ? eventFunc.q : [];\n\n // Overwrite user defined function\n window[eventFunctionName] = defaultEventFunc;\n\n // Post events from the queue of the user defined function\n for (var event in queue) {\n if (hasProp(queue, event)) {\n Array.isArray(queue[event])\n ? sendEvent.apply(null, queue[event])\n : sendEvent(queue[event]);\n }\n }\n } catch (e) {\n sendError(e);\n }\n})(\n window,\n {},\n \"\",\n \"\",\n \"custom_latest_11\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","sendError","warn","undefinedVar","undefined","trueVar","falseVar","trueText","https","pageviewText","eventText","errorText","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","notSendingWhen","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","documentElement","language","Height","scroll","uaData","userAgentData","scrollHeight","offsetHeight","clientHeight","pagehide","platformText","platformVersionText","docsUrl","pages","isBotAgent","test","screen","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","warnInFunction","name","error","hasProp","obj","prop","Object","hasOwnProperty","filterRegex","item","replace","attr","attribute","getAttribute","convertCommaSeparatedToArray","csv","Array","isArray","length","split","isObject","object","constructor","assign","to","arg","index","nextSource","nextKey","settings","sa_settings","logSettings","keys","ignoreMetrics","collectMetricByString","metricAbbreviation","filter","RegExp","now","Date","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","c","getRandomValues","Uint8Array","toString","r","Math","random","isFunction","func","namespaceText","namespace","metadataObject","appendMetadata","metadata","data","metadataCollectorFunction","metadataCollector","strictUtm","getQueryParams","ignoreSource","search","keyValue","ignore","paramsRegexList","allowParams","map","join","regex","loadedVariable","sa_event_loaded","sendData","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","image","Image","onerror","onload","src","key","overwrittenHostname","hostname","definedHostname","basePayload","version","errorOrMessage","stack","type","path","pathname","event","filename","indexOf","message","timezone","start","scrolled","mode","collectDnt","value","autoCollect","eventFunctionName","saGlobal","ignorePages","nonUniqueHostnames","pathOverwriter","Intl","DateTimeFormat","resolvedOptions","timeZone","bot","webdriver","__nightmare","callPhantom","_phantom","phantom","__polypane","_bot","collectDataOnLeave","ua","protocol","page_id","session_id","sri","mobile","brands","doctype","hostname_original","lastSendPath","hiddenStart","referrer","msHidden","sendOnLeave","id","push","append","original_id","duration","round","max","position","sendBeacon","hidden","body","documentClientHeight","height","min","scrollTop","previousReferrer","sameSite","userNavigated","getPath","overwrite","pathOverwriterFunction","i","ignorePageRaw","ignorePage","shouldIgnore","hash","pageview","isPushState","pathOverwrite","viewport_width","innerWidth","viewport_height","innerHeight","screen_width","width","screen_height","performaceEntryType","perf","performance","navigationText","getEntriesByType","currentReferrerHostname","unique","triggerSendPageView","deleteSourceInfo","currentPage","query","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","e","his","history","hisPushState","pushState","dis","dispatchEvent","pushStateText","Event","orig","rv","this","createEvent","initEvent","sa_pageview","validTypes","sendEvent","callbackRaw","eventIsFunction","eventType","eventOutput","eventParams","firstPage","defaultEventFunc","eventFunc","queue","q"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"latest.source.js","sources":["latest.source.js"],"sourcesContent":["/* eslint-env browser */\n\n(function (\n window,\n overwriteOptions,\n baseUrl,\n apiUrlPrefix,\n version,\n defaultNamespace,\n sendError,\n warn\n) {\n try {\n /////////////////////\n // PREDEFINED VARIABLES FOR BETTER MINIFICATION\n //\n\n // This seems like a lot of repetition, but it makes our script available for\n // multple destination which prevents us to need multiple scripts. The minified\n // version stays small.\n var undefinedVar = undefined;\n var trueVar = true;\n var falseVar = false;\n var trueText = \"true\";\n var https = \"https:\";\n var pageviewText = \"pageview\";\n var eventText = \"event\";\n var errorText = \"error\";\n var slash = \"/\";\n var protocol = https + \"//\";\n var con = window.console;\n var doNotTrack = \"doNotTrack\";\n var nav = window.navigator;\n var loc = window.location;\n var locationHostname = loc.host;\n var doc = window.document;\n var userAgent = nav.userAgent;\n var notSending = \"Not sending request \";\n var notSendingWhen = notSending + \"when \";\n var fetchedHighEntropyValues = falseVar;\n var encodeURIComponentFunc = encodeURIComponent;\n var decodeURIComponentFunc = decodeURIComponent;\n var stringify = JSON.stringify;\n var thousand = 1000;\n var addEventListenerFunc = window.addEventListener;\n var fullApiUrl = protocol + apiUrlPrefix + baseUrl;\n var documentElement = doc.documentElement || {};\n var language = \"language\";\n var Height = \"Height\";\n var Width = \"Width\";\n var scroll = \"scroll\";\n var uaData = nav.userAgentData;\n var scrollHeight = scroll + Height;\n var offsetHeight = \"offset\" + Height;\n var clientHeight = \"client\" + Height;\n var clientWidth = \"client\" + Width;\n var pagehide = \"pagehide\";\n var platformText = \"platform\";\n var platformVersionText = \"platformVersion\";\n var docsUrl = \"https://docs.simpleanalytics.com\";\n var pages = 0;\n var isBotAgent =\n /(bot|spider|crawl)/i.test(userAgent) && !/(cubot)/i.test(userAgent);\n var screen = window.screen;\n\n\n // Find the script element where options can be set on\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"' + baseUrl + '\"]');\n\n /////////////////////\n // HELPER FUNCTIONS\n //\n\n // A simple log function so the user knows why a request is not being send\n warn = function () {\n // 1. Convert args to a normal array\n var args = [].slice.call(arguments);\n\n // 2. Prepend log prefix\n args.unshift(\"Simple Analytics:\");\n\n // 3. Pass along arguments to console.warn\n // Function.prototype.apply.call is needed for Internet Explorer\n return Function.prototype.apply.call(con.warn, con, args);\n };\n\n var warnInFunction = function (name, error) {\n warn(\"Error in your \" + name + \" function:\", error);\n };\n\n var hasProp = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n\n var isString = function (string) {\n return typeof string == \"string\";\n };\n\n var filterRegex = function (item) {\n return item.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n var attr = function (scriptElement, attribute) {\n return scriptElement && scriptElement.getAttribute(\"data-\" + attribute);\n };\n\n var convertCommaSeparatedToArray = function (csv) {\n return Array.isArray(csv)\n ? csv\n : isString(csv) && csv.length\n ? csv.split(/, ?/)\n : [];\n };\n\n var isObject = function (object) {\n return object && object.constructor === Object;\n };\n\n var assign = function () {\n var to = {};\n var arg = arguments;\n for (var index = 0; index < arg.length; index++) {\n var nextSource = arg[index];\n if (isObject(nextSource)) {\n for (var nextKey in nextSource) {\n if (hasProp(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n\n var settings = window.sa_settings;\n var logSettings = settings || Object.keys(overwriteOptions).length;\n\n // Merge overwriteOptions with sa_settings\n overwriteOptions = assign(overwriteOptions, settings);\n\n if (logSettings) warn(\"Settings\", overwriteOptions);\n\n // Customers can skip data points\n var ignoreMetrics = convertCommaSeparatedToArray(\n overwriteOptions.ignoreMetrics || attr(scriptElement, \"ignore-metrics\")\n );\n\n var collectMetricByString = function (metricAbbreviation) {\n // Can't use Array.find() here because we need to support IE9\n return (\n ignoreMetrics.filter(function (item) {\n return new RegExp(\"^\" + metricAbbreviation).test(item);\n }).length === 0\n );\n };\n\n var now = Date.now;\n\n var uuid = function () {\n var cryptoObject = window.crypto || window.msCrypto;\n var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;\n var uuidRegex = /[018]/g;\n\n try {\n return emptyUUID.replace(uuidRegex, function (c) {\n return (\n c ^\n (cryptoObject.getRandomValues(new Uint8Array(1))[0] &\n (15 >> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n var appendMetadata = function (metadata, data) {\n var metadataObject = window[namespace + \"_metadata\"];\n if (isObject(metadataObject)) metadata = assign(metadata, metadataObject);\n var metadataCollectorFunction = window[metadataCollector];\n if (!isFunction(metadataCollectorFunction)) {\n if (metadataCollector)\n warn(\n metadataCollector + \" not found, set window.\" + metadataCollector\n );\n return metadata;\n }\n try {\n return assign(\n metadata,\n metadataCollectorFunction.call(window, assign(metadata, data))\n );\n } catch (error) {\n warnInFunction(\"metadata\", error);\n }\n };\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource, overwriteSearch) {\n return (\n (overwriteSearch || loc.search)\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n var paramsRegexList = allowParams.map(filterRegex).join(\"|\");\n var regex = ignore\n ? \"^(\" + paramsRegexList + \")=\"\n : \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \"|\" +\n paramsRegexList +\n \")=\";\n if (ignore && !allowParams.length) return falseVar;\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n // Ignore pages specified in data-ignore-pages\n var shouldIgnore = function (path) {\n for (var i in ignorePages) {\n var ignorePageRaw = ignorePages[i];\n if (!ignorePageRaw) continue;\n\n // Prepend a slash when it's missing\n var ignorePage =\n ignorePageRaw[0] == slash ? ignorePageRaw : slash + ignorePageRaw;\n\n if (\n ignorePage === path ||\n new RegExp(\n \"^\" + filterRegex(ignorePage).replace(/\\\\\\*/gi, \"(.*)\") + \"$\",\n \"i\"\n ).test(path)\n )\n return trueVar;\n }\n return falseVar;\n };\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n if (callback) {\n image.onerror = callback;\n image.onload = callback;\n }\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n /////////////////////\n // ERROR FUNCTIONS\n //\n\n // Send errors\n // no var because it's scoped outside of the try/catch\n sendError = function (errorOrMessage) {\n errorOrMessage = errorOrMessage.stack\n ? errorOrMessage + \" \" + errorOrMessage.stack\n : errorOrMessage;\n warn(errorOrMessage);\n sendData(\n assign(basePayload, {\n type: errorText,\n error: errorOrMessage,\n path: loc.pathname,\n }),\n undefinedVar,\n trueVar\n );\n };\n\n // We listen for the error events and only send errors that are\n // from our script (checked by filename) to our server.\n addEventListenerFunc(\n errorText,\n function (event) {\n if (event.filename && event.filename.indexOf(baseUrl) > -1) {\n sendError(event.message);\n }\n },\n falseVar\n );\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n var start = now();\n\n var scrolled = 0;\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n // Should we record Do Not Track visits?\n var collectDnt = isBoolean(overwriteOptions.collectDnt)\n ? overwriteOptions.collectDnt\n : attr(scriptElement, \"ignore-dnt\") == trueText ||\n attr(scriptElement, \"skip-dnt\") == trueText ||\n attr(scriptElement, \"collect-dnt\") == trueText;\n\n // Some customers want to collect page views manually\n var autoCollect = !(\n attr(scriptElement, \"auto-collect\") == \"false\" ||\n overwriteOptions.autoCollect === falseVar\n );\n\n // Event function name\n var eventFunctionName =\n overwriteOptions.saGlobal ||\n attr(scriptElement, \"sa-global\") ||\n namespace + \"_\" + eventText;\n\n // Customers can ignore certain pages\n var ignorePages = convertCommaSeparatedToArray(\n overwriteOptions.ignorePages || attr(scriptElement, \"ignore-pages\")\n );\n\n // Customers can allow params\n var allowParams = convertCommaSeparatedToArray(\n overwriteOptions.allowParams || attr(scriptElement, \"allow-params\")\n );\n\n // Customers can allow params\n var nonUniqueHostnames = convertCommaSeparatedToArray(\n overwriteOptions.nonUniqueHostnames ||\n attr(scriptElement, \"non-unique-hostnames\")\n );\n\n // Customers can overwrite certain values\n var pathOverwriter =\n overwriteOptions.pathOverwriter || attr(scriptElement, \"path-overwriter\");\n\n // Customers can add metadata to events and pageviews via a function\n var metadataCollector =\n overwriteOptions.metadataCollector ||\n attr(scriptElement, \"metadata-collector\");\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var phantom = window.phantom;\n var bot =\n nav.webdriver ||\n window.__nightmare ||\n window.callPhantom ||\n window._phantom ||\n (phantom && !phantom.solana) ||\n window.__polypane ||\n window._bot ||\n isBotAgent ||\n Math.random() == Math.random();\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = falseVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n // Warn when no document.doctype is defined (this breaks some documentElement dimensions)\n if (!doc.doctype) warn(\"Add DOCTYPE html for accurate dimensions\");\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (!collectDnt && doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n // Customers can overwrite their referrer, here we check for that\n var overwrittenReferrer =\n overwriteOptions.referrer || attr(scriptElement, \"referrer\");\n\n return (\n (overwrittenReferrer || doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n // t = timeonpage\n if (collectMetricByString(\"t\")) {\n append.duration = Math.round((now() - start - msHidden) / thousand);\n }\n msHidden = 0;\n start = now();\n\n // scro = scrolled\n if (collectMetricByString(\"scro\")) {\n append.scrolled = Math.max(0, scrolled, position());\n }\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n try {\n nav.sendBeacon.bind(nav)(fullApiUrl + \"/append\", stringify(append));\n } catch (e) {\n // Fallback for browsers throwing \"Illegal invocation\" when the URL is invalid\n sendData(append, undefinedVar, trueVar);\n }\n }\n };\n\n var hiddenStart;\n addEventListenerFunc(\n \"visibilitychange\",\n function () {\n if (doc.hidden) {\n if (!(\"on\" + pagehide in window)) sendOnLeave();\n hiddenStart = now();\n } else msHidden += now() - hiddenStart;\n },\n falseVar\n );\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n var body = doc.body || {};\n var position = function () {\n try {\n var documentClientHeight = documentElement[clientHeight] || 0;\n var height = Math.max(\n body[scrollHeight] || 0,\n body[offsetHeight] || 0,\n documentElement[clientHeight] || 0,\n documentElement[scrollHeight] || 0,\n documentElement[offsetHeight] || 0\n );\n return Math.min(\n 100,\n Math.round(\n (100 * ((documentElement.scrollTop || 0) + documentClientHeight)) /\n height /\n 5\n ) * 5\n );\n } catch (error) {\n warn(error);\n return 0;\n }\n };\n\n addEventListenerFunc(\"load\", function () {\n scrolled = position();\n addEventListenerFunc(\n scroll,\n function () {\n if (scrolled < position()) scrolled = position();\n },\n falseVar\n );\n });\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n var pathOverwriterFunction = window[pathOverwriter];\n if (isFunction(pathOverwriterFunction)) {\n try {\n path = pathOverwriterFunction.call(window, { path: path }) || path;\n } catch (error) {\n warnInFunction(\"path\", error);\n }\n }\n\n // Ignore pages specified in data-ignore-pages\n if (shouldIgnore(path)) {\n warn(notSendingWhen + \"ignoring \" + path);\n return;\n }\n\n // Add hash to path when script is put in to hash mode\n if (mode == \"hash\" && loc.hash) path += loc.hash.split(\"?\")[0];\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n query,\n metadata,\n callback\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData(\n {\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: query || getQueryParams(deleteSourceInfo),\n\n metadata: stringify(metadata),\n },\n callback\n );\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (\n isPushState,\n pathOverwrite,\n metadata,\n callbackRaw\n ) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var querySearch;\n if (isString(pathOverwrite) && pathOverwrite.indexOf(\"?\") > -1) {\n // keep query from manual path\n var parts = pathOverwrite.split(\"?\");\n pathOverwrite = parts.shift();\n querySearch = \"?\" + parts.join(\"?\");\n }\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n // v = viewportsizes\n if (collectMetricByString(\"v\")) {\n page.viewport_width =\n Math.max(documentElement[clientWidth] || 0, window.innerWidth || 0) ||\n null;\n page.viewport_height =\n Math.max(\n documentElement[clientHeight] || 0,\n window.innerHeight || 0\n ) || null;\n }\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n // sc = screensizes\n if (screen && collectMetricByString(\"sc\")) {\n page.screen_width = screen.width;\n page.screen_height = screen.height;\n }\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n var currentReferrerHostname = referrer\n ? referrer.split(slash)[0]\n : undefinedVar;\n sameSite = referrer\n ? nonUniqueHostnames.indexOf(currentReferrerHostname) > -1 ||\n currentReferrerHostname == locationHostname\n : falseVar;\n\n // We set unique variable based on pushstate or back navigation, if no match we check the referrer\n page.unique =\n /__cf_/.test(getReferrer()) || isPushState || userNavigated\n ? falseVar\n : !sameSite;\n\n metadata = appendMetadata(metadata, {\n type: pageviewText,\n path: page.path,\n });\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n var delSrc =\n isPushState || userNavigated || !collectMetricByString(\"r\");\n sendPageView(\n isPushState,\n delSrc, // r = referrers\n sameSite,\n querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar,\n metadata,\n callback\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n /////////////////////\n // AUTOMATED PAGE VIEW COLLECTION\n //\n\n var his = window.history;\n var hisPushState = his ? his.pushState : undefinedVar;\n var dis = window.dispatchEvent;\n var pushStateText = \"pushState\";\n\n // Overwrite history pushState function to\n // allow listening on the pushState event\n if (autoCollect && hisPushState && Event && dis) {\n var stateListener = function (type) {\n var orig = his[type];\n return function () {\n var arg = arguments;\n var rv = orig.apply(this, arg);\n var event;\n if (isFunction(Event)) {\n event = new Event(type);\n } else {\n // Fix for IE\n // https://github.com/simpleanalytics/scripts/issues/8\n event = doc.createEvent(\"Event\");\n event.initEvent(type, trueVar, trueVar);\n }\n event.arguments = arg;\n dis(event);\n return rv;\n };\n };\n\n his.pushState = stateListener(pushStateText);\n\n addEventListenerFunc(\n pushStateText,\n function () {\n pageview(1);\n },\n falseVar\n );\n\n addEventListenerFunc(\n \"popstate\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n // When in hash mode, we record a pageview based on the onhashchange function\n if (autoCollect && mode == \"hash\" && \"onhashchange\" in window) {\n addEventListenerFunc(\n \"hashchange\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n if (autoCollect) pageview();\n\n window.sa_pageview = function (path, metadata, callback) {\n pageview(0, path, metadata, callback);\n };\n\n\n /////////////////////\n // EVENTS\n //\n\n var validTypes = [\"string\", \"number\"];\n\n var sendEvent = function (event, metadata, callbackRaw) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n\n var eventIsFunction = isFunction(event);\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var eventType = typeof event;\n\n if (validTypes.indexOf(eventType) < 0 && !eventIsFunction) {\n warnInFunction(eventFunctionName, eventText + \" can't be \" + eventType);\n return callback();\n }\n\n try {\n if (eventIsFunction) {\n var eventOutput = event();\n if (validTypes.indexOf(typeof eventOutput) < 0) {\n warnInFunction(\n eventFunctionName,\n event + \" returns no string: \" + eventOutput\n );\n return callback();\n }\n event = eventOutput;\n }\n } catch (error) {\n warnInFunction(eventFunctionName, error);\n return callback();\n }\n\n event = (\"\" + event).replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_|_$)/g, \"\");\n\n var eventParams = { type: eventText, event: event };\n var firstPage = !userNavigated && pages < 2;\n\n metadata = appendMetadata(metadata, eventParams);\n\n if (event) {\n sendData(\n assign(eventParams, {\n id: uuid(),\n query: getQueryParams(!firstPage),\n referrer:\n (firstPage || sameSite) && collectMetricByString(\"r\")\n ? previousReferrer\n : null,\n\n metadata: stringify(metadata),\n }),\n callback\n );\n }\n };\n\n var defaultEventFunc = function (event, metadata, callback) {\n sendEvent(event, metadata, callback);\n };\n\n // Set default function if user didn't define a function\n if (!window[eventFunctionName])\n window[eventFunctionName] = defaultEventFunc;\n\n var eventFunc = window[eventFunctionName];\n\n // Read queue of the user defined function\n var queue = eventFunc && eventFunc.q ? eventFunc.q : [];\n\n // Overwrite user defined function\n window[eventFunctionName] = defaultEventFunc;\n\n // Post events from the queue of the user defined function\n for (var event in queue) {\n if (hasProp(queue, event)) {\n Array.isArray(queue[event])\n ? sendEvent.apply(null, queue[event])\n : sendEvent(queue[event]);\n }\n }\n } catch (e) {\n sendError(e);\n }\n})(\n window,\n {},\n \"\",\n \"\",\n \"custom_latest_12\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","sendError","warn","undefinedVar","undefined","trueVar","falseVar","trueText","https","pageviewText","eventText","errorText","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","notSendingWhen","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","documentElement","language","Height","scroll","uaData","userAgentData","scrollHeight","offsetHeight","clientHeight","pagehide","platformText","platformVersionText","docsUrl","pages","isBotAgent","test","screen","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","warnInFunction","name","error","hasProp","obj","prop","Object","hasOwnProperty","isString","string","filterRegex","item","replace","attr","attribute","getAttribute","convertCommaSeparatedToArray","csv","Array","isArray","length","split","isObject","object","constructor","assign","to","arg","index","nextSource","nextKey","settings","sa_settings","logSettings","keys","ignoreMetrics","collectMetricByString","metricAbbreviation","filter","RegExp","now","Date","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","c","getRandomValues","Uint8Array","toString","r","Math","random","isFunction","func","namespaceText","namespace","appendMetadata","metadata","data","metadataObject","metadataCollectorFunction","metadataCollector","strictUtm","getQueryParams","ignoreSource","overwriteSearch","search","keyValue","ignore","paramsRegexList","allowParams","map","join","regex","loadedVariable","sa_event_loaded","sendData","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","image","Image","onerror","onload","src","key","overwrittenHostname","hostname","definedHostname","basePayload","version","errorOrMessage","stack","type","path","pathname","event","filename","indexOf","message","timezone","start","scrolled","mode","collectDnt","value","autoCollect","eventFunctionName","saGlobal","ignorePages","nonUniqueHostnames","pathOverwriter","Intl","DateTimeFormat","resolvedOptions","timeZone","phantom","bot","webdriver","__nightmare","callPhantom","_phantom","solana","__polypane","_bot","collectDataOnLeave","ua","protocol","page_id","session_id","sri","mobile","brands","doctype","hostname_original","lastSendPath","hiddenStart","getReferrer","referrer","msHidden","sendOnLeave","id","push","append","original_id","duration","round","max","position","sendBeacon","bind","e","hidden","body","documentClientHeight","height","min","scrollTop","previousReferrer","sameSite","userNavigated","getPath","overwrite","pathOverwriterFunction","i","ignorePageRaw","ignorePage","shouldIgnore","hash","pageview","isPushState","pathOverwrite","callbackRaw","querySearch","parts","shift","viewport_width","innerWidth","viewport_height","innerHeight","screen_width","width","screen_height","performaceEntryType","perf","performance","navigationText","getEntriesByType","currentReferrerHostname","unique","triggerSendPageView","delSrc","deleteSourceInfo","query","currentPage","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","his","history","hisPushState","pushState","dis","dispatchEvent","pushStateText","Event","orig","rv","this","createEvent","initEvent","sa_pageview","validTypes","sendEvent","eventIsFunction","eventType","eventOutput","eventParams","firstPage","defaultEventFunc","eventFunc","queue","q"],"mappings":"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"} \ No newline at end of file diff --git a/dist/latest/custom/light.js b/dist/latest/custom/light.js index 20bf335c..80b6f837 100644 --- a/dist/latest/custom/light.js +++ b/dist/latest/custom/light.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy friendly analytics (docs.simpleanalytics.com/script; 2023-05-03; a797; v11) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; 971c; v12) */ -!function(s,e,t,u){try{var i=undefined,n="https:",r=s.console,a="doNotTrack",p=s.navigator,c=s.location,d=c.host,o=s.document,l=p.userAgent,m="Not sending request ",f=!1,g=encodeURIComponent,h=decodeURIComponent,v=JSON.stringify,y=s.addEventListener,_="https://"+t,w=(o.documentElement,"language"),b=p.userAgentData,O="platform",S="platformVersion",k="https://docs.simpleanalytics.com",j=/(bot|spider|crawl)/i.test(l)&&!/(cubot)/i.test(l),E=o.currentScript||o.querySelector('script[src*="'+t+'"]');u=function(){var e=[].slice.call(arguments);return e.unshift("Simple Analytics:"),Function.prototype.apply.call(r.warn,r,e)};var x=function(e,t){return e&&e.getAttribute("data-"+t)},A=function(){for(var e,t,n,r={},a=arguments,o=0;o>e/4).toString(16)})}catch(r){return e.replace(n,function(e){var t=16*Math.random()|0;return(e<2?t:3&t|8).toString(16)})}},I="namespace",N=e[I]||x(E,I)||"sa",R=e.strictUtm||"true"==x(E,"strict-utm"),U=N+"_loaded";if(1==s[U])return u(m+"twice");s.sa_event_loaded=!0,s[U]=!0;var V,B=function(t,e,n){t=n?t:A(F,J,t),p.brave&&!n&&(t.brave=!0),p._duckduckgoloader_&&!n&&(t.duck=!0),(new Image).src=_+"/simple.gif?"+Object.keys(t).filter(function(e){return t[e]!=i}).map(function(e){return g(e)+"="+g(t[e])}).join("&")+"&time="+Date.now()},C=e.hostname||x(E,"hostname"),H=C||d,T={version:"custom_light_11",hostname:H};e.mode||x(E,"mode");try{V=Intl.DateTimeFormat().resolvedOptions().timeZone}catch(Q){u(Q)}j&&(T.bot=!0);var F=A(T,{ua:l,https:c.protocol==n,timezone:V,page_id:D(),session_id:D()});if(F.sri=!1,b&&(F.mobile=b.mobile,F.brands=v(b.brands)),H!==d&&(F.hostname_original=d),a in p&&"1"==p[a])return u("Not sending request when "+a+" is enabled. See "+k+"/dnt");-1!=d.indexOf(".")&&!/^[0-9.:]+$/.test(d)||C||u("Set hostname on "+d+". See "+k+"/overwrite-domain-name");var z,J={},L=(o.referrer||"").replace(d,H).replace(/^https?:\/\/((m|l|w{2,3}([0-9]+)?)\.)?([^?#]+)(.*)$/,"$4").replace(/^([^/]+)$/,"$1")||i,M=function(e,t){var n=A(T,{type:"append",original_id:t?e:F.page_id});t||!p.sendBeacon?B(n,0,!0):p.sendBeacon(_+"/append",v(n))};y("pagehide",M,!1);var P,Z,G=function(e){var t="";try{t=e||h(c.pathname)}catch(Q){u(Q)}return t},K=function(e,t,n,r){e&&M(""+F.page_id,!0),F.page_id=D();var a,o=H+G();B({id:F.page_id,type:"pageview",referrer:!t||n?L:null,query:(a=t,c.search.slice(1).split("&").filter(function(e){return!a&&new RegExp("^((utm_)"+(R?"":"?")+"(source|medium|content|term|campaign)"+(R?"":"|ref")+")=").test(e)}).join("&")||i)}),L=o,0};!function(e,t){var n=G(t);if(n&&z!=n){z=n,J.path=n,p[w]&&(J[w]=p[w]);var r,a=s.performance,o="navigation";try{r=a.getEntriesByType(o)[0].type}catch(Q){u(Q)}Z=r?-1<["reload","back_forward"].indexOf(r):a&&a[o]&&-1<[1,2].indexOf(a[o].type),P=!!L&&L.split("/")[0]==d;var i=function(){f=!0,K(e,e||Z||!1,P)};if(f)i();else try{b&&"function"==typeof b.getHighEntropyValues?b.getHighEntropyValues([O,S]).then(function(e){F.os_name=e[O],F.os_version=e[S],i()})["catch"](i):i()}catch(c){i()}}}()}catch(W){u(W)}}(window,{},""); +!function(l,e,t,f){try{var m=undefined,n="https:",r=l.console,a="doNotTrack",g=l.navigator,i=l.location,h=i.host,o=l.document,c=g.userAgent,s="Not sending request ",v=!1,u=encodeURIComponent,p=decodeURIComponent,d=JSON.stringify,y=l.addEventListener,_="https://"+t,b=(o.documentElement,"language"),w=g.userAgentData,O="platform",S="platformVersion",j="https://docs.simpleanalytics.com",k=/(bot|spider|crawl)/i.test(c)&&!/(cubot)/i.test(c),x=o.currentScript||o.querySelector('script[src*="'+t+'"]');f=function(){var e=[].slice.call(arguments);return e.unshift("Simple Analytics:"),Function.prototype.apply.call(r.warn,r,e)};var E=function(e){return"string"==typeof e},A=function(e,t){return e&&e.getAttribute("data-"+t)},$=function(){for(var e,t,n,r={},a=arguments,i=0;i>e/4).toString(16)})}catch(r){return e.replace(n,function(e){var t=16*Math.random()|0;return(e<2?t:3&t|8).toString(16)})}},N=function(e){return"function"==typeof e},R="namespace",U=e[R]||A(x,R)||"sa",V=e.strictUtm||"true"==A(x,"strict-utm"),B=function(t,e){return(e||i.search).slice(1).split("&").filter(function(e){return!t&&new RegExp("^((utm_)"+(V?"":"?")+"(source|medium|content|term|campaign)"+(V?"":"|ref")+")=").test(e)}).join("&")||m},C=U+"_loaded";if(1==l[C])return f(s+"twice");l.sa_event_loaded=!0,l[C]=!0;var H,T=function(t,e,n){t=n?t:$(L,P,t),g.brave&&!n&&(t.brave=!0),g._duckduckgoloader_&&!n&&(t.duck=!0),(new Image).src=_+"/simple.gif?"+Object.keys(t).filter(function(e){return t[e]!=m}).map(function(e){return u(e)+"="+u(t[e])}).join("&")+"&time="+Date.now()},F=e.hostname||A(x,"hostname"),z=F||h,J={version:"custom_light_12",hostname:z};e.mode||A(x,"mode");try{H=Intl.DateTimeFormat().resolvedOptions().timeZone}catch(X){f(X)}k&&(J.bot=!0);var L=$(J,{ua:c,https:i.protocol==n,timezone:H,page_id:I(),session_id:I()});if(L.sri=!1,w&&(L.mobile=w.mobile,L.brands=d(w.brands)),z!==h&&(L.hostname_original=h),a in g&&"1"==g[a])return f("Not sending request when "+a+" is enabled. See "+j+"/dnt");-1!=h.indexOf(".")&&!/^[0-9.:]+$/.test(h)||F||f("Set hostname on "+h+". See "+j+"/overwrite-domain-name");var M,P={},Z=(e.referrer||A(x,"referrer")||o.referrer||"").replace(h,z).replace(/^https?:\/\/((m|l|w{2,3}([0-9]+)?)\.)?([^?#]+)(.*)$/,"$4").replace(/^([^/]+)$/,"$1")||m,G=function(e,t){var n=$(J,{type:"append",original_id:t?e:L.page_id});if(t||!g.sendBeacon)T(n,0,!0);else try{g.sendBeacon.bind(g)(_+"/append",d(n))}catch(r){T(n,0,!0)}};y("pagehide",G,!1);var K,Q,W=function(e){var t="";try{t=e||p(i.pathname)}catch(X){f(X)}return t};!function(t,e,n,r){!r&&N(n)&&(r=n);var a,i;N(r);E(e)&&-1"); //# sourceMappingURL=light.js.map \ No newline at end of file diff --git a/dist/latest/custom/light.js.map b/dist/latest/custom/light.js.map index b68cba95..825c7d38 100644 --- a/dist/latest/custom/light.js.map +++ b/dist/latest/custom/light.js.map @@ -1 +1 @@ -{"version":3,"file":"light.source.js","sources":["light.source.js"],"sourcesContent":["/* eslint-env browser */\n\n(function (\n window,\n overwriteOptions,\n baseUrl,\n apiUrlPrefix,\n version,\n defaultNamespace,\n sendError,\n warn\n) {\n try {\n /////////////////////\n // PREDEFINED VARIABLES FOR BETTER MINIFICATION\n //\n\n // This seems like a lot of repetition, but it makes our script available for\n // multple destination which prevents us to need multiple scripts. The minified\n // version stays small.\n var undefinedVar = undefined;\n var trueVar = true;\n var falseVar = false;\n var trueText = \"true\";\n var https = \"https:\";\n var pageviewText = \"pageview\";\n var eventText = \"event\";\n var slash = \"/\";\n var protocol = https + \"//\";\n var con = window.console;\n var doNotTrack = \"doNotTrack\";\n var nav = window.navigator;\n var loc = window.location;\n var locationHostname = loc.host;\n var doc = window.document;\n var userAgent = nav.userAgent;\n var notSending = \"Not sending request \";\n var notSendingWhen = notSending + \"when \";\n var fetchedHighEntropyValues = falseVar;\n var encodeURIComponentFunc = encodeURIComponent;\n var decodeURIComponentFunc = decodeURIComponent;\n var stringify = JSON.stringify;\n var thousand = 1000;\n var addEventListenerFunc = window.addEventListener;\n var fullApiUrl = protocol + apiUrlPrefix + baseUrl;\n var documentElement = doc.documentElement || {};\n var language = \"language\";\n var Height = \"Height\";\n var Width = \"Width\";\n var scroll = \"scroll\";\n var uaData = nav.userAgentData;\n var scrollHeight = scroll + Height;\n var offsetHeight = \"offset\" + Height;\n var clientHeight = \"client\" + Height;\n var clientWidth = \"client\" + Width;\n var pagehide = \"pagehide\";\n var platformText = \"platform\";\n var platformVersionText = \"platformVersion\";\n var docsUrl = \"https://docs.simpleanalytics.com\";\n var pages = 0;\n var isBotAgent =\n /(bot|spider|crawl)/i.test(userAgent) && !/(cubot)/i.test(userAgent);\n\n\n // Find the script element where options can be set on\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"' + baseUrl + '\"]');\n\n /////////////////////\n // HELPER FUNCTIONS\n //\n\n // A simple log function so the user knows why a request is not being send\n warn = function () {\n // 1. Convert args to a normal array\n var args = [].slice.call(arguments);\n\n // 2. Prepend log prefix\n args.unshift(\"Simple Analytics:\");\n\n // 3. Pass along arguments to console.warn\n // Function.prototype.apply.call is needed for Internet Explorer\n return Function.prototype.apply.call(con.warn, con, args);\n };\n\n var warnInFunction = function (name, error) {\n warn(\"Error in your \" + name + \" function:\", error);\n };\n\n var hasProp = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n\n var isString = function (string) {\n return typeof string == \"string\";\n };\n\n var filterRegex = function (item) {\n return item.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n var attr = function (scriptElement, attribute) {\n return scriptElement && scriptElement.getAttribute(\"data-\" + attribute);\n };\n\n var convertCommaSeparatedToArray = function (csv) {\n return Array.isArray(csv)\n ? csv\n : isString(csv) && csv.length\n ? csv.split(/, ?/)\n : [];\n };\n\n var isObject = function (object) {\n return object && object.constructor === Object;\n };\n\n var assign = function () {\n var to = {};\n var arg = arguments;\n for (var index = 0; index < arg.length; index++) {\n var nextSource = arg[index];\n if (isObject(nextSource)) {\n for (var nextKey in nextSource) {\n if (hasProp(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n\n var settings = window.sa_settings;\n var logSettings = settings || Object.keys(overwriteOptions).length;\n\n // Merge overwriteOptions with sa_settings\n overwriteOptions = assign(overwriteOptions, settings);\n\n if (logSettings) warn(\"Settings\", overwriteOptions);\n\n\n var collectMetricByString = function (metricAbbreviation) {\n return true;\n };\n\n var now = Date.now;\n\n var uuid = function () {\n var cryptoObject = window.crypto || window.msCrypto;\n var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;\n var uuidRegex = /[018]/g;\n\n try {\n return emptyUUID.replace(uuidRegex, function (c) {\n return (\n c ^\n (cryptoObject.getRandomValues(new Uint8Array(1))[0] &\n (15 >> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource) {\n return (\n loc.search\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n if (ignore) return falseVar;\n var regex =\n \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \")=\";\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n\n\n\n\n\n\n\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var bot = isBotAgent;\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = falseVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n return (\n (doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n nav.sendBeacon(fullApiUrl + \"/append\", stringify(append));\n }\n };\n\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n\n\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n metadata\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData({\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: getQueryParams(deleteSourceInfo),\n\n });\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (isPushState, pathOverwrite, metadata) {\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n sameSite = referrer\n ? referrer.split(slash)[0] == locationHostname\n : falseVar;\n\n\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n sendPageView(\n isPushState,\n isPushState || userNavigated || !collectMetricByString(\"r\"), // r = referrers\n sameSite,\n metadata\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n\n\n pageview();\n\n } catch (e) {\n warn(e);\n }\n})(\n window,\n {},\n \"\",\n \"\",\n \"custom_light_11\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","warn","undefinedVar","undefined","https","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","language","documentElement","uaData","userAgentData","platformText","platformVersionText","docsUrl","isBotAgent","test","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","attr","attribute","getAttribute","assign","obj","prop","object","to","arg","index","length","nextSource","constructor","Object","nextKey","hasOwnProperty","settings","sa_settings","logSettings","keys","Date","now","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","replace","c","getRandomValues","Uint8Array","toString","error","r","Math","random","namespaceText","namespace","strictUtm","loadedVariable","sa_event_loaded","timezone","sendData","data","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","Image","src","filter","key","map","join","overwrittenHostname","hostname","definedHostname","basePayload","version","mode","Intl","DateTimeFormat","resolvedOptions","timeZone","bot","ua","protocol","page_id","session_id","sri","mobile","brands","hostname_original","indexOf","lastSendPath","referrer","sendOnLeave","id","push","append","type","original_id","sendBeacon","sameSite","userNavigated","getPath","overwrite","path","pathname","sendPageView","isPushState","deleteSourceInfo","metadata","ignoreSource","currentPage","query","search","split","keyValue","RegExp","pages","pathOverwrite","performaceEntryType","perf","performance","navigationText","getEntriesByType","triggerSendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","e","pageview"],"mappings":";;CAEA,SACEA,EACAC,EACAC,EAKAC,GAEA,IAQE,IAAIC,EAAeC,UAIfC,EAAQ,SAKRC,EAAMP,EAAOQ,QACbC,EAAa,aACbC,EAAMV,EAAOW,UACbC,EAAMZ,EAAOa,SACbC,EAAmBF,EAAIG,KACvBC,EAAMhB,EAAOiB,SACbC,EAAYR,EAAIQ,UAChBC,EAAa,uBAEbC,GAhBW,EAiBXC,EAAyBC,mBACzBC,EAAyBC,mBACzBC,EAAYC,KAAKD,UAEjBE,EAAuB3B,EAAO4B,iBAC9BC,EAhBWvB,WAgB4BJ,EAEvC4B,GADkBd,EAAIe,gBACX,YAIXC,EAAStB,EAAIuB,cAMbC,EAAe,WACfC,EAAsB,kBACtBC,EAAU,mCAEVC,EACF,sBAAsBC,KAAKpB,KAAe,WAAWoB,KAAKpB,GAIxDqB,EACFvB,EAAIwB,eAAiBxB,EAAIyB,cAAc,gBAAkBvC,EAAU,MAOrEC,EAAO,WAEL,IAAIuC,EAAO,GAAGC,MAAMC,KAAKC,WAOzB,OAJAH,EAAKI,QAAQ,qBAINC,SAASC,UAAUC,MAAML,KAAKrC,EAAIJ,KAAMI,EAAKmC,IAGtD,IAgBIQ,EAAO,SAAUX,EAAeY,GAClC,OAAOZ,GAAiBA,EAAca,aAAa,QAAUD,IAe3DE,EAAS,WAGX,IAFA,IA7BsBC,EAAKC,EAwBJC,EAKnBC,EAAK,GACLC,EAAMb,UACDc,EAAQ,EAAGA,EAAQD,EAAIE,OAAQD,IAAS,CAC/C,IAAIE,EAAaH,EAAIC,GACrB,IATqBH,EASRK,IAREL,EAAOM,cAAgBC,OASpC,IAAK,IAAIC,KAAWH,EAlCFP,EAmCJO,EAnCSN,EAmCGS,EAlCvBD,OAAOf,UAAUiB,eAAerB,KAAKU,EAAKC,KAmCzCE,EAAGO,GAAWH,EAAWG,IAKjC,OAAOP,GAGLS,EAAWlE,EAAOmE,YAClBC,EAAcF,GAAYH,OAAOM,KAAKpE,GAAkB2D,OAG5D3D,EAAmBoD,EAAOpD,EAAkBiE,GAExCE,GAAajE,EAAK,WAAYF,GAOxBqE,KAAKC,IAJf,IAMIC,EAAO,WACT,IAAIC,EAAezE,EAAO0E,QAAU1E,EAAO2E,SACvCC,EAAY,CAAC,MAAQ,KAAO,KAAO,KAAO,KAC1CC,EAAY,SAEhB,IACE,OAAOD,EAAUE,QAAQD,EAAW,SAAUE,GAC5C,OACEA,EACCN,EAAaO,gBAAgB,IAAIC,WAAW,IAAI,GAC9C,IAAOF,EAAI,GACdG,SAAS,MAEb,MAAOC,GACP,OAAOP,EAAUE,QAAQD,EAAW,SAAUE,GAC5C,IAAIK,EAAqB,GAAhBC,KAAKC,SAAiB,EAE/B,OADMP,EAAI,EAAIK,EAAS,EAAJA,EAAW,GACrBF,SAAS,QAUpBK,EAAgB,YAChBC,EACFvF,EAAiBsF,IACjBrC,EAAKX,EAAegD,IA0XxB,KAhXME,EACFxF,EAAiBwF,WAtKJ,QAuKbvC,EAAKX,EAAe,cAiClBmD,EAAiBF,EAAY,UACjC,GA3Mc,GA2MVxF,EAAO0F,GAA4B,OAAOvF,EAAKgB,EAAa,SAChEnB,EAAO2F,iBA5MO,EA6Md3F,EAAO0F,IA7MO,EAoNd,IA4DIE,EA5DAC,EAAW,SAAUC,EAAMC,EAAUC,GACvCF,EAAOE,EAAeF,EAAOzC,EAAO4C,EAASC,EAAMJ,GAE/CpF,EAAIyF,QAAUH,IAAcF,EAAKK,OAvNzB,GAwNRzF,EAAI0F,qBAAuBJ,IAAcF,EAAKO,MAxNtC,IA2NA,IAAIC,OACVC,IACJ1E,EACA,eACAkC,OAAOM,KAAKyB,GACTU,OAAO,SAAUC,GAChB,OAAOX,EAAKW,IAAQrG,IAErBsG,IAAI,SAAUD,GACb,OACEpF,EAAuBoF,GACvB,IACApF,EAAuByE,EAAKW,MAG/BE,KAAK,KACR,SACArC,KAAKC,OAILqC,EACF3G,EAAiB4G,UAAY3D,EAAKX,EAAe,YAC/CuE,EAAkBF,GAAuB9F,EAEzCiG,EAAc,CAChBC,QAiSJ,kBAhSIH,SAAUC,GAeD7G,EAAiBgH,MAAQ/D,EAAKX,EAAe,QAYxD,IAEEqD,EACIsB,KAAKC,iBAAiBC,kBAAkBC,SAE5C,MAAOlC,GACPhF,EAAKgF,GAOG9C,IAMD0E,EAAYO,KApSP,GAsSd,IAAIrB,EAAU5C,EAAO0D,EAAa,CAEhCQ,GAAkCrG,EAElCZ,MAAOM,EAAI4G,UAAYlH,EACvBsF,SAAUA,EACV6B,QAA8BjD,IAG9BkD,WAA0ClD,MAwB5C,GArBAyB,EAAQ0B,KAjTO,EAqTX3F,IACFiE,EAAQ2B,OAAS5F,EAAO4F,OACxB3B,EAAQ4B,OAASpG,EAAUO,EAAO6F,SAWhCf,IAAoBhG,IACtBmF,EAAQ6B,kBAAoBhH,GAG1BL,KAAcC,GAA0B,KAAnBA,EAAID,GAC3B,OAAON,EAxTYgB,4BAyTAV,EAAa,oBAAsB2B,EAAU,SAK7B,GAAlCtB,EAAiBiH,QAAQ,OACxB,aAAazF,KAAKxB,IACnB8F,GAEDzG,EACE,mBACEW,EACA,SACAsB,EACA,0BAON,IACI4F,EADA9B,EAAO,GAaP+B,GARCjH,EAAIiH,UAAY,IACdnD,QAAQhE,EAAkBgG,GAC1BhC,QAAQ,sDAAuD,MAC/DA,QAAQ,YAAa,OAAS1E,EAcjC8H,EAAc,SAAUC,EAAIC,GAG9B,IAAIC,EAAShF,EAAO0D,EAAa,CAC/BuB,KAAM,SACNC,YAAaH,EAAOD,EAAKlC,EAAQwB,UAK/BW,IAAS1H,EAAI8H,WAEf3C,EAASwC,EAAQjI,GAhYP,GAkYVM,EAAI8H,WAAW3G,EAAa,UAAWJ,EAAU4G,KAKrD1G,EArWe,WAqWgBuG,GAtYhB,GA6Yf,IA6CIO,EAAUC,EA7CVC,EAAU,SAAUC,GACtB,IAAIC,EAAO,GAIX,IACEA,EAAOD,GAAarH,EAAuBX,EAAIkI,UAC/C,MAAO3D,GACPhF,EAAKgF,GAMP,OAAO0D,GAMLE,EAAe,SACjBC,EACAC,EACAR,EACAS,GAEIF,GAAad,EAAY,GAAKjC,EAAQwB,SAxa9B,GAyaYxB,EAAQwB,QAAUjD,IAE1C,IAhQ6B2E,EAgQzBC,EAActC,EAAkB6B,IAEpC9C,EAAS,CACPsC,GAAIlC,EAAQwB,QACZa,KA3ae,WA4afL,UAAWgB,GAAoBR,EAAWR,EAAW,KACrDoB,OAtQ2BF,EAsQLF,EApQtBrI,EAAI0I,OACD3G,MAAM,GACN4G,MAAM,KACN/C,OAAO,SAAUgD,GAGhB,OAFaL,GAYN,IAAIM,OART,YACChE,EAAY,GAAK,KAClB,yCACCA,EAAY,GAAK,QAClB,MAIuBnD,KAAKkH,KAE/B7C,KAAK,MAAQvG,KAuPlB6H,EAAWmB,EAEXM,IAKa,SAAUV,EAAaW,GAEpC,IAAId,EAAOF,EAAQgB,GAGnB,GAAKd,GAAQb,GAAgBa,EAA7B,CAEAb,EAAea,EACf3C,EAAK2C,KAAOA,EAKNnI,EAAIoB,KAAWoE,EAAKpE,GAAYpB,EAAIoB,IAK1C,IAII8H,EAJAC,EAAO7J,EAAO8J,YACdC,EAAiB,aAIrB,IACEH,EAAsBC,EAAKG,iBAAiBD,GAAgB,GAAGzB,KAC/D,MAAOnD,GACPhF,EAAKgF,GAGPuD,EAAgBkB,GAC+C,EAA3D,CAAC,SAAU,gBAAgB7B,QAAQ6B,GAGnCC,GACAA,EAAKE,KACwC,EAA7C,CAAC,EAAG,GAAGhC,QAAQ8B,EAAKE,GAAgBzB,MAGxCG,IAAWR,GACPA,EAASsB,MA9dH,KA8dgB,IAAMzI,EAKhC,IAAImJ,EAAsB,WACxB7I,GA1eU,EA2eV2H,EACEC,EACAA,GAAeN,IAAiB,EAChCD,IAKJ,GAAKrH,EAmBH6I,SAjBA,IACMjI,GAhWc,mBAgWOA,EAAOkI,qBAC9BlI,EACGkI,qBAAqB,CAAChI,EAAcC,IACpCgI,KAAK,SAAUC,GACdnE,EAAQoE,QAAUD,EAAkBlI,GACpC+D,EAAQqE,WAAaF,EAAkBjI,GACvC8H,MAEDM,SAAMN,GAETA,IAEF,MAAOO,GACPP,MASNQ,GAEA,MAAOD,GACPrK,EAAKqK,IAliBT,CAqiBExK,OACA,uBACA"} \ No newline at end of file +{"version":3,"file":"light.source.js","sources":["light.source.js"],"sourcesContent":["/* eslint-env browser */\n\n(function (\n window,\n overwriteOptions,\n baseUrl,\n apiUrlPrefix,\n version,\n defaultNamespace,\n sendError,\n warn\n) {\n try {\n /////////////////////\n // PREDEFINED VARIABLES FOR BETTER MINIFICATION\n //\n\n // This seems like a lot of repetition, but it makes our script available for\n // multple destination which prevents us to need multiple scripts. The minified\n // version stays small.\n var undefinedVar = undefined;\n var trueVar = true;\n var falseVar = false;\n var trueText = \"true\";\n var https = \"https:\";\n var pageviewText = \"pageview\";\n var eventText = \"event\";\n var slash = \"/\";\n var protocol = https + \"//\";\n var con = window.console;\n var doNotTrack = \"doNotTrack\";\n var nav = window.navigator;\n var loc = window.location;\n var locationHostname = loc.host;\n var doc = window.document;\n var userAgent = nav.userAgent;\n var notSending = \"Not sending request \";\n var notSendingWhen = notSending + \"when \";\n var fetchedHighEntropyValues = falseVar;\n var encodeURIComponentFunc = encodeURIComponent;\n var decodeURIComponentFunc = decodeURIComponent;\n var stringify = JSON.stringify;\n var thousand = 1000;\n var addEventListenerFunc = window.addEventListener;\n var fullApiUrl = protocol + apiUrlPrefix + baseUrl;\n var documentElement = doc.documentElement || {};\n var language = \"language\";\n var Height = \"Height\";\n var Width = \"Width\";\n var scroll = \"scroll\";\n var uaData = nav.userAgentData;\n var scrollHeight = scroll + Height;\n var offsetHeight = \"offset\" + Height;\n var clientHeight = \"client\" + Height;\n var clientWidth = \"client\" + Width;\n var pagehide = \"pagehide\";\n var platformText = \"platform\";\n var platformVersionText = \"platformVersion\";\n var docsUrl = \"https://docs.simpleanalytics.com\";\n var pages = 0;\n var isBotAgent =\n /(bot|spider|crawl)/i.test(userAgent) && !/(cubot)/i.test(userAgent);\n\n\n // Find the script element where options can be set on\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"' + baseUrl + '\"]');\n\n /////////////////////\n // HELPER FUNCTIONS\n //\n\n // A simple log function so the user knows why a request is not being send\n warn = function () {\n // 1. Convert args to a normal array\n var args = [].slice.call(arguments);\n\n // 2. Prepend log prefix\n args.unshift(\"Simple Analytics:\");\n\n // 3. Pass along arguments to console.warn\n // Function.prototype.apply.call is needed for Internet Explorer\n return Function.prototype.apply.call(con.warn, con, args);\n };\n\n var warnInFunction = function (name, error) {\n warn(\"Error in your \" + name + \" function:\", error);\n };\n\n var hasProp = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n\n var isString = function (string) {\n return typeof string == \"string\";\n };\n\n var filterRegex = function (item) {\n return item.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n var attr = function (scriptElement, attribute) {\n return scriptElement && scriptElement.getAttribute(\"data-\" + attribute);\n };\n\n var convertCommaSeparatedToArray = function (csv) {\n return Array.isArray(csv)\n ? csv\n : isString(csv) && csv.length\n ? csv.split(/, ?/)\n : [];\n };\n\n var isObject = function (object) {\n return object && object.constructor === Object;\n };\n\n var assign = function () {\n var to = {};\n var arg = arguments;\n for (var index = 0; index < arg.length; index++) {\n var nextSource = arg[index];\n if (isObject(nextSource)) {\n for (var nextKey in nextSource) {\n if (hasProp(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n\n var settings = window.sa_settings;\n var logSettings = settings || Object.keys(overwriteOptions).length;\n\n // Merge overwriteOptions with sa_settings\n overwriteOptions = assign(overwriteOptions, settings);\n\n if (logSettings) warn(\"Settings\", overwriteOptions);\n\n\n var collectMetricByString = function (metricAbbreviation) {\n // eslint-disable-next-line no-unreachable\n return true;\n };\n\n var now = Date.now;\n\n var uuid = function () {\n var cryptoObject = window.crypto || window.msCrypto;\n var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;\n var uuidRegex = /[018]/g;\n\n try {\n return emptyUUID.replace(uuidRegex, function (c) {\n return (\n c ^\n (cryptoObject.getRandomValues(new Uint8Array(1))[0] &\n (15 >> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource, overwriteSearch) {\n return (\n (overwriteSearch || loc.search)\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n if (ignore) return falseVar;\n // eslint-disable-next-line no-redeclare\n var regex =\n \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \")=\";\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n\n\n\n\n\n\n\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n // eslint-disable-next-line no-redeclare\n var bot = isBotAgent;\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = falseVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n // Customers can overwrite their referrer, here we check for that\n var overwrittenReferrer =\n overwriteOptions.referrer || attr(scriptElement, \"referrer\");\n\n return (\n (overwrittenReferrer || doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n try {\n nav.sendBeacon.bind(nav)(fullApiUrl + \"/append\", stringify(append));\n } catch (e) {\n // Fallback for browsers throwing \"Illegal invocation\" when the URL is invalid\n sendData(append, undefinedVar, trueVar);\n }\n }\n };\n\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n\n\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n query,\n metadata,\n callback\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData(\n {\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: query || getQueryParams(deleteSourceInfo),\n\n },\n callback\n );\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (\n isPushState,\n pathOverwrite,\n metadata,\n callbackRaw\n ) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var querySearch;\n if (isString(pathOverwrite) && pathOverwrite.indexOf(\"?\") > -1) {\n // keep query from manual path\n var parts = pathOverwrite.split(\"?\");\n pathOverwrite = parts.shift();\n querySearch = \"?\" + parts.join(\"?\");\n }\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n sameSite = referrer\n ? referrer.split(slash)[0] == locationHostname\n : falseVar;\n\n\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n var delSrc =\n isPushState || userNavigated || !collectMetricByString(\"r\");\n sendPageView(\n isPushState,\n delSrc, // r = referrers\n sameSite,\n querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar,\n metadata,\n callback\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n\n\n pageview();\n\n } catch (e) {\n warn(e);\n }\n})(\n window,\n {},\n \"\",\n \"\",\n \"custom_light_12\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","warn","undefinedVar","undefined","https","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","language","documentElement","uaData","userAgentData","platformText","platformVersionText","docsUrl","isBotAgent","test","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","isString","string","attr","attribute","getAttribute","assign","obj","prop","object","to","arg","index","length","nextSource","constructor","Object","nextKey","hasOwnProperty","settings","sa_settings","logSettings","keys","Date","now","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","replace","c","getRandomValues","Uint8Array","toString","error","r","Math","random","isFunction","func","namespaceText","namespace","strictUtm","getQueryParams","ignoreSource","overwriteSearch","search","split","filter","keyValue","RegExp","join","loadedVariable","sa_event_loaded","timezone","sendData","data","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","Image","src","key","map","overwrittenHostname","hostname","definedHostname","basePayload","version","mode","Intl","DateTimeFormat","resolvedOptions","timeZone","bot","ua","protocol","page_id","session_id","sri","mobile","brands","hostname_original","indexOf","lastSendPath","referrer","sendOnLeave","id","push","append","type","original_id","sendBeacon","bind","e","sameSite","userNavigated","getPath","overwrite","path","pathname","isPushState","pathOverwrite","metadata","callbackRaw","querySearch","parts","shift","performaceEntryType","perf","performance","navigationText","getEntriesByType","triggerSendPageView","delSrc","deleteSourceInfo","query","currentPage","pages","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","pageview"],"mappings":";;CAEA,SACEA,EACAC,EACAC,EAKAC,GAEA,IAQE,IAAIC,EAAeC,UAIfC,EAAQ,SAKRC,EAAMP,EAAOQ,QACbC,EAAa,aACbC,EAAMV,EAAOW,UACbC,EAAMZ,EAAOa,SACbC,EAAmBF,EAAIG,KACvBC,EAAMhB,EAAOiB,SACbC,EAAYR,EAAIQ,UAChBC,EAAa,uBAEbC,GAhBW,EAiBXC,EAAyBC,mBACzBC,EAAyBC,mBACzBC,EAAYC,KAAKD,UAEjBE,EAAuB3B,EAAO4B,iBAC9BC,EAhBWvB,WAgB4BJ,EAEvC4B,GADkBd,EAAIe,gBACX,YAIXC,EAAStB,EAAIuB,cAMbC,EAAe,WACfC,EAAsB,kBACtBC,EAAU,mCAEVC,EACF,sBAAsBC,KAAKpB,KAAe,WAAWoB,KAAKpB,GAIxDqB,EACFvB,EAAIwB,eAAiBxB,EAAIyB,cAAc,gBAAkBvC,EAAU,MAOrEC,EAAO,WAEL,IAAIuC,EAAO,GAAGC,MAAMC,KAAKC,WAOzB,OAJAH,EAAKI,QAAQ,qBAINC,SAASC,UAAUC,MAAML,KAAKrC,EAAIJ,KAAMI,EAAKmC,IAGtD,IAQIQ,EAAW,SAAUC,GACvB,MAAwB,iBAAVA,GAOZC,EAAO,SAAUb,EAAec,GAClC,OAAOd,GAAiBA,EAAce,aAAa,QAAUD,IAe3DE,EAAS,WAGX,IAFA,IA7BsBC,EAAKC,EAwBJC,EAKnBC,EAAK,GACLC,EAAMf,UACDgB,EAAQ,EAAGA,EAAQD,EAAIE,OAAQD,IAAS,CAC/C,IAAIE,EAAaH,EAAIC,GACrB,IATqBH,EASRK,IAREL,EAAOM,cAAgBC,OASpC,IAAK,IAAIC,KAAWH,EAlCFP,EAmCJO,EAnCSN,EAmCGS,EAlCvBD,OAAOjB,UAAUmB,eAAevB,KAAKY,EAAKC,KAmCzCE,EAAGO,GAAWH,EAAWG,IAKjC,OAAOP,GAGLS,EAAWpE,EAAOqE,YAClBC,EAAcF,GAAYH,OAAOM,KAAKtE,GAAkB6D,OAG5D7D,EAAmBsD,EAAOtD,EAAkBmE,GAExCE,GAAanE,EAAK,WAAYF,GAQxBuE,KAAKC,IALf,IAOIC,EAAO,WACT,IAAIC,EAAe3E,EAAO4E,QAAU5E,EAAO6E,SACvCC,EAAY,CAAC,MAAQ,KAAO,KAAO,KAAO,KAC1CC,EAAY,SAEhB,IACE,OAAOD,EAAUE,QAAQD,EAAW,SAAUE,GAC5C,OACEA,EACCN,EAAaO,gBAAgB,IAAIC,WAAW,IAAI,GAC9C,IAAOF,EAAI,GACdG,SAAS,MAEb,MAAOC,GACP,OAAOP,EAAUE,QAAQD,EAAW,SAAUE,GAC5C,IAAIK,EAAqB,GAAhBC,KAAKC,SAAiB,EAE/B,OADMP,EAAI,EAAIK,EAAS,EAAJA,EAAW,GACrBF,SAAS,QAKpBK,EAAa,SAAUC,GACzB,MAAsB,mBAARA,GAIZC,EAAgB,YAChBC,EACF3F,EAAiB0F,IACjBvC,EAAKb,EAAeoD,IA4ZxB,KAlZME,EACF5F,EAAiB4F,WAvKJ,QAwKbzC,EAAKb,EAAe,cAElBuD,EAAiB,SAAUC,EAAcC,GAC3C,OACGA,GAAmBpF,EAAIqF,QACrBtD,MAAM,GACNuD,MAAM,KACNC,OAAO,SAAUC,GAGhB,OAFaL,GAaN,IAAIM,OART,YACCR,EAAY,GAAK,KAClB,yCACCA,EAAY,GAAK,QAClB,MAIuBvD,KAAK8D,KAE/BE,KAAK,MAAQlG,GAWhBmG,EAAiBX,EAAY,UACjC,GA7Mc,GA6MV5F,EAAOuG,GAA4B,OAAOpG,EAAKgB,EAAa,SAChEnB,EAAOwG,iBA9MO,EA+MdxG,EAAOuG,IA/MO,EAsNd,IA4DIE,EA5DAC,EAAW,SAAUC,EAAMC,EAAUC,GACvCF,EAAOE,EAAeF,EAAOpD,EAAOuD,EAASC,EAAMJ,GAE/CjG,EAAIsG,QAAUH,IAAcF,EAAKK,OAzNzB,GA0NRtG,EAAIuG,qBAAuBJ,IAAcF,EAAKO,MA1NtC,IA6NA,IAAIC,OACVC,IACJvF,EACA,eACAoC,OAAOM,KAAKoC,GACTR,OAAO,SAAUkB,GAChB,OAAOV,EAAKU,IAAQjH,IAErBkH,IAAI,SAAUD,GACb,OACEhG,EAAuBgG,GACvB,IACAhG,EAAuBsF,EAAKU,MAG/Bf,KAAK,KACR,SACA9B,KAAKC,OAIL8C,EACFtH,EAAiBuH,UAAYpE,EAAKb,EAAe,YAC/CkF,EAAkBF,GAAuBzG,EAEzC4G,EAAc,CAChBC,QAkUJ,kBAjUIH,SAAUC,GAeDxH,EAAiB2H,MAAQxE,EAAKb,EAAe,QAYxD,IAEEkE,EACIoB,KAAKC,iBAAiBC,kBAAkBC,SAE5C,MAAO3C,GACPlF,EAAKkF,GAQGhD,IAMDqF,EAAYO,KAvSP,GAySd,IAAInB,EAAUvD,EAAOmE,EAAa,CAEhCQ,GAAkChH,EAElCZ,MAAOM,EAAIuH,UAAY7H,EACvBmG,SAAUA,EACV2B,QAA8B1D,IAG9B2D,WAA0C3D,MAwB5C,GArBAoC,EAAQwB,KApTO,EAwTXtG,IACF8E,EAAQyB,OAASvG,EAAOuG,OACxBzB,EAAQ0B,OAAS/G,EAAUO,EAAOwG,SAWhCf,IAAoB3G,IACtBgG,EAAQ2B,kBAAoB3H,GAG1BL,KAAcC,GAA0B,KAAnBA,EAAID,GAC3B,OAAON,EA3TYgB,4BA4TAV,EAAa,oBAAsB2B,EAAU,SAK7B,GAAlCtB,EAAiB4H,QAAQ,OACxB,aAAapG,KAAKxB,IACnByG,GAEDpH,EACE,mBACEW,EACA,SACAsB,EACA,0BAON,IACIuG,EADA5B,EAAO,GAiBP6B,GAXA3I,EAAiB2I,UAAYxF,EAAKb,EAAe,aAGzBvB,EAAI4H,UAAY,IACrC5D,QAAQlE,EAAkB2G,GAC1BzC,QAAQ,sDAAuD,MAC/DA,QAAQ,YAAa,OAAS5E,EAcjCyI,EAAc,SAAUC,EAAIC,GAG9B,IAAIC,EAASzF,EAAOmE,EAAa,CAC/BuB,KAAM,SACNC,YAAaH,EAAOD,EAAKhC,EAAQsB,UAKnC,GAAIW,IAASrI,EAAIyI,WAEfzC,EAASsC,EAAQ5I,GAvYP,QAyYV,IACEM,EAAIyI,WAAWC,KAAK1I,EAApBA,CAAyBmB,EAAa,UAAWJ,EAAUuH,IAC3D,MAAOK,GAEP3C,EAASsC,EAAQ5I,GA7YT,KAmZduB,EAjXe,WAiXgBkH,GAlZhB,GAyZf,IAkDIS,EAAUC,EAlDVC,EAAU,SAAUC,GACtB,IAAIC,EAAO,GAIX,IACEA,EAAOD,GAAalI,EAAuBX,EAAI+I,UAC/C,MAAOtE,GACPlF,EAAKkF,GAMP,OAAOqE,IAsCM,SACbE,EACAC,EACAC,EACAC,IAEKA,GAAetE,EAAWqE,KAAWC,EAAcD,GACxD,IACIE,EAGEC,EAJSxE,EAAWsE,GAEtB7G,EAAS2G,KAAgD,EAA9BA,EAAcnB,QAAQ,OAGnDmB,GADII,EAAQJ,EAAc3D,MAAM,MACVgE,QACtBF,EAAc,IAAMC,EAAM3D,KAAK,MAGjC,IAAIoD,EAAOF,EAAQK,GAGnB,GAAKH,GAAQf,GAAgBe,EAA7B,CAEAf,EAAee,EACf3C,EAAK2C,KAAOA,EAKNhJ,EAAIoB,KAAWiF,EAAKjF,GAAYpB,EAAIoB,IAK1C,IAIIqI,EAJAC,EAAOpK,EAAOqK,YACdC,EAAiB,aAIrB,IACEH,EAAsBC,EAAKG,iBAAiBD,GAAgB,GAAGrB,KAC/D,MAAO5D,GACPlF,EAAKkF,GAGPkE,EAAgBY,GAC+C,EAA3D,CAAC,SAAU,gBAAgBzB,QAAQyB,GAGnCC,GACAA,EAAKE,KACwC,EAA7C,CAAC,EAAG,GAAG5B,QAAQ0B,EAAKE,GAAgBrB,MAGxCK,IAAWV,GACPA,EAAS1C,MA7fH,KA6fgB,IAAMpF,EAKhC,IAAI0J,EAAsB,WACxBpJ,GAzgBU,EA0gBV,IAAIqJ,EACFb,GAAeL,IAAiB,GA7FnB,SACjBK,EACAc,EACApB,EACAqB,GAIIf,GAAaf,EAAY,GAAK/B,EAAQsB,SAtb9B,GAubYtB,EAAQsB,QAAU1D,IAE1C,IAAIkG,EAAcnD,EAAkB+B,IAEpC9C,EACE,CACEoC,GAAIhC,EAAQsB,QACZa,KA1ba,WA2bbL,UAAW8B,GAAoBpB,EAAWV,EAAW,KACrD+B,MAAOA,GAAS7E,EAAe4E,KAOnC9B,EAAWgC,EAEXC,EAmEEC,CACElB,EACAa,EACAnB,EACAU,EAAclE,EAAe2E,EAAQT,GAAe5J,IAMxD,GAAKgB,EAmBHoJ,SAjBA,IACMxI,GAAUyD,EAAWzD,EAAO+I,sBAC9B/I,EACG+I,qBAAqB,CAAC7I,EAAcC,IACpC6I,KAAK,SAAUC,GACdnE,EAAQoE,QAAUD,EAAkB/I,GACpC4E,EAAQqE,WAAaF,EAAkB9I,GACvCqI,MAEDY,SAAMZ,GAETA,IAEF,MAAOnB,GACPmB,MASNa,GAEA,MAAOhC,GACPlJ,EAAKkJ,IArkBT,CAwkBErJ,OACA,uBACA"} \ No newline at end of file diff --git a/dist/latest/custom/proxy.js b/dist/latest/custom/proxy.js index 3c4bf08d..2f733240 100644 --- a/dist/latest/custom/proxy.js +++ b/dist/latest/custom/proxy.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy friendly analytics (docs.simpleanalytics.com/script; 2023-05-03; 9b4d; v11) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; 1d2a; v12) */ -!function(l,t,e,n,p){try{var h=undefined,f=!0,d=!1,r="true",a="https:",m="pageview",u="event",i="error",o=l.console,c="doNotTrack",g=l.navigator,s=l.location,v=s.host,y=l.document,_=g.userAgent,w="Not sending request ",b=w+"when ",x=d,E=encodeURIComponent,O=decodeURIComponent,S=JSON.stringify,M=l.addEventListener,k="https://"+e,A=y.documentElement||{},q="language",$="Height",j="scroll",D=g.userAgentData,C=j+$,H="offset"+$,P="client"+$,R="pagehide",T="platform",U="platformVersion",I="https://docs.simpleanalytics.com",V=0,B=/(bot|spider|crawl)/i.test(_)&&!/(cubot)/i.test(_),N=l.screen,z=y.currentScript||y.querySelector('script[src*="'+e+'"]');p=function(){var t=[].slice.call(arguments);return t.unshift("Simple Analytics:"),Function.prototype.apply.call(o.warn,o,t)};var F=function(t,e){p("Error in your "+t+" function:",e)},W=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},G=function(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},J=function(t,e){return t&&t.getAttribute("data-"+e)},L=function(t){return Array.isArray(t)?t:"string"==typeof t&&t.length?t.split(/, ?/):[]},Y=function(t){return t&&t.constructor===Object},Z=function(){for(var t={},e=arguments,n=0;n>t/4).toString(16)})}catch(r){return t.replace(n,function(t){var e=16*Math.random()|0;return(t<2?e:3&e|8).toString(16)})}},rt=function(t){return"function"==typeof t},at="namespace",it=t[at]||J(z,at)||"sa",ot=l[it+"_metadata"],ct=function(t,e){Y(ot)&&(t=Z(t,ot));var n=l[Mt];if(!rt(n))return t;try{return Z(t,n.call(l,Z(t,e)))}catch(r){F("metadata",r)}},st=t.strictUtm||J(z,"strict-utm")==r,ut=function(a){return s.search.slice(1).split("&").filter(function(t){var e=a||!tt("ut"),n=Et.map(G).join("|"),r=e?"^("+n+")=":"^((utm_)"+(st?"":"?")+"(source|medium|content|term|campaign)"+(st?"":"|ref")+"|"+n+")=";return e&&!Et.length?d:new RegExp(r).test(t)}).join("&")||h},lt=it+"_loaded";if(l[lt]==f)return p(w+"twice");l.sa_event_loaded=f,l[lt]=f;var pt=function(e,t,n){e=n?e:Z(qt,Dt,e),g.brave&&!n&&(e.brave=f),g._duckduckgoloader_&&!n&&(e.duck=f);var r=new Image;t&&(r.onerror=t,r.onload=t),r.src=k+"/simple.gif?"+Object.keys(e).filter(function(t){return e[t]!=h}).map(function(t){return E(t)+"="+E(e[t])}).join("&")+"&time="+Date.now()},ht=t.hostname||J(z,"hostname"),ft=ht||v,dt={version:"custom_proxy_11",hostname:ft};n=function(t){t=t.stack?t+" "+t.stack:t,p(t),pt(Z(dt,{type:i,error:t,path:s.pathname}),h,f)},M(i,function(t){t.filename&&-1"); +!function(d,t,e,n,m){try{var g=undefined,v=!0,y=!1,r="true",a="https:",_="pageview",u="event",i="error",o=d.console,c="doNotTrack",w=d.navigator,s=d.location,b=s.host,l=d.document,p=w.userAgent,f="Not sending request ",h=f+"when ",x=y,O=encodeURIComponent,E=decodeURIComponent,S=JSON.stringify,M=d.addEventListener,k="https://"+e,A=l.documentElement||{},q="language",$="Height",j="scroll",D=w.userAgentData,C=j+$,H="offset"+$,P="client"+$,R="pagehide",T="platform",U="platformVersion",I="https://docs.simpleanalytics.com",V=0,B=/(bot|spider|crawl)/i.test(p)&&!/(cubot)/i.test(p),N=d.screen,z=l.currentScript||l.querySelector('script[src*="'+e+'"]');m=function(){var t=[].slice.call(arguments);return t.unshift("Simple Analytics:"),Function.prototype.apply.call(o.warn,o,t)};var F=function(t,e){m("Error in your "+t+" function:",e)},W=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},G=function(t){return"string"==typeof t},J=function(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},L=function(t,e){return t&&t.getAttribute("data-"+e)},Y=function(t){return Array.isArray(t)?t:G(t)&&t.length?t.split(/, ?/):[]},Z=function(t){return t&&t.constructor===Object},K=function(){for(var t={},e=arguments,n=0;n>t/4).toString(16)})}catch(r){return t.replace(n,function(t){var e=16*Math.random()|0;return(t<2?e:3&e|8).toString(16)})}},at=function(t){return"function"==typeof t},it="namespace",ot=t[it]||L(z,it)||"sa",ct=function(t,e){var n=d[ot+"_metadata"];Z(n)&&(t=K(t,n));var r=d[Mt];if(!at(r))return Mt&&m(Mt+" not found, set window."+Mt),t;try{return K(t,r.call(d,K(t,e)))}catch(a){F("metadata",a)}},st=t.strictUtm||L(z,"strict-utm")==r,ut=function(a,t){return(t||s.search).slice(1).split("&").filter(function(t){var e=a||!et("ut"),n=Ot.map(J).join("|"),r=e?"^("+n+")=":"^((utm_)"+(st?"":"?")+"(source|medium|content|term|campaign)"+(st?"":"|ref")+"|"+n+")=";return e&&!Ot.length?y:new RegExp(r).test(t)}).join("&")||g},lt=ot+"_loaded";if(d[lt]==v)return m(f+"twice");d.sa_event_loaded=v,d[lt]=v;var pt=function(e,t,n){e=n?e:K($t,Ct,e),w.brave&&!n&&(e.brave=v),w._duckduckgoloader_&&!n&&(e.duck=v);var r=new Image;t&&(r.onerror=t,r.onload=t),r.src=k+"/simple.gif?"+Object.keys(e).filter(function(t){return e[t]!=g}).map(function(t){return O(t)+"="+O(e[t])}).join("&")+"&time="+Date.now()},ft=t.hostname||L(z,"hostname"),ht=ft||b,dt={version:"custom_proxy_12",hostname:ht};n=function(t){t=t.stack?t+" "+t.stack:t,m(t),pt(K(dt,{type:i,error:t,path:s.pathname}),g,v)},M(i,function(t){t.filename&&-1"); //# sourceMappingURL=proxy.js.map \ No newline at end of file diff --git a/dist/latest/custom/proxy.js.map b/dist/latest/custom/proxy.js.map index 88f16711..7554d2cd 100644 --- a/dist/latest/custom/proxy.js.map +++ b/dist/latest/custom/proxy.js.map @@ -1 +1 @@ -{"version":3,"file":"proxy.source.js","sources":["proxy.source.js"],"sourcesContent":["/* eslint-env browser */\n\n(function (\n window,\n overwriteOptions,\n baseUrl,\n apiUrlPrefix,\n version,\n defaultNamespace,\n sendError,\n warn\n) {\n try {\n /////////////////////\n // PREDEFINED VARIABLES FOR BETTER MINIFICATION\n //\n\n // This seems like a lot of repetition, but it makes our script available for\n // multple destination which prevents us to need multiple scripts. The minified\n // version stays small.\n var undefinedVar = undefined;\n var trueVar = true;\n var falseVar = false;\n var trueText = \"true\";\n var https = \"https:\";\n var pageviewText = \"pageview\";\n var eventText = \"event\";\n var errorText = \"error\";\n var slash = \"/\";\n var protocol = https + \"//\";\n var con = window.console;\n var doNotTrack = \"doNotTrack\";\n var nav = window.navigator;\n var loc = window.location;\n var locationHostname = loc.host;\n var doc = window.document;\n var userAgent = nav.userAgent;\n var notSending = \"Not sending request \";\n var notSendingWhen = notSending + \"when \";\n var fetchedHighEntropyValues = falseVar;\n var encodeURIComponentFunc = encodeURIComponent;\n var decodeURIComponentFunc = decodeURIComponent;\n var stringify = JSON.stringify;\n var thousand = 1000;\n var addEventListenerFunc = window.addEventListener;\n var fullApiUrl = protocol + apiUrlPrefix + baseUrl;\n var documentElement = doc.documentElement || {};\n var language = \"language\";\n var Height = \"Height\";\n var Width = \"Width\";\n var scroll = \"scroll\";\n var uaData = nav.userAgentData;\n var scrollHeight = scroll + Height;\n var offsetHeight = \"offset\" + Height;\n var clientHeight = \"client\" + Height;\n var clientWidth = \"client\" + Width;\n var pagehide = \"pagehide\";\n var platformText = \"platform\";\n var platformVersionText = \"platformVersion\";\n var docsUrl = \"https://docs.simpleanalytics.com\";\n var pages = 0;\n var isBotAgent =\n /(bot|spider|crawl)/i.test(userAgent) && !/(cubot)/i.test(userAgent);\n var screen = window.screen;\n\n\n // Find the script element where options can be set on\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"' + baseUrl + '\"]');\n\n /////////////////////\n // HELPER FUNCTIONS\n //\n\n // A simple log function so the user knows why a request is not being send\n warn = function () {\n // 1. Convert args to a normal array\n var args = [].slice.call(arguments);\n\n // 2. Prepend log prefix\n args.unshift(\"Simple Analytics:\");\n\n // 3. Pass along arguments to console.warn\n // Function.prototype.apply.call is needed for Internet Explorer\n return Function.prototype.apply.call(con.warn, con, args);\n };\n\n var warnInFunction = function (name, error) {\n warn(\"Error in your \" + name + \" function:\", error);\n };\n\n var hasProp = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n\n var isString = function (string) {\n return typeof string == \"string\";\n };\n\n var filterRegex = function (item) {\n return item.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n var attr = function (scriptElement, attribute) {\n return scriptElement && scriptElement.getAttribute(\"data-\" + attribute);\n };\n\n var convertCommaSeparatedToArray = function (csv) {\n return Array.isArray(csv)\n ? csv\n : isString(csv) && csv.length\n ? csv.split(/, ?/)\n : [];\n };\n\n var isObject = function (object) {\n return object && object.constructor === Object;\n };\n\n var assign = function () {\n var to = {};\n var arg = arguments;\n for (var index = 0; index < arg.length; index++) {\n var nextSource = arg[index];\n if (isObject(nextSource)) {\n for (var nextKey in nextSource) {\n if (hasProp(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n\n var settings = window.sa_settings;\n var logSettings = settings || Object.keys(overwriteOptions).length;\n\n // Merge overwriteOptions with sa_settings\n overwriteOptions = assign(overwriteOptions, settings);\n\n if (logSettings) warn(\"Settings\", overwriteOptions);\n\n // Customers can skip data points\n var ignoreMetrics = convertCommaSeparatedToArray(\n overwriteOptions.ignoreMetrics || attr(scriptElement, \"ignore-metrics\")\n );\n\n var collectMetricByString = function (metricAbbreviation) {\n // Can't use Array.find() here because we need to support IE9\n return (\n ignoreMetrics.filter(function (item) {\n return new RegExp(\"^\" + metricAbbreviation).test(item);\n }).length === 0\n );\n };\n\n var now = Date.now;\n\n var uuid = function () {\n var cryptoObject = window.crypto || window.msCrypto;\n var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;\n var uuidRegex = /[018]/g;\n\n try {\n return emptyUUID.replace(uuidRegex, function (c) {\n return (\n c ^\n (cryptoObject.getRandomValues(new Uint8Array(1))[0] &\n (15 >> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n var metadataObject = window[namespace + \"_metadata\"];\n var appendMetadata = function (metadata, data) {\n if (isObject(metadataObject)) metadata = assign(metadata, metadataObject);\n var metadataCollectorFunction = window[metadataCollector];\n if (!isFunction(metadataCollectorFunction)) return metadata;\n try {\n return assign(\n metadata,\n metadataCollectorFunction.call(window, assign(metadata, data))\n );\n } catch (error) {\n warnInFunction(\"metadata\", error);\n }\n };\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource) {\n return (\n loc.search\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n var paramsRegexList = allowParams.map(filterRegex).join(\"|\");\n var regex = ignore\n ? \"^(\" + paramsRegexList + \")=\"\n : \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \"|\" +\n paramsRegexList +\n \")=\";\n if (ignore && !allowParams.length) return falseVar;\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n // Ignore pages specified in data-ignore-pages\n var shouldIgnore = function (path) {\n for (var i in ignorePages) {\n var ignorePageRaw = ignorePages[i];\n if (!ignorePageRaw) continue;\n\n // Prepend a slash when it's missing\n var ignorePage =\n ignorePageRaw[0] == slash ? ignorePageRaw : slash + ignorePageRaw;\n\n if (\n ignorePage === path ||\n new RegExp(\n \"^\" + filterRegex(ignorePage).replace(/\\\\\\*/gi, \"(.*)\") + \"$\",\n \"i\"\n ).test(path)\n )\n return trueVar;\n }\n return falseVar;\n };\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n if (callback) {\n image.onerror = callback;\n image.onload = callback;\n }\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n /////////////////////\n // ERROR FUNCTIONS\n //\n\n // Send errors\n // no var because it's scoped outside of the try/catch\n sendError = function (errorOrMessage) {\n errorOrMessage = errorOrMessage.stack\n ? errorOrMessage + \" \" + errorOrMessage.stack\n : errorOrMessage;\n warn(errorOrMessage);\n sendData(\n assign(basePayload, {\n type: errorText,\n error: errorOrMessage,\n path: loc.pathname,\n }),\n undefinedVar,\n trueVar\n );\n };\n\n // We listen for the error events and only send errors that are\n // from our script (checked by filename) to our server.\n addEventListenerFunc(\n errorText,\n function (event) {\n if (event.filename && event.filename.indexOf(baseUrl) > -1) {\n sendError(event.message);\n }\n },\n falseVar\n );\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n var start = now();\n\n var scrolled = 0;\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n // Should we record Do Not Track visits?\n var collectDnt = isBoolean(overwriteOptions.collectDnt)\n ? overwriteOptions.collectDnt\n : attr(scriptElement, \"ignore-dnt\") == trueText ||\n attr(scriptElement, \"skip-dnt\") == trueText ||\n attr(scriptElement, \"collect-dnt\") == trueText;\n\n // Some customers want to collect page views manually\n var autoCollect = !(\n attr(scriptElement, \"auto-collect\") == \"false\" ||\n overwriteOptions.autoCollect === falseVar\n );\n\n // Event function name\n var eventFunctionName =\n overwriteOptions.saGlobal ||\n attr(scriptElement, \"sa-global\") ||\n namespace + \"_\" + eventText;\n\n // Customers can ignore certain pages\n var ignorePages = convertCommaSeparatedToArray(\n overwriteOptions.ignorePages || attr(scriptElement, \"ignore-pages\")\n );\n\n // Customers can allow params\n var allowParams = convertCommaSeparatedToArray(\n overwriteOptions.allowParams || attr(scriptElement, \"allow-params\")\n );\n\n // Customers can allow params\n var nonUniqueHostnames = convertCommaSeparatedToArray(\n overwriteOptions.nonUniqueHostnames ||\n attr(scriptElement, \"non-unique-hostnames\")\n );\n\n // Customers can overwrite certain values\n var pathOverwriter =\n overwriteOptions.pathOverwriter || attr(scriptElement, \"path-overwriter\");\n\n // Customers can add metadata to events and pageviews via a function\n var metadataCollector =\n overwriteOptions.metadataCollector ||\n attr(scriptElement, \"metadata-collector\");\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var bot =\n nav.webdriver ||\n window.__nightmare ||\n window.callPhantom ||\n window._phantom ||\n window.phantom ||\n window.__polypane ||\n window._bot ||\n isBotAgent ||\n Math.random() == Math.random();\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = falseVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n // Warn when no document.doctype is defined (this breaks some documentElement dimensions)\n if (!doc.doctype) warn(\"Add DOCTYPE html for accurate dimensions\");\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (!collectDnt && doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n return (\n (doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n // t = timeonpage\n if (collectMetricByString(\"t\")) {\n append.duration = Math.round((now() - start - msHidden) / thousand);\n }\n msHidden = 0;\n start = now();\n\n // scro = scrolled\n if (collectMetricByString(\"scro\")) {\n append.scrolled = Math.max(0, scrolled, position());\n }\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n nav.sendBeacon(fullApiUrl + \"/append\", stringify(append));\n }\n };\n\n var hiddenStart;\n addEventListenerFunc(\n \"visibilitychange\",\n function () {\n if (doc.hidden) {\n if (!(\"on\" + pagehide in window)) sendOnLeave();\n hiddenStart = now();\n } else msHidden += now() - hiddenStart;\n },\n falseVar\n );\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n var body = doc.body || {};\n var position = function () {\n try {\n var documentClientHeight = documentElement[clientHeight] || 0;\n var height = Math.max(\n body[scrollHeight] || 0,\n body[offsetHeight] || 0,\n documentElement[clientHeight] || 0,\n documentElement[scrollHeight] || 0,\n documentElement[offsetHeight] || 0\n );\n return Math.min(\n 100,\n Math.round(\n (100 * ((documentElement.scrollTop || 0) + documentClientHeight)) /\n height /\n 5\n ) * 5\n );\n } catch (error) {\n warn(error);\n return 0;\n }\n };\n\n addEventListenerFunc(\"load\", function () {\n scrolled = position();\n addEventListenerFunc(\n scroll,\n function () {\n if (scrolled < position()) scrolled = position();\n },\n falseVar\n );\n });\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n var pathOverwriterFunction = window[pathOverwriter];\n if (isFunction(pathOverwriterFunction)) {\n try {\n path = pathOverwriterFunction.call(window, { path: path }) || path;\n } catch (error) {\n warnInFunction(\"path\", error);\n }\n }\n\n // Ignore pages specified in data-ignore-pages\n if (shouldIgnore(path)) {\n warn(notSendingWhen + \"ignoring \" + path);\n return;\n }\n\n // Add hash to path when script is put in to hash mode\n if (mode == \"hash\" && loc.hash) path += loc.hash.split(\"?\")[0];\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n metadata\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData({\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: getQueryParams(deleteSourceInfo),\n\n metadata: stringify(metadata),\n });\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (isPushState, pathOverwrite, metadata) {\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n // v = viewportsizes\n if (collectMetricByString(\"v\")) {\n page.viewport_width =\n Math.max(documentElement[clientWidth] || 0, window.innerWidth || 0) ||\n null;\n page.viewport_height =\n Math.max(\n documentElement[clientHeight] || 0,\n window.innerHeight || 0\n ) || null;\n }\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n // sc = screensizes\n if (screen && collectMetricByString(\"sc\")) {\n page.screen_width = screen.width;\n page.screen_height = screen.height;\n }\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n var currentReferrerHostname = referrer\n ? referrer.split(slash)[0]\n : undefinedVar;\n sameSite = referrer\n ? nonUniqueHostnames.indexOf(currentReferrerHostname) > -1 ||\n currentReferrerHostname == locationHostname\n : falseVar;\n\n // We set unique variable based on pushstate or back navigation, if no match we check the referrer\n page.unique = isPushState || userNavigated ? falseVar : !sameSite;\n\n metadata = appendMetadata(metadata, {\n type: pageviewText,\n path: page.path,\n });\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n sendPageView(\n isPushState,\n isPushState || userNavigated || !collectMetricByString(\"r\"), // r = referrers\n sameSite,\n metadata\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n /////////////////////\n // AUTOMATED PAGE VIEW COLLECTION\n //\n\n var his = window.history;\n var hisPushState = his ? his.pushState : undefinedVar;\n var dis = window.dispatchEvent;\n var pushStateText = \"pushState\";\n\n // Overwrite history pushState function to\n // allow listening on the pushState event\n if (autoCollect && hisPushState && Event && dis) {\n var stateListener = function (type) {\n var orig = his[type];\n return function () {\n var arg = arguments;\n var rv = orig.apply(this, arg);\n var event;\n if (isFunction(Event)) {\n event = new Event(type);\n } else {\n // Fix for IE\n // https://github.com/simpleanalytics/scripts/issues/8\n event = doc.createEvent(\"Event\");\n event.initEvent(type, trueVar, trueVar);\n }\n event.arguments = arg;\n dis(event);\n return rv;\n };\n };\n\n his.pushState = stateListener(pushStateText);\n\n addEventListenerFunc(\n pushStateText,\n function () {\n pageview(1);\n },\n falseVar\n );\n\n addEventListenerFunc(\n \"popstate\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n // When in hash mode, we record a pageview based on the onhashchange function\n if (autoCollect && mode == \"hash\" && \"onhashchange\" in window) {\n addEventListenerFunc(\n \"hashchange\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n if (autoCollect) pageview();\n else {\n window.sa_pageview = function (path, metadata) {\n pageview(0, path, metadata);\n };\n }\n\n /////////////////////\n // EVENTS\n //\n\n var validTypes = [\"string\", \"number\"];\n\n var sendEvent = function (event, metadata, callbackRaw) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n\n var eventIsFunction = isFunction(event);\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var eventType = typeof event;\n\n if (validTypes.indexOf(eventType) < 0 && !eventIsFunction) {\n warnInFunction(eventFunctionName, eventText + \" can't be \" + eventType);\n return callback();\n }\n\n try {\n if (eventIsFunction) {\n var eventOutput = event();\n if (validTypes.indexOf(typeof eventOutput) < 0) {\n warnInFunction(\n eventFunctionName,\n event + \" returns no string: \" + eventOutput\n );\n return callback();\n }\n event = eventOutput;\n }\n } catch (error) {\n warnInFunction(eventFunctionName, error);\n return callback();\n }\n\n event = (\"\" + event).replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_|_$)/g, \"\");\n\n var eventParams = { type: eventText, event: event };\n var firstPage = !userNavigated && pages < 2;\n\n metadata = appendMetadata(metadata, eventParams);\n\n if (event) {\n sendData(\n assign(eventParams, {\n id: uuid(),\n query: getQueryParams(!firstPage),\n referrer:\n (firstPage || sameSite) && collectMetricByString(\"r\")\n ? previousReferrer\n : null,\n\n metadata: stringify(metadata),\n }),\n callback\n );\n }\n };\n\n var defaultEventFunc = function (event, metadata, callback) {\n sendEvent(event, metadata, callback);\n };\n\n // Set default function if user didn't define a function\n if (!window[eventFunctionName])\n window[eventFunctionName] = defaultEventFunc;\n\n var eventFunc = window[eventFunctionName];\n\n // Read queue of the user defined function\n var queue = eventFunc && eventFunc.q ? eventFunc.q : [];\n\n // Overwrite user defined function\n window[eventFunctionName] = defaultEventFunc;\n\n // Post events from the queue of the user defined function\n for (var event in queue) {\n if (hasProp(queue, event)) {\n Array.isArray(queue[event])\n ? sendEvent.apply(null, queue[event])\n : sendEvent(queue[event]);\n }\n }\n } catch (e) {\n sendError(e);\n }\n})(\n window,\n {},\n \"\",\n \"\",\n \"custom_proxy_11\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","sendError","warn","undefinedVar","undefined","trueVar","falseVar","trueText","https","pageviewText","eventText","errorText","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","notSendingWhen","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","documentElement","language","Height","scroll","uaData","userAgentData","scrollHeight","offsetHeight","clientHeight","pagehide","platformText","platformVersionText","docsUrl","pages","isBotAgent","test","screen","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","warnInFunction","name","error","hasProp","obj","prop","Object","hasOwnProperty","filterRegex","item","replace","attr","attribute","getAttribute","convertCommaSeparatedToArray","csv","Array","isArray","length","split","isObject","object","constructor","assign","to","arg","index","nextSource","nextKey","settings","sa_settings","logSettings","keys","ignoreMetrics","collectMetricByString","metricAbbreviation","filter","RegExp","now","Date","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","c","getRandomValues","Uint8Array","toString","r","Math","random","isFunction","func","namespaceText","namespace","metadataObject","appendMetadata","metadata","data","metadataCollectorFunction","metadataCollector","strictUtm","getQueryParams","ignoreSource","search","keyValue","ignore","paramsRegexList","allowParams","map","join","regex","loadedVariable","sa_event_loaded","sendData","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","image","Image","onerror","onload","src","key","overwrittenHostname","hostname","definedHostname","basePayload","version","errorOrMessage","stack","type","path","pathname","event","filename","indexOf","message","timezone","start","scrolled","mode","collectDnt","value","autoCollect","eventFunctionName","saGlobal","ignorePages","nonUniqueHostnames","pathOverwriter","Intl","DateTimeFormat","resolvedOptions","timeZone","bot","webdriver","__nightmare","callPhantom","_phantom","phantom","__polypane","_bot","collectDataOnLeave","ua","protocol","page_id","session_id","sri","mobile","brands","doctype","hostname_original","lastSendPath","hiddenStart","referrer","msHidden","sendOnLeave","id","push","append","original_id","duration","round","max","position","sendBeacon","hidden","body","documentClientHeight","height","min","scrollTop","previousReferrer","sameSite","userNavigated","getPath","overwrite","pathOverwriterFunction","i","ignorePageRaw","ignorePage","shouldIgnore","hash","pageview","isPushState","pathOverwrite","viewport_width","innerWidth","viewport_height","innerHeight","screen_width","width","screen_height","performaceEntryType","perf","performance","navigationText","getEntriesByType","currentReferrerHostname","unique","triggerSendPageView","deleteSourceInfo","currentPage","query","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","e","his","history","hisPushState","pushState","dis","dispatchEvent","pushStateText","Event","orig","rv","this","createEvent","initEvent","sa_pageview","validTypes","sendEvent","callbackRaw","eventIsFunction","eventType","eventOutput","eventParams","firstPage","defaultEventFunc","eventFunc","queue","q"],"mappings":";;CAEA,SACEA,EACAC,EACAC,EAIAC,EACAC,GAEA,IAQE,IAAIC,EAAeC,UACfC,GAAU,EACVC,GAAW,EACXC,EAAW,OACXC,EAAQ,SACRC,EAAe,WACfC,EAAY,QACZC,EAAY,QAGZC,EAAMd,EAAOe,QACbC,EAAa,aACbC,EAAMjB,EAAOkB,UACbC,EAAMnB,EAAOoB,SACbC,EAAmBF,EAAIG,KACvBC,EAAMvB,EAAOwB,SACbC,EAAYR,EAAIQ,UAChBC,EAAa,uBACbC,EAAiBD,EAAa,QAC9BE,EAA2BpB,EAC3BqB,EAAyBC,mBACzBC,EAAyBC,mBACzBC,EAAYC,KAAKD,UAEjBE,EAAuBnC,EAAOoC,iBAC9BC,EAhBW3B,WAgB4BR,EACvCoC,EAAkBf,EAAIe,iBAAmB,GACzCC,EAAW,WACXC,EAAS,SAETC,EAAS,SACTC,EAASzB,EAAI0B,cACbC,EAAeH,EAASD,EACxBK,EAAe,SAAWL,EAC1BM,EAAe,SAAWN,EAE1BO,EAAW,WACXC,EAAe,WACfC,EAAsB,kBACtBC,EAAU,mCACVC,EAAQ,EACRC,EACF,sBAAsBC,KAAK5B,KAAe,WAAW4B,KAAK5B,GACxD6B,EAAStD,EAAOsD,OAIhBC,EACFhC,EAAIiC,eAAiBjC,EAAIkC,cAAc,gBAAkBvD,EAAU,MAOrEE,EAAO,WAEL,IAAIsD,EAAO,GAAGC,MAAMC,KAAKC,WAOzB,OAJAH,EAAKI,QAAQ,qBAINC,SAASC,UAAUC,MAAML,KAAK9C,EAAIV,KAAMU,EAAK4C,IAGtD,IAAIQ,EAAiB,SAAUC,EAAMC,GACnChE,EAAK,iBAAmB+D,EAAO,aAAcC,IAG3CC,EAAU,SAAUC,EAAKC,GAC3B,OAAOC,OAAOR,UAAUS,eAAeb,KAAKU,EAAKC,IAO/CG,EAAc,SAAUC,GAC1B,OAAOA,EAAKC,QAAQ,sBAAuB,SAGzCC,EAAO,SAAUtB,EAAeuB,GAClC,OAAOvB,GAAiBA,EAAcwB,aAAa,QAAUD,IAG3DE,EAA+B,SAAUC,GAC3C,OAAOC,MAAMC,QAAQF,GACjBA,EAboB,iBAcXA,GAAQA,EAAIG,OACrBH,EAAII,MAAM,OACV,IAGFC,EAAW,SAAUC,GACvB,OAAOA,GAAUA,EAAOC,cAAgBhB,QAGtCiB,EAAS,WAGX,IAFA,IAAIC,EAAK,GACLC,EAAM9B,UACD+B,EAAQ,EAAGA,EAAQD,EAAIP,OAAQQ,IAAS,CAC/C,IAAIC,EAAaF,EAAIC,GACrB,GAAIN,EAASO,GACX,IAAK,IAAIC,KAAWD,EACdxB,EAAQwB,EAAYC,KACtBJ,EAAGI,GAAWD,EAAWC,IAKjC,OAAOJ,GAGLK,EAAW/F,EAAOgG,YAClBC,EAAcF,GAAYvB,OAAO0B,KAAKjG,GAAkBmF,OAG5DnF,EAAmBwF,EAAOxF,EAAkB8F,GAExCE,GAAa7F,EAAK,WAAYH,GAGlC,IAAIkG,EAAgBnB,EAClB/E,EAAiBkG,eAAiBtB,EAAKtB,EAAe,mBAGpD6C,GAAwB,SAAUC,GAEpC,OAGgB,IAFdF,EAAcG,OAAO,SAAU3B,GAC7B,OAAO,IAAI4B,OAAO,IAAMF,GAAoBhD,KAAKsB,KAChDS,QAIHoB,GAAMC,KAAKD,IAEXE,GAAO,WACT,IAAIC,EAAe3G,EAAO4G,QAAU5G,EAAO6G,SACvCC,EAAY,CAAC,MAAQ,KAAO,KAAO,KAAO,KAC1CC,EAAY,SAEhB,IACE,OAAOD,EAAUlC,QAAQmC,EAAW,SAAUC,GAC5C,OACEA,EACCL,EAAaM,gBAAgB,IAAIC,WAAW,IAAI,GAC9C,IAAOF,EAAI,GACdG,SAAS,MAEb,MAAO/C,GACP,OAAO0C,EAAUlC,QAAQmC,EAAW,SAAUC,GAC5C,IAAII,EAAqB,GAAhBC,KAAKC,SAAiB,EAE/B,OADMN,EAAI,EAAII,EAAS,EAAJA,EAAW,GACrBD,SAAS,QAKpBI,GAAa,SAAUC,GACzB,MAAsB,mBAARA,GAIZC,GAAgB,YAChBC,GACFzH,EAAiBwH,KACjB5C,EAAKtB,EAAekE,KA6uBxB,KA1uBME,GAAiB3H,EAAO0H,GAAY,aACpCE,GAAiB,SAAUC,EAAUC,GACnCxC,EAASqC,MAAiBE,EAAWpC,EAAOoC,EAAUF,KAC1D,IAAII,EAA4B/H,EAAOgI,IACvC,IAAKT,GAAWQ,GAA4B,OAAOF,EACnD,IACE,OAAOpC,EACLoC,EACAE,EAA0BnE,KAAK5D,EAAQyF,EAAOoC,EAAUC,KAE1D,MAAO1D,GACPF,EAAe,WAAYE,KAU3B6D,GACFhI,EAAiBgI,WACjBpD,EAAKtB,EAAe,eAAiB9C,EAEnCyH,GAAiB,SAAUC,GAC7B,OACEhH,EAAIiH,OACDzE,MAAM,GACN0B,MAAM,KACNiB,OAAO,SAAU+B,GAChB,IAAIC,EAASH,IAAiB/B,GAAsB,MAEhDmC,EAAkBC,GAAYC,IAAI/D,GAAagE,KAAK,KACpDC,EAAQL,EACR,KAAOC,EAAkB,KACzB,YACCN,GAAY,GAAK,KAClB,yCACCA,GAAY,GAAK,QAClB,IACAM,EACA,KACJ,OAAID,IAAWE,GAAYpD,OAAe5E,EAInC,IAAI+F,OAAOoC,GAAOtF,KAAKgF,KAE/BK,KAAK,MAAQrI,GAgChBuI,GAAiBlB,GAAY,UACjC,GAAI1H,EAAO4I,KAAmBrI,EAAS,OAAOH,EAAKsB,EAAa,SAChE1B,EAAO6I,gBAAkBtI,EACzBP,EAAO4I,IAAkBrI,EAOzB,IAAIuI,GAAW,SAAUhB,EAAMiB,EAAUC,GACvClB,EAAOkB,EAAelB,EAAOrC,EAAOwD,GAASC,GAAMpB,GAE/C7G,EAAIkI,QAAUH,IAAclB,EAAKqB,MAAQ5I,GACzCU,EAAImI,qBAAuBJ,IAAclB,EAAKuB,KAAO9I,GAGzD,IAAI+I,EAAQ,IAAIC,MACZR,IACFO,EAAME,QAAUT,EAChBO,EAAMG,OAASV,GAEjBO,EAAMI,IACJrH,EACA,eACAmC,OAAO0B,KAAK4B,GACTxB,OAAO,SAAUqD,GAChB,OAAO7B,EAAK6B,IAAQtJ,IAErBoI,IAAI,SAAUkB,GACb,OACE9H,EAAuB8H,GACvB,IACA9H,EAAuBiG,EAAK6B,MAG/BjB,KAAK,KACR,SACAjC,KAAKD,OAILoD,GACF3J,EAAiB4J,UAAYhF,EAAKtB,EAAe,YAC/CuG,GAAkBF,IAAuBvI,EAEzC0I,GAAc,CAChBC,QAymBJ,kBAxmBIH,SAAUC,IASZ3J,EAAY,SAAU8J,GACpBA,EAAiBA,EAAeC,MAC5BD,EAAiB,IAAMA,EAAeC,MACtCD,EACJ7J,EAAK6J,GACLnB,GACErD,EAAOsE,GAAa,CAClBI,KAAMtJ,EACNuD,MAAO6F,EACPG,KAAMjJ,EAAIkJ,WAEZhK,EACAE,IAMJ4B,EACEtB,EACA,SAAUyJ,GACJA,EAAMC,WAA+C,EAAnCD,EAAMC,SAASC,QAAQtK,IAC3CC,EAAUmK,EAAMG,UAGpBjK,GAOF,IAwDIkK,GAxDAC,GAAQnE,KAERoE,GAAW,EAOXC,GAAO5K,EAAiB4K,MAAQhG,EAAKtB,EAAe,QAGpDuH,MAvKsBC,GAuKC9K,EAAiB6K,cAtKvBC,GAuKjB9K,EAAiB6K,WACjBjG,EAAKtB,EAAe,eAAiB9C,GACrCoE,EAAKtB,EAAe,aAAe9C,GACnCoE,EAAKtB,EAAe,gBAAkB9C,EAGtCuK,KACqC,SAAvCnG,EAAKtB,EAAe,iBACpBtD,EAAiB+K,cAAgBxK,GAI/ByK,GACFhL,EAAiBiL,UACjBrG,EAAKtB,EAAe,cACpBmE,GAAY,IAAM9G,EAGhBuK,GAAcnG,EAChB/E,EAAiBkL,aAAetG,EAAKtB,EAAe,iBAIlDiF,GAAcxD,EAChB/E,EAAiBuI,aAAe3D,EAAKtB,EAAe,iBAIlD6H,GAAqBpG,EACvB/E,EAAiBmL,oBACfvG,EAAKtB,EAAe,yBAIpB8H,GACFpL,EAAiBoL,gBAAkBxG,EAAKtB,EAAe,mBAGrDyE,GACF/H,EAAiB+H,mBACjBnD,EAAKtB,EAAe,sBAItB,IAEEmH,GAAWtE,GAAsB,KAC7BkF,KAAKC,iBAAiBC,kBAAkBC,SACxCpL,EACJ,MAAO+D,IACPhE,EAAKgE,IAOP,IAAIsH,GACFzK,EAAI0K,WACJ3L,EAAO4L,aACP5L,EAAO6L,aACP7L,EAAO8L,UACP9L,EAAO+L,SACP/L,EAAOgM,YACPhM,EAAOiM,MACP7I,GACAiE,KAAKC,UAAYD,KAAKC,SAGpB4E,GACF9F,GAAsB,MAAQA,GAAsB,QAElDsF,KAAK3B,GAAY2B,IAAMnL,GAE3B,IAAI0I,GAAUxD,EAAOsE,GAAa,CAEhCoC,GAAI/F,GAAsB,MAAQ3E,EAAYpB,EAE9CK,MAAOS,EAAIiL,UAAY1L,EACvBgK,SAAUA,GACV2B,QAASH,GAAqBxF,KAASrG,EAGvCiM,WAAYlG,GAAsB,MAAQM,KAASrG,IA0BrD,GAvBA4I,GAAQsD,IAAM/L,EAIVkC,IACFuG,GAAQuD,OAAS9J,EAAO8J,OACxBvD,GAAQwD,OAASxK,EAAUS,EAAO+J,SAS/BlL,EAAImL,SAAStM,EAAK,4CAInB0J,KAAoBzI,IACtB4H,GAAQ0D,kBAAoBtL,IAGzByJ,IAAc9J,KAAcC,GAA0B,KAAnBA,EAAID,GAC1C,OAAOZ,EACLuB,EAAiBX,EAAa,oBAAsBkC,EAAU,SAK7B,GAAlC7B,EAAiBmJ,QAAQ,OACxB,aAAanH,KAAKhC,IACnBuI,IAEDxJ,EACE,mBACEiB,EACA,SACA6B,EACA,0BAON,IACI0J,GAiDAC,GAlDA3D,GAAO,GAaP4D,IARCvL,EAAIuL,UAAY,IACdlI,QAAQvD,EAAkByI,IAC1BlF,QAAQ,sDAAuD,MAC/DA,QAAQ,YAAa,OAASvE,EAYjC0M,GAAW,EAEXC,GAAc,SAAUC,EAAIC,GAC9B,IAEIC,EAFCjB,KAEDiB,EAAS1H,EAAOsE,GAAa,CAC/BI,KAAM,SACNiD,YAAaF,EAAOD,EAAKhE,GAAQoD,UAI/BjG,GAAsB,OACxB+G,EAAOE,SAAWhG,KAAKiG,OAAO9G,KAAQmE,GAAQoC,IAhfnC,MAkfbA,GAAW,EACXpC,GAAQnE,KAGJJ,GAAsB,UACxB+G,EAAOvC,SAAWvD,KAAKkG,IAAI,EAAG3C,GAAU4C,OAGtCN,IAASjM,EAAIwM,WAEf3E,GAASqE,EAAQ9M,EAAcE,GAE/BU,EAAIwM,WAAWpL,EAAa,UAAWJ,EAAUkL,MAKrDhL,EACE,mBACA,WACMZ,EAAImM,QACA,KAAO3K,KAAY/C,GAASgN,KAClCH,GAAcrG,MACTuG,IAAYvG,KAAQqG,IAE7BrM,GAGF2B,EAAqBY,EAAUiK,GAAaxM,GAE5C,IAAImN,GAAOpM,EAAIoM,MAAQ,GACnBH,GAAW,WACb,IACE,IAAII,EAAuBtL,EAAgBQ,IAAiB,EACxD+K,EAASxG,KAAKkG,IAChBI,GAAK/K,IAAiB,EACtB+K,GAAK9K,IAAiB,EACtBP,EAAgBQ,IAAiB,EACjCR,EAAgBM,IAAiB,EACjCN,EAAgBO,IAAiB,GAEnC,OAAOwE,KAAKyG,IACV,IAKI,EAJJzG,KAAKiG,MACF,MAAQhL,EAAgByL,WAAa,GAAKH,GACzCC,EACA,IAGN,MAAOzJ,IAEP,OADAhE,EAAKgE,IACE,IAIXjC,EAAqB,OAAQ,WAC3ByI,GAAW4C,KACXrL,EACEM,EACA,WACMmI,GAAW4C,OAAY5C,GAAW4C,OAExChN,KAQJ,IAgCIwN,GA6BAC,GAAUC,GA7DVC,GAAU,SAAUC,GACtB,IAAIhE,EAAO,GAIX,IACEA,EAAOgE,GAAarM,EAAuBZ,EAAIkJ,UAC/C,MAAOjG,IACPhE,EAAKgE,IAGP,IAAIiK,EAAyBrO,EAAOqL,IACpC,GAAI9D,GAAW8G,GACb,IACEjE,EAAOiE,EAAuBzK,KAAK5D,EAAQ,CAAEoK,KAAMA,KAAWA,EAC9D,MAAOhG,IACPF,EAAe,OAAQE,IAK3B,IAlYiB,SAAUgG,GAC3B,IAAK,IAAIkE,KAAKnD,GAAa,CACzB,IAAIoD,EAAgBpD,GAAYmD,GAChC,GAAKC,EAAL,CAGA,IAAIC,EAhOI,KAiOND,EAAc,GAAcA,EAjOtB,IAiO8CA,EAEtD,GACEC,IAAepE,GACf,IAAI7D,OACF,IAAM7B,EAAY8J,GAAY5J,QAAQ,SAAU,QAAU,IAC1D,KACAvB,KAAK+G,GAEP,OAAO7J,GAEX,OAAOC,EAgXHiO,CAAarE,GAQjB,MAFY,QAARS,IAAkB1J,EAAIuN,OAAMtE,GAAQjJ,EAAIuN,KAAKrJ,MAAM,KAAK,IAErD+E,EAPLhK,EAAKuB,EAAiB,YAAcyI,IAyCpCuE,GAAW,SAAUC,EAAaC,EAAehH,GAEnD,IAAIuC,EAAO+D,GAAQU,GAGnB,GAAKzE,GAAQwC,IAAgBxC,EAA7B,CAEAwC,GAAexC,EACflB,GAAKkB,KAAOA,EAGRhE,GAAsB,OACxB8C,GAAK4F,eACHzH,KAAKkG,IAAIjL,EAA2B,aAAK,EAAGtC,EAAO+O,YAAc,IACjE,KACF7F,GAAK8F,gBACH3H,KAAKkG,IACHjL,EAAgBQ,IAAiB,EACjC9C,EAAOiP,aAAe,IACnB,MAIL7I,GAAsB,MACpBnF,EAAIsB,KAAW2G,GAAK3G,GAAYtB,EAAIsB,IAItCe,GAAU8C,GAAsB,QAClC8C,GAAKgG,aAAe5L,EAAO6L,MAC3BjG,GAAKkG,cAAgB9L,EAAOuK,QAI9B,IAIIwB,EAJAC,EAAOtP,EAAOuP,YACdC,EAAiB,aAIrB,IACEH,EAAsBC,EAAKG,iBAAiBD,GAAgB,GAAGrF,KAC/D,MAAO/F,IACPhE,EAAKgE,IAGP8J,GAAgBmB,GAC+C,EAA3D,CAAC,SAAU,gBAAgB7E,QAAQ6E,GAGnCC,GACAA,EAAKE,KACwC,EAA7C,CAAC,EAAG,GAAGhF,QAAQ8E,EAAKE,GAAgBrF,MAGxC,IAAIuF,EAA0B5C,GAC1BA,GAASzH,MA7rBH,KA6rBgB,GACtBhF,EACJ4N,GAAWnB,IACgD,EAAvD1B,GAAmBZ,QAAQkF,IAC3BA,GAA2BrO,EAC3Bb,EAGJ0I,GAAKyG,OAASf,GAAeV,GAAgB1N,GAAYyN,GAEzDpG,EAAWD,GAAeC,EAAU,CAClCsC,KAAMxJ,EACNyJ,KAAMlB,GAAKkB,OAGb,IAAIwF,EAAsB,WACxBhO,EAA2BrB,EAnGZ,SACjBqO,EACAiB,EACA5B,EACApG,GAEI+G,GAAa5B,GAAY,GAAK/D,GAAQoD,QAAS9L,GAC/C2L,KAAoBjD,GAAQoD,QAAU3F,MAE1C,IAAIoJ,EAAchG,GAAkBqE,KAEpCrF,GAAS,CACPmE,GAAIhE,GAAQoD,QACZlC,KAAMxJ,EACNmM,UAAW+C,GAAoB5B,EAAWnB,GAAW,KACrDiD,MAAO7H,GAAe2H,GAEtBhI,SAAU5F,EAAU4F,KAGtBmG,GAAmBlB,GACnBA,GAAWgD,EAEX3M,IA6EE6M,CACEpB,EACAA,GAAeV,KAAkB9H,GAAsB,KACvD6H,GACApG,IAIJ,GAAKjG,EAmBHgO,SAjBA,IACMlN,GAAU6E,GAAW7E,EAAOuN,sBAC9BvN,EACGuN,qBAAqB,CAACjN,EAAcC,IACpCiN,KAAK,SAAUC,GACdlH,GAAQmH,QAAUD,EAAkBnN,GACpCiG,GAAQoH,WAAaF,EAAkBlN,GACvC2M,MAEDU,SAAMV,GAETA,IAEF,MAAOW,GACPX,OAWFY,GAAMxQ,EAAOyQ,QACbC,GAAeF,GAAMA,GAAIG,UAAYtQ,EACrCuQ,GAAM5Q,EAAO6Q,cACbC,GAAgB,YAIhB9F,IAAe0F,IAAgBK,OAASH,KAqB1CJ,GAAIG,WAnBEK,GAAOR,GADiBrG,GAoBA2G,IAlBrB,WACL,IAEIxG,EAFA3E,EAAM9B,UACNoN,EAAKD,GAAK/M,MAAMiN,KAAMvL,GAY1B,OAVI4B,GAAWwJ,OACbzG,EAAQ,IAAIyG,MAAM5G,KAIlBG,EAAQ/I,EAAI4P,YAAY,UAClBC,UAAUjH,GAAM5J,EAASA,GAEjC+J,EAAMzG,UAAY8B,EAClBiL,GAAItG,GACG2G,IAMX9O,EACE2O,GACA,WACEnC,GAAS,IAEXnO,GAGF2B,EACE,WACA,WACEwM,GAAS,IAEXnO,IAKAwK,IAAuB,QAARH,IAAkB,iBAAkB7K,GACrDmC,EACE,aACA,WACEwM,GAAS,IAEXnO,GAIAwK,GAAa2D,KAEf3O,EAAOqR,YAAc,SAAUjH,EAAMvC,GACnC8G,GAAS,EAAGvE,EAAMvC,IAQtB,IAAIyJ,GAAa,CAAC,SAAU,UAExBC,GAAY,SAAUjH,EAAOzC,EAAU2J,IACpCA,GAAejK,GAAWM,KAAW2J,EAAc3J,GAExD,IAAI4J,EAAkBlK,GAAW+C,GAC7BvB,EAAWxB,GAAWiK,GAAeA,EAAc,aACnDE,SAAmBpH,EAEvB,GAAIgH,GAAW9G,QAAQkH,GAAa,IAAMD,EAExC,OADAvN,EAAe+G,GAAmBrK,EAAY,aAAe8Q,GACtD3I,IAGT,IACE,GAAI0I,EAAiB,CACnB,IAAIE,EAAcrH,IAClB,GAAIgH,GAAW9G,eAAemH,GAAe,EAK3C,OAJAzN,EACE+G,GACAX,EAAQ,uBAAyBqH,GAE5B5I,IAETuB,EAAQqH,GAEV,MAAOvN,IAEP,OADAF,EAAe+G,GAAmB7G,IAC3B2E,IAGTuB,GAAS,GAAKA,GAAO1F,QAAQ,eAAgB,KAAKA,QAAQ,WAAY,IAEtE,IAAIgN,EAAc,CAAEzH,KAAMvJ,EAAW0J,MAAOA,GACxCuH,GAAa3D,IAAiB/K,EAAQ,EAE1C0E,EAAWD,GAAeC,EAAU+J,GAEhCtH,GACFxB,GACErD,EAAOmM,EAAa,CAClB3E,GAAIvG,KACJqJ,MAAO7H,IAAgB2J,GACvB/E,UACG+E,GAAa5D,KAAa7H,GAAsB,KAC7C4H,GACA,KAENnG,SAAU5F,EAAU4F,KAEtBkB,IAKF+I,GAAmB,SAAUxH,EAAOzC,EAAUkB,GAChDwI,GAAUjH,EAAOzC,EAAUkB,IAIxB/I,EAAOiL,MACVjL,EAAOiL,IAAqB6G,IAE9B,IAAIC,GAAY/R,EAAOiL,IAGnB+G,GAAQD,IAAaA,GAAUE,EAAIF,GAAUE,EAAI,GAMrD,IAAK,IAAI3H,MAHTtK,EAAOiL,IAAqB6G,GAGVE,GACZ3N,EAAQ2N,GAAO1H,MACjBpF,MAAMC,QAAQ6M,GAAM1H,KAChBiH,GAAUtN,MAAM,KAAM+N,GAAM1H,KAC5BiH,GAAUS,GAAM1H,MAGxB,MAAOiG,IACPpQ,EAAUoQ,IA7IY,IAAUpG,GACxB6G,GAvkBkBjG,GA7M9B,CAm6BE/K,OACA,uBACA"} \ No newline at end of file +{"version":3,"file":"proxy.source.js","sources":["proxy.source.js"],"sourcesContent":["/* eslint-env browser */\n\n(function (\n window,\n overwriteOptions,\n baseUrl,\n apiUrlPrefix,\n version,\n defaultNamespace,\n sendError,\n warn\n) {\n try {\n /////////////////////\n // PREDEFINED VARIABLES FOR BETTER MINIFICATION\n //\n\n // This seems like a lot of repetition, but it makes our script available for\n // multple destination which prevents us to need multiple scripts. The minified\n // version stays small.\n var undefinedVar = undefined;\n var trueVar = true;\n var falseVar = false;\n var trueText = \"true\";\n var https = \"https:\";\n var pageviewText = \"pageview\";\n var eventText = \"event\";\n var errorText = \"error\";\n var slash = \"/\";\n var protocol = https + \"//\";\n var con = window.console;\n var doNotTrack = \"doNotTrack\";\n var nav = window.navigator;\n var loc = window.location;\n var locationHostname = loc.host;\n var doc = window.document;\n var userAgent = nav.userAgent;\n var notSending = \"Not sending request \";\n var notSendingWhen = notSending + \"when \";\n var fetchedHighEntropyValues = falseVar;\n var encodeURIComponentFunc = encodeURIComponent;\n var decodeURIComponentFunc = decodeURIComponent;\n var stringify = JSON.stringify;\n var thousand = 1000;\n var addEventListenerFunc = window.addEventListener;\n var fullApiUrl = protocol + apiUrlPrefix + baseUrl;\n var documentElement = doc.documentElement || {};\n var language = \"language\";\n var Height = \"Height\";\n var Width = \"Width\";\n var scroll = \"scroll\";\n var uaData = nav.userAgentData;\n var scrollHeight = scroll + Height;\n var offsetHeight = \"offset\" + Height;\n var clientHeight = \"client\" + Height;\n var clientWidth = \"client\" + Width;\n var pagehide = \"pagehide\";\n var platformText = \"platform\";\n var platformVersionText = \"platformVersion\";\n var docsUrl = \"https://docs.simpleanalytics.com\";\n var pages = 0;\n var isBotAgent =\n /(bot|spider|crawl)/i.test(userAgent) && !/(cubot)/i.test(userAgent);\n var screen = window.screen;\n\n\n // Find the script element where options can be set on\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"' + baseUrl + '\"]');\n\n /////////////////////\n // HELPER FUNCTIONS\n //\n\n // A simple log function so the user knows why a request is not being send\n warn = function () {\n // 1. Convert args to a normal array\n var args = [].slice.call(arguments);\n\n // 2. Prepend log prefix\n args.unshift(\"Simple Analytics:\");\n\n // 3. Pass along arguments to console.warn\n // Function.prototype.apply.call is needed for Internet Explorer\n return Function.prototype.apply.call(con.warn, con, args);\n };\n\n var warnInFunction = function (name, error) {\n warn(\"Error in your \" + name + \" function:\", error);\n };\n\n var hasProp = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n\n var isString = function (string) {\n return typeof string == \"string\";\n };\n\n var filterRegex = function (item) {\n return item.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n var attr = function (scriptElement, attribute) {\n return scriptElement && scriptElement.getAttribute(\"data-\" + attribute);\n };\n\n var convertCommaSeparatedToArray = function (csv) {\n return Array.isArray(csv)\n ? csv\n : isString(csv) && csv.length\n ? csv.split(/, ?/)\n : [];\n };\n\n var isObject = function (object) {\n return object && object.constructor === Object;\n };\n\n var assign = function () {\n var to = {};\n var arg = arguments;\n for (var index = 0; index < arg.length; index++) {\n var nextSource = arg[index];\n if (isObject(nextSource)) {\n for (var nextKey in nextSource) {\n if (hasProp(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n\n var settings = window.sa_settings;\n var logSettings = settings || Object.keys(overwriteOptions).length;\n\n // Merge overwriteOptions with sa_settings\n overwriteOptions = assign(overwriteOptions, settings);\n\n if (logSettings) warn(\"Settings\", overwriteOptions);\n\n // Customers can skip data points\n var ignoreMetrics = convertCommaSeparatedToArray(\n overwriteOptions.ignoreMetrics || attr(scriptElement, \"ignore-metrics\")\n );\n\n var collectMetricByString = function (metricAbbreviation) {\n // Can't use Array.find() here because we need to support IE9\n return (\n ignoreMetrics.filter(function (item) {\n return new RegExp(\"^\" + metricAbbreviation).test(item);\n }).length === 0\n );\n };\n\n var now = Date.now;\n\n var uuid = function () {\n var cryptoObject = window.crypto || window.msCrypto;\n var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;\n var uuidRegex = /[018]/g;\n\n try {\n return emptyUUID.replace(uuidRegex, function (c) {\n return (\n c ^\n (cryptoObject.getRandomValues(new Uint8Array(1))[0] &\n (15 >> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n var appendMetadata = function (metadata, data) {\n var metadataObject = window[namespace + \"_metadata\"];\n if (isObject(metadataObject)) metadata = assign(metadata, metadataObject);\n var metadataCollectorFunction = window[metadataCollector];\n if (!isFunction(metadataCollectorFunction)) {\n if (metadataCollector)\n warn(\n metadataCollector + \" not found, set window.\" + metadataCollector\n );\n return metadata;\n }\n try {\n return assign(\n metadata,\n metadataCollectorFunction.call(window, assign(metadata, data))\n );\n } catch (error) {\n warnInFunction(\"metadata\", error);\n }\n };\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource, overwriteSearch) {\n return (\n (overwriteSearch || loc.search)\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n var paramsRegexList = allowParams.map(filterRegex).join(\"|\");\n var regex = ignore\n ? \"^(\" + paramsRegexList + \")=\"\n : \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \"|\" +\n paramsRegexList +\n \")=\";\n if (ignore && !allowParams.length) return falseVar;\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n // Ignore pages specified in data-ignore-pages\n var shouldIgnore = function (path) {\n for (var i in ignorePages) {\n var ignorePageRaw = ignorePages[i];\n if (!ignorePageRaw) continue;\n\n // Prepend a slash when it's missing\n var ignorePage =\n ignorePageRaw[0] == slash ? ignorePageRaw : slash + ignorePageRaw;\n\n if (\n ignorePage === path ||\n new RegExp(\n \"^\" + filterRegex(ignorePage).replace(/\\\\\\*/gi, \"(.*)\") + \"$\",\n \"i\"\n ).test(path)\n )\n return trueVar;\n }\n return falseVar;\n };\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n if (callback) {\n image.onerror = callback;\n image.onload = callback;\n }\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n /////////////////////\n // ERROR FUNCTIONS\n //\n\n // Send errors\n // no var because it's scoped outside of the try/catch\n sendError = function (errorOrMessage) {\n errorOrMessage = errorOrMessage.stack\n ? errorOrMessage + \" \" + errorOrMessage.stack\n : errorOrMessage;\n warn(errorOrMessage);\n sendData(\n assign(basePayload, {\n type: errorText,\n error: errorOrMessage,\n path: loc.pathname,\n }),\n undefinedVar,\n trueVar\n );\n };\n\n // We listen for the error events and only send errors that are\n // from our script (checked by filename) to our server.\n addEventListenerFunc(\n errorText,\n function (event) {\n if (event.filename && event.filename.indexOf(baseUrl) > -1) {\n sendError(event.message);\n }\n },\n falseVar\n );\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n var start = now();\n\n var scrolled = 0;\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n // Should we record Do Not Track visits?\n var collectDnt = isBoolean(overwriteOptions.collectDnt)\n ? overwriteOptions.collectDnt\n : attr(scriptElement, \"ignore-dnt\") == trueText ||\n attr(scriptElement, \"skip-dnt\") == trueText ||\n attr(scriptElement, \"collect-dnt\") == trueText;\n\n // Some customers want to collect page views manually\n var autoCollect = !(\n attr(scriptElement, \"auto-collect\") == \"false\" ||\n overwriteOptions.autoCollect === falseVar\n );\n\n // Event function name\n var eventFunctionName =\n overwriteOptions.saGlobal ||\n attr(scriptElement, \"sa-global\") ||\n namespace + \"_\" + eventText;\n\n // Customers can ignore certain pages\n var ignorePages = convertCommaSeparatedToArray(\n overwriteOptions.ignorePages || attr(scriptElement, \"ignore-pages\")\n );\n\n // Customers can allow params\n var allowParams = convertCommaSeparatedToArray(\n overwriteOptions.allowParams || attr(scriptElement, \"allow-params\")\n );\n\n // Customers can allow params\n var nonUniqueHostnames = convertCommaSeparatedToArray(\n overwriteOptions.nonUniqueHostnames ||\n attr(scriptElement, \"non-unique-hostnames\")\n );\n\n // Customers can overwrite certain values\n var pathOverwriter =\n overwriteOptions.pathOverwriter || attr(scriptElement, \"path-overwriter\");\n\n // Customers can add metadata to events and pageviews via a function\n var metadataCollector =\n overwriteOptions.metadataCollector ||\n attr(scriptElement, \"metadata-collector\");\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var phantom = window.phantom;\n var bot =\n nav.webdriver ||\n window.__nightmare ||\n window.callPhantom ||\n window._phantom ||\n (phantom && !phantom.solana) ||\n window.__polypane ||\n window._bot ||\n isBotAgent ||\n Math.random() == Math.random();\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = falseVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n // Warn when no document.doctype is defined (this breaks some documentElement dimensions)\n if (!doc.doctype) warn(\"Add DOCTYPE html for accurate dimensions\");\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (!collectDnt && doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n // Customers can overwrite their referrer, here we check for that\n var overwrittenReferrer =\n overwriteOptions.referrer || attr(scriptElement, \"referrer\");\n\n return (\n (overwrittenReferrer || doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n // t = timeonpage\n if (collectMetricByString(\"t\")) {\n append.duration = Math.round((now() - start - msHidden) / thousand);\n }\n msHidden = 0;\n start = now();\n\n // scro = scrolled\n if (collectMetricByString(\"scro\")) {\n append.scrolled = Math.max(0, scrolled, position());\n }\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n try {\n nav.sendBeacon.bind(nav)(fullApiUrl + \"/append\", stringify(append));\n } catch (e) {\n // Fallback for browsers throwing \"Illegal invocation\" when the URL is invalid\n sendData(append, undefinedVar, trueVar);\n }\n }\n };\n\n var hiddenStart;\n addEventListenerFunc(\n \"visibilitychange\",\n function () {\n if (doc.hidden) {\n if (!(\"on\" + pagehide in window)) sendOnLeave();\n hiddenStart = now();\n } else msHidden += now() - hiddenStart;\n },\n falseVar\n );\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n var body = doc.body || {};\n var position = function () {\n try {\n var documentClientHeight = documentElement[clientHeight] || 0;\n var height = Math.max(\n body[scrollHeight] || 0,\n body[offsetHeight] || 0,\n documentElement[clientHeight] || 0,\n documentElement[scrollHeight] || 0,\n documentElement[offsetHeight] || 0\n );\n return Math.min(\n 100,\n Math.round(\n (100 * ((documentElement.scrollTop || 0) + documentClientHeight)) /\n height /\n 5\n ) * 5\n );\n } catch (error) {\n warn(error);\n return 0;\n }\n };\n\n addEventListenerFunc(\"load\", function () {\n scrolled = position();\n addEventListenerFunc(\n scroll,\n function () {\n if (scrolled < position()) scrolled = position();\n },\n falseVar\n );\n });\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n var pathOverwriterFunction = window[pathOverwriter];\n if (isFunction(pathOverwriterFunction)) {\n try {\n path = pathOverwriterFunction.call(window, { path: path }) || path;\n } catch (error) {\n warnInFunction(\"path\", error);\n }\n }\n\n // Ignore pages specified in data-ignore-pages\n if (shouldIgnore(path)) {\n warn(notSendingWhen + \"ignoring \" + path);\n return;\n }\n\n // Add hash to path when script is put in to hash mode\n if (mode == \"hash\" && loc.hash) path += loc.hash.split(\"?\")[0];\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n query,\n metadata,\n callback\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData(\n {\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: query || getQueryParams(deleteSourceInfo),\n\n metadata: stringify(metadata),\n },\n callback\n );\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (\n isPushState,\n pathOverwrite,\n metadata,\n callbackRaw\n ) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var querySearch;\n if (isString(pathOverwrite) && pathOverwrite.indexOf(\"?\") > -1) {\n // keep query from manual path\n var parts = pathOverwrite.split(\"?\");\n pathOverwrite = parts.shift();\n querySearch = \"?\" + parts.join(\"?\");\n }\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n // v = viewportsizes\n if (collectMetricByString(\"v\")) {\n page.viewport_width =\n Math.max(documentElement[clientWidth] || 0, window.innerWidth || 0) ||\n null;\n page.viewport_height =\n Math.max(\n documentElement[clientHeight] || 0,\n window.innerHeight || 0\n ) || null;\n }\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n // sc = screensizes\n if (screen && collectMetricByString(\"sc\")) {\n page.screen_width = screen.width;\n page.screen_height = screen.height;\n }\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n var currentReferrerHostname = referrer\n ? referrer.split(slash)[0]\n : undefinedVar;\n sameSite = referrer\n ? nonUniqueHostnames.indexOf(currentReferrerHostname) > -1 ||\n currentReferrerHostname == locationHostname\n : falseVar;\n\n // We set unique variable based on pushstate or back navigation, if no match we check the referrer\n page.unique =\n /__cf_/.test(getReferrer()) || isPushState || userNavigated\n ? falseVar\n : !sameSite;\n\n metadata = appendMetadata(metadata, {\n type: pageviewText,\n path: page.path,\n });\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n var delSrc =\n isPushState || userNavigated || !collectMetricByString(\"r\");\n sendPageView(\n isPushState,\n delSrc, // r = referrers\n sameSite,\n querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar,\n metadata,\n callback\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n /////////////////////\n // AUTOMATED PAGE VIEW COLLECTION\n //\n\n var his = window.history;\n var hisPushState = his ? his.pushState : undefinedVar;\n var dis = window.dispatchEvent;\n var pushStateText = \"pushState\";\n\n // Overwrite history pushState function to\n // allow listening on the pushState event\n if (autoCollect && hisPushState && Event && dis) {\n var stateListener = function (type) {\n var orig = his[type];\n return function () {\n var arg = arguments;\n var rv = orig.apply(this, arg);\n var event;\n if (isFunction(Event)) {\n event = new Event(type);\n } else {\n // Fix for IE\n // https://github.com/simpleanalytics/scripts/issues/8\n event = doc.createEvent(\"Event\");\n event.initEvent(type, trueVar, trueVar);\n }\n event.arguments = arg;\n dis(event);\n return rv;\n };\n };\n\n his.pushState = stateListener(pushStateText);\n\n addEventListenerFunc(\n pushStateText,\n function () {\n pageview(1);\n },\n falseVar\n );\n\n addEventListenerFunc(\n \"popstate\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n // When in hash mode, we record a pageview based on the onhashchange function\n if (autoCollect && mode == \"hash\" && \"onhashchange\" in window) {\n addEventListenerFunc(\n \"hashchange\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n if (autoCollect) pageview();\n\n window.sa_pageview = function (path, metadata, callback) {\n pageview(0, path, metadata, callback);\n };\n\n\n /////////////////////\n // EVENTS\n //\n\n var validTypes = [\"string\", \"number\"];\n\n var sendEvent = function (event, metadata, callbackRaw) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n\n var eventIsFunction = isFunction(event);\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var eventType = typeof event;\n\n if (validTypes.indexOf(eventType) < 0 && !eventIsFunction) {\n warnInFunction(eventFunctionName, eventText + \" can't be \" + eventType);\n return callback();\n }\n\n try {\n if (eventIsFunction) {\n var eventOutput = event();\n if (validTypes.indexOf(typeof eventOutput) < 0) {\n warnInFunction(\n eventFunctionName,\n event + \" returns no string: \" + eventOutput\n );\n return callback();\n }\n event = eventOutput;\n }\n } catch (error) {\n warnInFunction(eventFunctionName, error);\n return callback();\n }\n\n event = (\"\" + event).replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_|_$)/g, \"\");\n\n var eventParams = { type: eventText, event: event };\n var firstPage = !userNavigated && pages < 2;\n\n metadata = appendMetadata(metadata, eventParams);\n\n if (event) {\n sendData(\n assign(eventParams, {\n id: uuid(),\n query: getQueryParams(!firstPage),\n referrer:\n (firstPage || sameSite) && collectMetricByString(\"r\")\n ? previousReferrer\n : null,\n\n metadata: stringify(metadata),\n }),\n callback\n );\n }\n };\n\n var defaultEventFunc = function (event, metadata, callback) {\n sendEvent(event, metadata, callback);\n };\n\n // Set default function if user didn't define a function\n if (!window[eventFunctionName])\n window[eventFunctionName] = defaultEventFunc;\n\n var eventFunc = window[eventFunctionName];\n\n // Read queue of the user defined function\n var queue = eventFunc && eventFunc.q ? eventFunc.q : [];\n\n // Overwrite user defined function\n window[eventFunctionName] = defaultEventFunc;\n\n // Post events from the queue of the user defined function\n for (var event in queue) {\n if (hasProp(queue, event)) {\n Array.isArray(queue[event])\n ? sendEvent.apply(null, queue[event])\n : sendEvent(queue[event]);\n }\n }\n } catch (e) {\n sendError(e);\n }\n})(\n window,\n {},\n \"\",\n \"\",\n \"custom_proxy_12\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","sendError","warn","undefinedVar","undefined","trueVar","falseVar","trueText","https","pageviewText","eventText","errorText","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","notSendingWhen","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","documentElement","language","Height","scroll","uaData","userAgentData","scrollHeight","offsetHeight","clientHeight","pagehide","platformText","platformVersionText","docsUrl","pages","isBotAgent","test","screen","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","warnInFunction","name","error","hasProp","obj","prop","Object","hasOwnProperty","isString","string","filterRegex","item","replace","attr","attribute","getAttribute","convertCommaSeparatedToArray","csv","Array","isArray","length","split","isObject","object","constructor","assign","to","arg","index","nextSource","nextKey","settings","sa_settings","logSettings","keys","ignoreMetrics","collectMetricByString","metricAbbreviation","filter","RegExp","now","Date","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","c","getRandomValues","Uint8Array","toString","r","Math","random","isFunction","func","namespaceText","namespace","appendMetadata","metadata","data","metadataObject","metadataCollectorFunction","metadataCollector","strictUtm","getQueryParams","ignoreSource","overwriteSearch","search","keyValue","ignore","paramsRegexList","allowParams","map","join","regex","loadedVariable","sa_event_loaded","sendData","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","image","Image","onerror","onload","src","key","overwrittenHostname","hostname","definedHostname","basePayload","version","errorOrMessage","stack","type","path","pathname","event","filename","indexOf","message","timezone","start","scrolled","mode","collectDnt","value","autoCollect","eventFunctionName","saGlobal","ignorePages","nonUniqueHostnames","pathOverwriter","Intl","DateTimeFormat","resolvedOptions","timeZone","phantom","bot","webdriver","__nightmare","callPhantom","_phantom","solana","__polypane","_bot","collectDataOnLeave","ua","protocol","page_id","session_id","sri","mobile","brands","doctype","hostname_original","lastSendPath","hiddenStart","getReferrer","referrer","msHidden","sendOnLeave","id","push","append","original_id","duration","round","max","position","sendBeacon","bind","e","hidden","body","documentClientHeight","height","min","scrollTop","previousReferrer","sameSite","userNavigated","getPath","overwrite","pathOverwriterFunction","i","ignorePageRaw","ignorePage","shouldIgnore","hash","pageview","isPushState","pathOverwrite","callbackRaw","querySearch","parts","shift","viewport_width","innerWidth","viewport_height","innerHeight","screen_width","width","screen_height","performaceEntryType","perf","performance","navigationText","getEntriesByType","currentReferrerHostname","unique","triggerSendPageView","delSrc","deleteSourceInfo","query","currentPage","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","his","history","hisPushState","pushState","dis","dispatchEvent","pushStateText","Event","orig","rv","this","createEvent","initEvent","sa_pageview","validTypes","sendEvent","eventIsFunction","eventType","eventOutput","eventParams","firstPage","defaultEventFunc","eventFunc","queue","q"],"mappings":"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"} \ No newline at end of file diff --git a/dist/latest/hello.js b/dist/latest/hello.js index 289727ae..8bfecfe4 100644 --- a/dist/latest/hello.js +++ b/dist/latest/hello.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy friendly analytics (docs.simpleanalytics.com/script; 2023-05-03; f60b) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; 69f5) */ -!function(l,t,e,n,p){try{var h=undefined,f=!0,d=!1,r="true",a="https:",m="pageview",u="event",i="error",o=l.console,c="doNotTrack",g=l.navigator,s=l.location,v=s.host,y=l.document,_=g.userAgent,w="Not sending request ",b=w+"when ",E=d,O=encodeURIComponent,x=decodeURIComponent,S=JSON.stringify,M=l.addEventListener,k="https://queue."+e,q=y.documentElement||{},A="language",$="Height",j="scroll",D=g.userAgentData,C=j+$,R="offset"+$,H="client"+$,P="pagehide",T="platform",U="platformVersion",I="https://docs.simpleanalytics.com",V=0,B=/(bot|spider|crawl)/i.test(_)&&!/(cubot)/i.test(_),N=l.screen,z=y.currentScript||y.querySelector('script[src*="'+e+'"]');p=function(){var t=[].slice.call(arguments);return t.unshift("Simple Analytics:"),Function.prototype.apply.call(o.warn,o,t)};var F=function(t,e){p("Error in your "+t+" function:",e)},W=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},G=function(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},J=function(t,e){return t&&t.getAttribute("data-"+e)},L=function(t){return Array.isArray(t)?t:"string"==typeof t&&t.length?t.split(/, ?/):[]},Y=function(t){return t&&t.constructor===Object},Z=function(){for(var t={},e=arguments,n=0;n>t/4).toString(16)})}catch(r){return t.replace(n,function(t){var e=16*Math.random()|0;return(t<2?e:3&e|8).toString(16)})}},rt=function(t){return"function"==typeof t},at="namespace",it=t[at]||J(z,at)||"sa",ot=l[it+"_metadata"],ct=function(t,e){Y(ot)&&(t=Z(t,ot));var n=l[Mt];if(!rt(n))return t;try{return Z(t,n.call(l,Z(t,e)))}catch(r){F("metadata",r)}},st=t.strictUtm||J(z,"strict-utm")==r,ut=function(a){return s.search.slice(1).split("&").filter(function(t){var e=a||!tt("ut"),n=Ot.map(G).join("|"),r=e?"^("+n+")=":"^((utm_)"+(st?"":"?")+"(source|medium|content|term|campaign)"+(st?"":"|ref")+"|"+n+")=";return e&&!Ot.length?d:new RegExp(r).test(t)}).join("&")||h},lt=it+"_loaded";if(l[lt]==f)return p(w+"twice");l.sa_event_loaded=f,l[lt]=f;var pt=function(e,t,n){e=n?e:Z(At,Dt,e),g.brave&&!n&&(e.brave=f),g._duckduckgoloader_&&!n&&(e.duck=f);var r=new Image;t&&(r.onerror=t,r.onload=t),r.src=k+"/simple.gif?"+Object.keys(e).filter(function(t){return e[t]!=h}).map(function(t){return O(t)+"="+O(e[t])}).join("&")+"&time="+Date.now()},ht=t.hostname||J(z,"hostname"),ft=ht||v,dt={version:"cdn_hello_11",hostname:ft};n=function(t){t=t.stack?t+" "+t.stack:t,p(t),pt(Z(dt,{type:i,error:t,path:s.pathname}),h,f)},M(i,function(t){t.filename&&-1>t/4).toString(16)})}catch(r){return t.replace(n,function(t){var e=16*Math.random()|0;return(t<2?e:3&e|8).toString(16)})}},at=function(t){return"function"==typeof t},it="namespace",ot=t[it]||L(z,it)||"sa",ct=function(t,e){var n=d[ot+"_metadata"];Z(n)&&(t=K(t,n));var r=d[Mt];if(!at(r))return Mt&&m(Mt+" not found, set window."+Mt),t;try{return K(t,r.call(d,K(t,e)))}catch(a){F("metadata",a)}},st=t.strictUtm||L(z,"strict-utm")==r,ut=function(a,t){return(t||s.search).slice(1).split("&").filter(function(t){var e=a||!et("ut"),n=Et.map(J).join("|"),r=e?"^("+n+")=":"^((utm_)"+(st?"":"?")+"(source|medium|content|term|campaign)"+(st?"":"|ref")+"|"+n+")=";return e&&!Et.length?y:new RegExp(r).test(t)}).join("&")||v},lt=ot+"_loaded";if(d[lt]==g)return m(f+"twice");d.sa_event_loaded=g,d[lt]=g;var pt=function(e,t,n){e=n?e:K($t,Ct,e),w.brave&&!n&&(e.brave=g),w._duckduckgoloader_&&!n&&(e.duck=g);var r=new Image;t&&(r.onerror=t,r.onload=t),r.src=k+"/simple.gif?"+Object.keys(e).filter(function(t){return e[t]!=v}).map(function(t){return E(t)+"="+E(e[t])}).join("&")+"&time="+Date.now()},ft=t.hostname||L(z,"hostname"),ht=ft||b,dt={version:"cdn_hello_12",hostname:ht};n=function(t){t=t.stack?t+" "+t.stack:t,m(t),pt(K(dt,{type:i,error:t,path:s.pathname}),v,g)},M(i,function(t){t.filename&&-1> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n var metadataObject = window[namespace + \"_metadata\"];\n var appendMetadata = function (metadata, data) {\n if (isObject(metadataObject)) metadata = assign(metadata, metadataObject);\n var metadataCollectorFunction = window[metadataCollector];\n if (!isFunction(metadataCollectorFunction)) return metadata;\n try {\n return assign(\n metadata,\n metadataCollectorFunction.call(window, assign(metadata, data))\n );\n } catch (error) {\n warnInFunction(\"metadata\", error);\n }\n };\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource) {\n return (\n loc.search\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n var paramsRegexList = allowParams.map(filterRegex).join(\"|\");\n var regex = ignore\n ? \"^(\" + paramsRegexList + \")=\"\n : \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \"|\" +\n paramsRegexList +\n \")=\";\n if (ignore && !allowParams.length) return falseVar;\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n // Ignore pages specified in data-ignore-pages\n var shouldIgnore = function (path) {\n for (var i in ignorePages) {\n var ignorePageRaw = ignorePages[i];\n if (!ignorePageRaw) continue;\n\n // Prepend a slash when it's missing\n var ignorePage =\n ignorePageRaw[0] == slash ? ignorePageRaw : slash + ignorePageRaw;\n\n if (\n ignorePage === path ||\n new RegExp(\n \"^\" + filterRegex(ignorePage).replace(/\\\\\\*/gi, \"(.*)\") + \"$\",\n \"i\"\n ).test(path)\n )\n return trueVar;\n }\n return falseVar;\n };\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n if (callback) {\n image.onerror = callback;\n image.onload = callback;\n }\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n /////////////////////\n // ERROR FUNCTIONS\n //\n\n // Send errors\n // no var because it's scoped outside of the try/catch\n sendError = function (errorOrMessage) {\n errorOrMessage = errorOrMessage.stack\n ? errorOrMessage + \" \" + errorOrMessage.stack\n : errorOrMessage;\n warn(errorOrMessage);\n sendData(\n assign(basePayload, {\n type: errorText,\n error: errorOrMessage,\n path: loc.pathname,\n }),\n undefinedVar,\n trueVar\n );\n };\n\n // We listen for the error events and only send errors that are\n // from our script (checked by filename) to our server.\n addEventListenerFunc(\n errorText,\n function (event) {\n if (event.filename && event.filename.indexOf(baseUrl) > -1) {\n sendError(event.message);\n }\n },\n falseVar\n );\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n var start = now();\n\n var scrolled = 0;\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n // Should we record Do Not Track visits?\n var collectDnt = isBoolean(overwriteOptions.collectDnt)\n ? overwriteOptions.collectDnt\n : attr(scriptElement, \"ignore-dnt\") == trueText ||\n attr(scriptElement, \"skip-dnt\") == trueText ||\n attr(scriptElement, \"collect-dnt\") == trueText;\n\n // Some customers want to collect page views manually\n var autoCollect = !(\n attr(scriptElement, \"auto-collect\") == \"false\" ||\n overwriteOptions.autoCollect === falseVar\n );\n\n // Event function name\n var eventFunctionName =\n overwriteOptions.saGlobal ||\n attr(scriptElement, \"sa-global\") ||\n namespace + \"_\" + eventText;\n\n // Customers can ignore certain pages\n var ignorePages = convertCommaSeparatedToArray(\n overwriteOptions.ignorePages || attr(scriptElement, \"ignore-pages\")\n );\n\n // Customers can allow params\n var allowParams = convertCommaSeparatedToArray(\n overwriteOptions.allowParams || attr(scriptElement, \"allow-params\")\n );\n\n // Customers can allow params\n var nonUniqueHostnames = convertCommaSeparatedToArray(\n overwriteOptions.nonUniqueHostnames ||\n attr(scriptElement, \"non-unique-hostnames\")\n );\n\n // Customers can overwrite certain values\n var pathOverwriter =\n overwriteOptions.pathOverwriter || attr(scriptElement, \"path-overwriter\");\n\n // Customers can add metadata to events and pageviews via a function\n var metadataCollector =\n overwriteOptions.metadataCollector ||\n attr(scriptElement, \"metadata-collector\");\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var bot =\n nav.webdriver ||\n window.__nightmare ||\n window.callPhantom ||\n window._phantom ||\n window.phantom ||\n window.__polypane ||\n window._bot ||\n isBotAgent ||\n Math.random() == Math.random();\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = falseVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n // Warn when no document.doctype is defined (this breaks some documentElement dimensions)\n if (!doc.doctype) warn(\"Add DOCTYPE html for accurate dimensions\");\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (!collectDnt && doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n return (\n (doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n // t = timeonpage\n if (collectMetricByString(\"t\")) {\n append.duration = Math.round((now() - start - msHidden) / thousand);\n }\n msHidden = 0;\n start = now();\n\n // scro = scrolled\n if (collectMetricByString(\"scro\")) {\n append.scrolled = Math.max(0, scrolled, position());\n }\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n nav.sendBeacon(fullApiUrl + \"/append\", stringify(append));\n }\n };\n\n var hiddenStart;\n addEventListenerFunc(\n \"visibilitychange\",\n function () {\n if (doc.hidden) {\n if (!(\"on\" + pagehide in window)) sendOnLeave();\n hiddenStart = now();\n } else msHidden += now() - hiddenStart;\n },\n falseVar\n );\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n var body = doc.body || {};\n var position = function () {\n try {\n var documentClientHeight = documentElement[clientHeight] || 0;\n var height = Math.max(\n body[scrollHeight] || 0,\n body[offsetHeight] || 0,\n documentElement[clientHeight] || 0,\n documentElement[scrollHeight] || 0,\n documentElement[offsetHeight] || 0\n );\n return Math.min(\n 100,\n Math.round(\n (100 * ((documentElement.scrollTop || 0) + documentClientHeight)) /\n height /\n 5\n ) * 5\n );\n } catch (error) {\n warn(error);\n return 0;\n }\n };\n\n addEventListenerFunc(\"load\", function () {\n scrolled = position();\n addEventListenerFunc(\n scroll,\n function () {\n if (scrolled < position()) scrolled = position();\n },\n falseVar\n );\n });\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n var pathOverwriterFunction = window[pathOverwriter];\n if (isFunction(pathOverwriterFunction)) {\n try {\n path = pathOverwriterFunction.call(window, { path: path }) || path;\n } catch (error) {\n warnInFunction(\"path\", error);\n }\n }\n\n // Ignore pages specified in data-ignore-pages\n if (shouldIgnore(path)) {\n warn(notSendingWhen + \"ignoring \" + path);\n return;\n }\n\n // Add hash to path when script is put in to hash mode\n if (mode == \"hash\" && loc.hash) path += loc.hash.split(\"?\")[0];\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n metadata\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData({\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: getQueryParams(deleteSourceInfo),\n\n metadata: stringify(metadata),\n });\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (isPushState, pathOverwrite, metadata) {\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n // v = viewportsizes\n if (collectMetricByString(\"v\")) {\n page.viewport_width =\n Math.max(documentElement[clientWidth] || 0, window.innerWidth || 0) ||\n null;\n page.viewport_height =\n Math.max(\n documentElement[clientHeight] || 0,\n window.innerHeight || 0\n ) || null;\n }\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n // sc = screensizes\n if (screen && collectMetricByString(\"sc\")) {\n page.screen_width = screen.width;\n page.screen_height = screen.height;\n }\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n var currentReferrerHostname = referrer\n ? referrer.split(slash)[0]\n : undefinedVar;\n sameSite = referrer\n ? nonUniqueHostnames.indexOf(currentReferrerHostname) > -1 ||\n currentReferrerHostname == locationHostname\n : falseVar;\n\n // We set unique variable based on pushstate or back navigation, if no match we check the referrer\n page.unique = isPushState || userNavigated ? falseVar : !sameSite;\n\n metadata = appendMetadata(metadata, {\n type: pageviewText,\n path: page.path,\n });\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n sendPageView(\n isPushState,\n isPushState || userNavigated || !collectMetricByString(\"r\"), // r = referrers\n sameSite,\n metadata\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n /////////////////////\n // AUTOMATED PAGE VIEW COLLECTION\n //\n\n var his = window.history;\n var hisPushState = his ? his.pushState : undefinedVar;\n var dis = window.dispatchEvent;\n var pushStateText = \"pushState\";\n\n // Overwrite history pushState function to\n // allow listening on the pushState event\n if (autoCollect && hisPushState && Event && dis) {\n var stateListener = function (type) {\n var orig = his[type];\n return function () {\n var arg = arguments;\n var rv = orig.apply(this, arg);\n var event;\n if (isFunction(Event)) {\n event = new Event(type);\n } else {\n // Fix for IE\n // https://github.com/simpleanalytics/scripts/issues/8\n event = doc.createEvent(\"Event\");\n event.initEvent(type, trueVar, trueVar);\n }\n event.arguments = arg;\n dis(event);\n return rv;\n };\n };\n\n his.pushState = stateListener(pushStateText);\n\n addEventListenerFunc(\n pushStateText,\n function () {\n pageview(1);\n },\n falseVar\n );\n\n addEventListenerFunc(\n \"popstate\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n // When in hash mode, we record a pageview based on the onhashchange function\n if (autoCollect && mode == \"hash\" && \"onhashchange\" in window) {\n addEventListenerFunc(\n \"hashchange\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n if (autoCollect) pageview();\n else {\n window.sa_pageview = function (path, metadata) {\n pageview(0, path, metadata);\n };\n }\n\n /////////////////////\n // EVENTS\n //\n\n var validTypes = [\"string\", \"number\"];\n\n var sendEvent = function (event, metadata, callbackRaw) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n\n var eventIsFunction = isFunction(event);\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var eventType = typeof event;\n\n if (validTypes.indexOf(eventType) < 0 && !eventIsFunction) {\n warnInFunction(eventFunctionName, eventText + \" can't be \" + eventType);\n return callback();\n }\n\n try {\n if (eventIsFunction) {\n var eventOutput = event();\n if (validTypes.indexOf(typeof eventOutput) < 0) {\n warnInFunction(\n eventFunctionName,\n event + \" returns no string: \" + eventOutput\n );\n return callback();\n }\n event = eventOutput;\n }\n } catch (error) {\n warnInFunction(eventFunctionName, error);\n return callback();\n }\n\n event = (\"\" + event).replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_|_$)/g, \"\");\n\n var eventParams = { type: eventText, event: event };\n var firstPage = !userNavigated && pages < 2;\n\n metadata = appendMetadata(metadata, eventParams);\n\n if (event) {\n sendData(\n assign(eventParams, {\n id: uuid(),\n query: getQueryParams(!firstPage),\n referrer:\n (firstPage || sameSite) && collectMetricByString(\"r\")\n ? previousReferrer\n : null,\n\n metadata: stringify(metadata),\n }),\n callback\n );\n }\n };\n\n var defaultEventFunc = function (event, metadata, callback) {\n sendEvent(event, metadata, callback);\n };\n\n // Set default function if user didn't define a function\n if (!window[eventFunctionName])\n window[eventFunctionName] = defaultEventFunc;\n\n var eventFunc = window[eventFunctionName];\n\n // Read queue of the user defined function\n var queue = eventFunc && eventFunc.q ? eventFunc.q : [];\n\n // Overwrite user defined function\n window[eventFunctionName] = defaultEventFunc;\n\n // Post events from the queue of the user defined function\n for (var event in queue) {\n if (hasProp(queue, event)) {\n Array.isArray(queue[event])\n ? sendEvent.apply(null, queue[event])\n : sendEvent(queue[event]);\n }\n }\n } catch (e) {\n sendError(e);\n }\n})(\n window,\n {},\n \"simpleanalyticscdn.com\",\n \"queue.\",\n \"cdn_hello_11\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","sendError","warn","undefinedVar","undefined","trueVar","falseVar","trueText","https","pageviewText","eventText","errorText","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","notSendingWhen","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","protocol","documentElement","language","Height","scroll","uaData","userAgentData","scrollHeight","offsetHeight","clientHeight","pagehide","platformText","platformVersionText","docsUrl","pages","isBotAgent","test","screen","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","warnInFunction","name","error","hasProp","obj","prop","Object","hasOwnProperty","filterRegex","item","replace","attr","attribute","getAttribute","convertCommaSeparatedToArray","csv","Array","isArray","length","split","isObject","object","constructor","assign","to","arg","index","nextSource","nextKey","settings","sa_settings","logSettings","keys","ignoreMetrics","collectMetricByString","metricAbbreviation","filter","RegExp","now","Date","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","c","getRandomValues","Uint8Array","toString","r","Math","random","isFunction","func","namespaceText","namespace","metadataObject","appendMetadata","metadata","data","metadataCollectorFunction","metadataCollector","strictUtm","getQueryParams","ignoreSource","search","keyValue","ignore","paramsRegexList","allowParams","map","join","regex","loadedVariable","sa_event_loaded","sendData","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","image","Image","onerror","onload","src","key","overwrittenHostname","hostname","definedHostname","basePayload","version","errorOrMessage","stack","type","path","pathname","event","filename","indexOf","message","timezone","start","scrolled","mode","collectDnt","value","autoCollect","eventFunctionName","saGlobal","ignorePages","nonUniqueHostnames","pathOverwriter","Intl","DateTimeFormat","resolvedOptions","timeZone","bot","webdriver","__nightmare","callPhantom","_phantom","phantom","__polypane","_bot","collectDataOnLeave","ua","page_id","session_id","sri","mobile","brands","doctype","hostname_original","lastSendPath","hiddenStart","referrer","msHidden","sendOnLeave","id","push","append","original_id","duration","round","max","position","sendBeacon","hidden","body","documentClientHeight","height","min","scrollTop","previousReferrer","sameSite","userNavigated","getPath","overwrite","pathOverwriterFunction","i","ignorePageRaw","ignorePage","shouldIgnore","hash","pageview","isPushState","pathOverwrite","viewport_width","innerWidth","viewport_height","innerHeight","screen_width","width","screen_height","performaceEntryType","perf","performance","navigationText","getEntriesByType","currentReferrerHostname","unique","triggerSendPageView","deleteSourceInfo","currentPage","query","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","e","his","history","hisPushState","pushState","dis","dispatchEvent","pushStateText","Event","orig","rv","this","createEvent","initEvent","sa_pageview","validTypes","sendEvent","callbackRaw","eventIsFunction","eventType","eventOutput","eventParams","firstPage","defaultEventFunc","eventFunc","queue","q"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"hello.source.js","sources":["hello.source.js"],"sourcesContent":["/* eslint-env browser */\n\n(function (\n window,\n overwriteOptions,\n baseUrl,\n apiUrlPrefix,\n version,\n defaultNamespace,\n sendError,\n warn\n) {\n try {\n /////////////////////\n // PREDEFINED VARIABLES FOR BETTER MINIFICATION\n //\n\n // This seems like a lot of repetition, but it makes our script available for\n // multple destination which prevents us to need multiple scripts. The minified\n // version stays small.\n var undefinedVar = undefined;\n var trueVar = true;\n var falseVar = false;\n var trueText = \"true\";\n var https = \"https:\";\n var pageviewText = \"pageview\";\n var eventText = \"event\";\n var errorText = \"error\";\n var slash = \"/\";\n var protocol = https + \"//\";\n var con = window.console;\n var doNotTrack = \"doNotTrack\";\n var nav = window.navigator;\n var loc = window.location;\n var locationHostname = loc.host;\n var doc = window.document;\n var userAgent = nav.userAgent;\n var notSending = \"Not sending request \";\n var notSendingWhen = notSending + \"when \";\n var fetchedHighEntropyValues = falseVar;\n var encodeURIComponentFunc = encodeURIComponent;\n var decodeURIComponentFunc = decodeURIComponent;\n var stringify = JSON.stringify;\n var thousand = 1000;\n var addEventListenerFunc = window.addEventListener;\n var fullApiUrl = protocol + apiUrlPrefix + baseUrl;\n var documentElement = doc.documentElement || {};\n var language = \"language\";\n var Height = \"Height\";\n var Width = \"Width\";\n var scroll = \"scroll\";\n var uaData = nav.userAgentData;\n var scrollHeight = scroll + Height;\n var offsetHeight = \"offset\" + Height;\n var clientHeight = \"client\" + Height;\n var clientWidth = \"client\" + Width;\n var pagehide = \"pagehide\";\n var platformText = \"platform\";\n var platformVersionText = \"platformVersion\";\n var docsUrl = \"https://docs.simpleanalytics.com\";\n var pages = 0;\n var isBotAgent =\n /(bot|spider|crawl)/i.test(userAgent) && !/(cubot)/i.test(userAgent);\n var screen = window.screen;\n\n\n // Find the script element where options can be set on\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"' + baseUrl + '\"]');\n\n /////////////////////\n // HELPER FUNCTIONS\n //\n\n // A simple log function so the user knows why a request is not being send\n warn = function () {\n // 1. Convert args to a normal array\n var args = [].slice.call(arguments);\n\n // 2. Prepend log prefix\n args.unshift(\"Simple Analytics:\");\n\n // 3. Pass along arguments to console.warn\n // Function.prototype.apply.call is needed for Internet Explorer\n return Function.prototype.apply.call(con.warn, con, args);\n };\n\n var warnInFunction = function (name, error) {\n warn(\"Error in your \" + name + \" function:\", error);\n };\n\n var hasProp = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n\n var isString = function (string) {\n return typeof string == \"string\";\n };\n\n var filterRegex = function (item) {\n return item.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n var attr = function (scriptElement, attribute) {\n return scriptElement && scriptElement.getAttribute(\"data-\" + attribute);\n };\n\n var convertCommaSeparatedToArray = function (csv) {\n return Array.isArray(csv)\n ? csv\n : isString(csv) && csv.length\n ? csv.split(/, ?/)\n : [];\n };\n\n var isObject = function (object) {\n return object && object.constructor === Object;\n };\n\n var assign = function () {\n var to = {};\n var arg = arguments;\n for (var index = 0; index < arg.length; index++) {\n var nextSource = arg[index];\n if (isObject(nextSource)) {\n for (var nextKey in nextSource) {\n if (hasProp(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n\n var settings = window.sa_settings;\n var logSettings = settings || Object.keys(overwriteOptions).length;\n\n // Merge overwriteOptions with sa_settings\n overwriteOptions = assign(overwriteOptions, settings);\n\n if (logSettings) warn(\"Settings\", overwriteOptions);\n\n // Customers can skip data points\n var ignoreMetrics = convertCommaSeparatedToArray(\n overwriteOptions.ignoreMetrics || attr(scriptElement, \"ignore-metrics\")\n );\n\n var collectMetricByString = function (metricAbbreviation) {\n // Can't use Array.find() here because we need to support IE9\n return (\n ignoreMetrics.filter(function (item) {\n return new RegExp(\"^\" + metricAbbreviation).test(item);\n }).length === 0\n );\n };\n\n var now = Date.now;\n\n var uuid = function () {\n var cryptoObject = window.crypto || window.msCrypto;\n var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;\n var uuidRegex = /[018]/g;\n\n try {\n return emptyUUID.replace(uuidRegex, function (c) {\n return (\n c ^\n (cryptoObject.getRandomValues(new Uint8Array(1))[0] &\n (15 >> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n var appendMetadata = function (metadata, data) {\n var metadataObject = window[namespace + \"_metadata\"];\n if (isObject(metadataObject)) metadata = assign(metadata, metadataObject);\n var metadataCollectorFunction = window[metadataCollector];\n if (!isFunction(metadataCollectorFunction)) {\n if (metadataCollector)\n warn(\n metadataCollector + \" not found, set window.\" + metadataCollector\n );\n return metadata;\n }\n try {\n return assign(\n metadata,\n metadataCollectorFunction.call(window, assign(metadata, data))\n );\n } catch (error) {\n warnInFunction(\"metadata\", error);\n }\n };\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource, overwriteSearch) {\n return (\n (overwriteSearch || loc.search)\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n var paramsRegexList = allowParams.map(filterRegex).join(\"|\");\n var regex = ignore\n ? \"^(\" + paramsRegexList + \")=\"\n : \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \"|\" +\n paramsRegexList +\n \")=\";\n if (ignore && !allowParams.length) return falseVar;\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n // Ignore pages specified in data-ignore-pages\n var shouldIgnore = function (path) {\n for (var i in ignorePages) {\n var ignorePageRaw = ignorePages[i];\n if (!ignorePageRaw) continue;\n\n // Prepend a slash when it's missing\n var ignorePage =\n ignorePageRaw[0] == slash ? ignorePageRaw : slash + ignorePageRaw;\n\n if (\n ignorePage === path ||\n new RegExp(\n \"^\" + filterRegex(ignorePage).replace(/\\\\\\*/gi, \"(.*)\") + \"$\",\n \"i\"\n ).test(path)\n )\n return trueVar;\n }\n return falseVar;\n };\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n if (callback) {\n image.onerror = callback;\n image.onload = callback;\n }\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n /////////////////////\n // ERROR FUNCTIONS\n //\n\n // Send errors\n // no var because it's scoped outside of the try/catch\n sendError = function (errorOrMessage) {\n errorOrMessage = errorOrMessage.stack\n ? errorOrMessage + \" \" + errorOrMessage.stack\n : errorOrMessage;\n warn(errorOrMessage);\n sendData(\n assign(basePayload, {\n type: errorText,\n error: errorOrMessage,\n path: loc.pathname,\n }),\n undefinedVar,\n trueVar\n );\n };\n\n // We listen for the error events and only send errors that are\n // from our script (checked by filename) to our server.\n addEventListenerFunc(\n errorText,\n function (event) {\n if (event.filename && event.filename.indexOf(baseUrl) > -1) {\n sendError(event.message);\n }\n },\n falseVar\n );\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n var start = now();\n\n var scrolled = 0;\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n // Should we record Do Not Track visits?\n var collectDnt = isBoolean(overwriteOptions.collectDnt)\n ? overwriteOptions.collectDnt\n : attr(scriptElement, \"ignore-dnt\") == trueText ||\n attr(scriptElement, \"skip-dnt\") == trueText ||\n attr(scriptElement, \"collect-dnt\") == trueText;\n\n // Some customers want to collect page views manually\n var autoCollect = !(\n attr(scriptElement, \"auto-collect\") == \"false\" ||\n overwriteOptions.autoCollect === falseVar\n );\n\n // Event function name\n var eventFunctionName =\n overwriteOptions.saGlobal ||\n attr(scriptElement, \"sa-global\") ||\n namespace + \"_\" + eventText;\n\n // Customers can ignore certain pages\n var ignorePages = convertCommaSeparatedToArray(\n overwriteOptions.ignorePages || attr(scriptElement, \"ignore-pages\")\n );\n\n // Customers can allow params\n var allowParams = convertCommaSeparatedToArray(\n overwriteOptions.allowParams || attr(scriptElement, \"allow-params\")\n );\n\n // Customers can allow params\n var nonUniqueHostnames = convertCommaSeparatedToArray(\n overwriteOptions.nonUniqueHostnames ||\n attr(scriptElement, \"non-unique-hostnames\")\n );\n\n // Customers can overwrite certain values\n var pathOverwriter =\n overwriteOptions.pathOverwriter || attr(scriptElement, \"path-overwriter\");\n\n // Customers can add metadata to events and pageviews via a function\n var metadataCollector =\n overwriteOptions.metadataCollector ||\n attr(scriptElement, \"metadata-collector\");\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var phantom = window.phantom;\n var bot =\n nav.webdriver ||\n window.__nightmare ||\n window.callPhantom ||\n window._phantom ||\n (phantom && !phantom.solana) ||\n window.__polypane ||\n window._bot ||\n isBotAgent ||\n Math.random() == Math.random();\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = falseVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n // Warn when no document.doctype is defined (this breaks some documentElement dimensions)\n if (!doc.doctype) warn(\"Add DOCTYPE html for accurate dimensions\");\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (!collectDnt && doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n // Customers can overwrite their referrer, here we check for that\n var overwrittenReferrer =\n overwriteOptions.referrer || attr(scriptElement, \"referrer\");\n\n return (\n (overwrittenReferrer || doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n // t = timeonpage\n if (collectMetricByString(\"t\")) {\n append.duration = Math.round((now() - start - msHidden) / thousand);\n }\n msHidden = 0;\n start = now();\n\n // scro = scrolled\n if (collectMetricByString(\"scro\")) {\n append.scrolled = Math.max(0, scrolled, position());\n }\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n try {\n nav.sendBeacon.bind(nav)(fullApiUrl + \"/append\", stringify(append));\n } catch (e) {\n // Fallback for browsers throwing \"Illegal invocation\" when the URL is invalid\n sendData(append, undefinedVar, trueVar);\n }\n }\n };\n\n var hiddenStart;\n addEventListenerFunc(\n \"visibilitychange\",\n function () {\n if (doc.hidden) {\n if (!(\"on\" + pagehide in window)) sendOnLeave();\n hiddenStart = now();\n } else msHidden += now() - hiddenStart;\n },\n falseVar\n );\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n var body = doc.body || {};\n var position = function () {\n try {\n var documentClientHeight = documentElement[clientHeight] || 0;\n var height = Math.max(\n body[scrollHeight] || 0,\n body[offsetHeight] || 0,\n documentElement[clientHeight] || 0,\n documentElement[scrollHeight] || 0,\n documentElement[offsetHeight] || 0\n );\n return Math.min(\n 100,\n Math.round(\n (100 * ((documentElement.scrollTop || 0) + documentClientHeight)) /\n height /\n 5\n ) * 5\n );\n } catch (error) {\n warn(error);\n return 0;\n }\n };\n\n addEventListenerFunc(\"load\", function () {\n scrolled = position();\n addEventListenerFunc(\n scroll,\n function () {\n if (scrolled < position()) scrolled = position();\n },\n falseVar\n );\n });\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n var pathOverwriterFunction = window[pathOverwriter];\n if (isFunction(pathOverwriterFunction)) {\n try {\n path = pathOverwriterFunction.call(window, { path: path }) || path;\n } catch (error) {\n warnInFunction(\"path\", error);\n }\n }\n\n // Ignore pages specified in data-ignore-pages\n if (shouldIgnore(path)) {\n warn(notSendingWhen + \"ignoring \" + path);\n return;\n }\n\n // Add hash to path when script is put in to hash mode\n if (mode == \"hash\" && loc.hash) path += loc.hash.split(\"?\")[0];\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n query,\n metadata,\n callback\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData(\n {\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: query || getQueryParams(deleteSourceInfo),\n\n metadata: stringify(metadata),\n },\n callback\n );\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (\n isPushState,\n pathOverwrite,\n metadata,\n callbackRaw\n ) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var querySearch;\n if (isString(pathOverwrite) && pathOverwrite.indexOf(\"?\") > -1) {\n // keep query from manual path\n var parts = pathOverwrite.split(\"?\");\n pathOverwrite = parts.shift();\n querySearch = \"?\" + parts.join(\"?\");\n }\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n // v = viewportsizes\n if (collectMetricByString(\"v\")) {\n page.viewport_width =\n Math.max(documentElement[clientWidth] || 0, window.innerWidth || 0) ||\n null;\n page.viewport_height =\n Math.max(\n documentElement[clientHeight] || 0,\n window.innerHeight || 0\n ) || null;\n }\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n // sc = screensizes\n if (screen && collectMetricByString(\"sc\")) {\n page.screen_width = screen.width;\n page.screen_height = screen.height;\n }\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n var currentReferrerHostname = referrer\n ? referrer.split(slash)[0]\n : undefinedVar;\n sameSite = referrer\n ? nonUniqueHostnames.indexOf(currentReferrerHostname) > -1 ||\n currentReferrerHostname == locationHostname\n : falseVar;\n\n // We set unique variable based on pushstate or back navigation, if no match we check the referrer\n page.unique =\n /__cf_/.test(getReferrer()) || isPushState || userNavigated\n ? falseVar\n : !sameSite;\n\n metadata = appendMetadata(metadata, {\n type: pageviewText,\n path: page.path,\n });\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n var delSrc =\n isPushState || userNavigated || !collectMetricByString(\"r\");\n sendPageView(\n isPushState,\n delSrc, // r = referrers\n sameSite,\n querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar,\n metadata,\n callback\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n /////////////////////\n // AUTOMATED PAGE VIEW COLLECTION\n //\n\n var his = window.history;\n var hisPushState = his ? his.pushState : undefinedVar;\n var dis = window.dispatchEvent;\n var pushStateText = \"pushState\";\n\n // Overwrite history pushState function to\n // allow listening on the pushState event\n if (autoCollect && hisPushState && Event && dis) {\n var stateListener = function (type) {\n var orig = his[type];\n return function () {\n var arg = arguments;\n var rv = orig.apply(this, arg);\n var event;\n if (isFunction(Event)) {\n event = new Event(type);\n } else {\n // Fix for IE\n // https://github.com/simpleanalytics/scripts/issues/8\n event = doc.createEvent(\"Event\");\n event.initEvent(type, trueVar, trueVar);\n }\n event.arguments = arg;\n dis(event);\n return rv;\n };\n };\n\n his.pushState = stateListener(pushStateText);\n\n addEventListenerFunc(\n pushStateText,\n function () {\n pageview(1);\n },\n falseVar\n );\n\n addEventListenerFunc(\n \"popstate\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n // When in hash mode, we record a pageview based on the onhashchange function\n if (autoCollect && mode == \"hash\" && \"onhashchange\" in window) {\n addEventListenerFunc(\n \"hashchange\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n if (autoCollect) pageview();\n\n window.sa_pageview = function (path, metadata, callback) {\n pageview(0, path, metadata, callback);\n };\n\n\n /////////////////////\n // EVENTS\n //\n\n var validTypes = [\"string\", \"number\"];\n\n var sendEvent = function (event, metadata, callbackRaw) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n\n var eventIsFunction = isFunction(event);\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var eventType = typeof event;\n\n if (validTypes.indexOf(eventType) < 0 && !eventIsFunction) {\n warnInFunction(eventFunctionName, eventText + \" can't be \" + eventType);\n return callback();\n }\n\n try {\n if (eventIsFunction) {\n var eventOutput = event();\n if (validTypes.indexOf(typeof eventOutput) < 0) {\n warnInFunction(\n eventFunctionName,\n event + \" returns no string: \" + eventOutput\n );\n return callback();\n }\n event = eventOutput;\n }\n } catch (error) {\n warnInFunction(eventFunctionName, error);\n return callback();\n }\n\n event = (\"\" + event).replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_|_$)/g, \"\");\n\n var eventParams = { type: eventText, event: event };\n var firstPage = !userNavigated && pages < 2;\n\n metadata = appendMetadata(metadata, eventParams);\n\n if (event) {\n sendData(\n assign(eventParams, {\n id: uuid(),\n query: getQueryParams(!firstPage),\n referrer:\n (firstPage || sameSite) && collectMetricByString(\"r\")\n ? previousReferrer\n : null,\n\n metadata: stringify(metadata),\n }),\n callback\n );\n }\n };\n\n var defaultEventFunc = function (event, metadata, callback) {\n sendEvent(event, metadata, callback);\n };\n\n // Set default function if user didn't define a function\n if (!window[eventFunctionName])\n window[eventFunctionName] = defaultEventFunc;\n\n var eventFunc = window[eventFunctionName];\n\n // Read queue of the user defined function\n var queue = eventFunc && eventFunc.q ? eventFunc.q : [];\n\n // Overwrite user defined function\n window[eventFunctionName] = defaultEventFunc;\n\n // Post events from the queue of the user defined function\n for (var event in queue) {\n if (hasProp(queue, event)) {\n Array.isArray(queue[event])\n ? sendEvent.apply(null, queue[event])\n : sendEvent(queue[event]);\n }\n }\n } catch (e) {\n sendError(e);\n }\n})(\n window,\n {},\n \"simpleanalyticscdn.com\",\n \"queue.\",\n \"cdn_hello_12\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","sendError","warn","undefinedVar","undefined","trueVar","falseVar","trueText","https","pageviewText","eventText","errorText","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","notSendingWhen","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","protocol","documentElement","language","Height","scroll","uaData","userAgentData","scrollHeight","offsetHeight","clientHeight","pagehide","platformText","platformVersionText","docsUrl","pages","isBotAgent","test","screen","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","warnInFunction","name","error","hasProp","obj","prop","Object","hasOwnProperty","isString","string","filterRegex","item","replace","attr","attribute","getAttribute","convertCommaSeparatedToArray","csv","Array","isArray","length","split","isObject","object","constructor","assign","to","arg","index","nextSource","nextKey","settings","sa_settings","logSettings","keys","ignoreMetrics","collectMetricByString","metricAbbreviation","filter","RegExp","now","Date","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","c","getRandomValues","Uint8Array","toString","r","Math","random","isFunction","func","namespaceText","namespace","appendMetadata","metadata","data","metadataObject","metadataCollectorFunction","metadataCollector","strictUtm","getQueryParams","ignoreSource","overwriteSearch","search","keyValue","ignore","paramsRegexList","allowParams","map","join","regex","loadedVariable","sa_event_loaded","sendData","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","image","Image","onerror","onload","src","key","overwrittenHostname","hostname","definedHostname","basePayload","version","errorOrMessage","stack","type","path","pathname","event","filename","indexOf","message","timezone","start","scrolled","mode","collectDnt","value","autoCollect","eventFunctionName","saGlobal","ignorePages","nonUniqueHostnames","pathOverwriter","Intl","DateTimeFormat","resolvedOptions","timeZone","phantom","bot","webdriver","__nightmare","callPhantom","_phantom","solana","__polypane","_bot","collectDataOnLeave","ua","page_id","session_id","sri","mobile","brands","doctype","hostname_original","lastSendPath","hiddenStart","getReferrer","referrer","msHidden","sendOnLeave","id","push","append","original_id","duration","round","max","position","sendBeacon","bind","e","hidden","body","documentClientHeight","height","min","scrollTop","previousReferrer","sameSite","userNavigated","getPath","overwrite","pathOverwriterFunction","i","ignorePageRaw","ignorePage","shouldIgnore","hash","pageview","isPushState","pathOverwrite","callbackRaw","querySearch","parts","shift","viewport_width","innerWidth","viewport_height","innerHeight","screen_width","width","screen_height","performaceEntryType","perf","performance","navigationText","getEntriesByType","currentReferrerHostname","unique","triggerSendPageView","delSrc","deleteSourceInfo","query","currentPage","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","his","history","hisPushState","pushState","dis","dispatchEvent","pushStateText","Event","orig","rv","this","createEvent","initEvent","sa_pageview","validTypes","sendEvent","eventIsFunction","eventType","eventOutput","eventParams","firstPage","defaultEventFunc","eventFunc","queue","q"],"mappings":";;CAEA,SACEA,EACAC,EACAC,EAIAC,EACAC,GAEA,IAQE,IAAIC,EAAeC,UACfC,GAAU,EACVC,GAAW,EACXC,EAAW,OACXC,EAAQ,SACRC,EAAe,WACfC,EAAY,QACZC,EAAY,QAGZC,EAAMd,EAAOe,QACbC,EAAa,aACbC,EAAMjB,EAAOkB,UACbC,EAAMnB,EAAOoB,SACbC,EAAmBF,EAAIG,KACvBC,EAAMvB,EAAOwB,SACbC,EAAYR,EAAIQ,UAChBC,EAAa,uBACbC,EAAiBD,EAAa,QAC9BE,EAA2BpB,EAC3BqB,EAAyBC,mBACzBC,EAAyBC,mBACzBC,EAAYC,KAAKD,UAEjBE,EAAuBnC,EAAOoC,iBAC9BC,EAAaC,iBAA0BpC,EACvCqC,EAAkBhB,EAAIgB,iBAAmB,GACzCC,EAAW,WACXC,EAAS,SAETC,EAAS,SACTC,EAAS1B,EAAI2B,cACbC,EAAeH,EAASD,EACxBK,EAAe,SAAWL,EAC1BM,EAAe,SAAWN,EAE1BO,EAAW,WACXC,EAAe,WACfC,EAAsB,kBACtBC,EAAU,mCACVC,EAAQ,EACRC,EACF,sBAAsBC,KAAK7B,KAAe,WAAW6B,KAAK7B,GACxD8B,EAASvD,EAAOuD,OAIhBC,EACFjC,EAAIkC,eAAiBlC,EAAImC,cAAc,gBAAkBxD,EAAU,MAOrEE,EAAO,WAEL,IAAIuD,EAAO,GAAGC,MAAMC,KAAKC,WAOzB,OAJAH,EAAKI,QAAQ,qBAINC,SAASC,UAAUC,MAAML,KAAK/C,EAAIV,KAAMU,EAAK6C,IAGtD,IAAIQ,EAAiB,SAAUC,EAAMC,GACnCjE,EAAK,iBAAmBgE,EAAO,aAAcC,IAG3CC,EAAU,SAAUC,EAAKC,GAC3B,OAAOC,OAAOR,UAAUS,eAAeb,KAAKU,EAAKC,IAG/CG,EAAW,SAAUC,GACvB,MAAwB,iBAAVA,GAGZC,EAAc,SAAUC,GAC1B,OAAOA,EAAKC,QAAQ,sBAAuB,SAGzCC,EAAO,SAAUxB,EAAeyB,GAClC,OAAOzB,GAAiBA,EAAc0B,aAAa,QAAUD,IAG3DE,EAA+B,SAAUC,GAC3C,OAAOC,MAAMC,QAAQF,GACjBA,EACAT,EAASS,IAAQA,EAAIG,OACnBH,EAAII,MAAM,OACV,IAGJC,EAAW,SAAUC,GACvB,OAAOA,GAAUA,EAAOC,cAAgBlB,QAGtCmB,EAAS,WAGX,IAFA,IAAIC,EAAK,GACLC,EAAMhC,UACDiC,EAAQ,EAAGA,EAAQD,EAAIP,OAAQQ,IAAS,CAC/C,IAAIC,EAAaF,EAAIC,GACrB,GAAIN,EAASO,GACX,IAAK,IAAIC,KAAWD,EACd1B,EAAQ0B,EAAYC,KACtBJ,EAAGI,GAAWD,EAAWC,IAKjC,OAAOJ,GAGLK,EAAWlG,EAAOmG,YAClBC,EAAcF,GAAYzB,OAAO4B,KAAKpG,GAAkBsF,OAG5DtF,EAAmB2F,EAAO3F,EAAkBiG,GAExCE,GAAahG,EAAK,WAAYH,GAGlC,IAAIqG,GAAgBnB,EAClBlF,EAAiBqG,eAAiBtB,EAAKxB,EAAe,mBAGpD+C,GAAwB,SAAUC,GAEpC,OAGgB,IAFdF,GAAcG,OAAO,SAAU3B,GAC7B,OAAO,IAAI4B,OAAO,IAAMF,GAAoBlD,KAAKwB,KAChDS,QAIHoB,GAAMC,KAAKD,IAEXE,GAAO,WACT,IAAIC,EAAe9G,EAAO+G,QAAU/G,EAAOgH,SACvCC,EAAY,CAAC,MAAQ,KAAO,KAAO,KAAO,KAC1CC,EAAY,SAEhB,IACE,OAAOD,EAAUlC,QAAQmC,EAAW,SAAUC,GAC5C,OACEA,EACCL,EAAaM,gBAAgB,IAAIC,WAAW,IAAI,GAC9C,IAAOF,EAAI,GACdG,SAAS,MAEb,MAAOjD,GACP,OAAO4C,EAAUlC,QAAQmC,EAAW,SAAUC,GAC5C,IAAII,EAAqB,GAAhBC,KAAKC,SAAiB,EAE/B,OADMN,EAAI,EAAII,EAAS,EAAJA,EAAW,GACrBD,SAAS,QAKpBI,GAAa,SAAUC,GACzB,MAAsB,mBAARA,GAIZC,GAAgB,YAChBC,GACF5H,EAAiB2H,KACjB5C,EAAKxB,EAAeoE,KAuxBxB,KApxBME,GAAiB,SAAUC,EAAUC,GACvC,IAAIC,EAAiBjI,EAAO6H,GAAY,aACpCpC,EAASwC,KAAiBF,EAAWnC,EAAOmC,EAAUE,IAC1D,IAAIC,EAA4BlI,EAAOmI,IACvC,IAAKT,GAAWQ,GAKd,OAJIC,IACF/H,EACE+H,GAAoB,0BAA4BA,IAE7CJ,EAET,IACE,OAAOnC,EACLmC,EACAG,EAA0BrE,KAAK7D,EAAQ4F,EAAOmC,EAAUC,KAE1D,MAAO3D,GACPF,EAAe,WAAYE,KAU3B+D,GACFnI,EAAiBmI,WACjBpD,EAAKxB,EAAe,eAAiB/C,EAEnC4H,GAAiB,SAAUC,EAAcC,GAC3C,OACGA,GAAmBpH,EAAIqH,QACrB5E,MAAM,GACN4B,MAAM,KACNiB,OAAO,SAAUgC,GAChB,IAAIC,EAASJ,IAAiB/B,GAAsB,MAEhDoC,EAAkBC,GAAYC,IAAIhE,GAAaiE,KAAK,KACpDC,EAAQL,EACR,KAAOC,EAAkB,KACzB,YACCP,GAAY,GAAK,KAClB,yCACCA,GAAY,GAAK,QAClB,IACAO,EACA,KACJ,OAAID,IAAWE,GAAYrD,OAAe/E,EAInC,IAAIkG,OAAOqC,GAAOzF,KAAKmF,KAE/BK,KAAK,MAAQzI,GAgChB2I,GAAiBnB,GAAY,UACjC,GAAI7H,EAAOgJ,KAAmBzI,EAAS,OAAOH,EAAKsB,EAAa,SAChE1B,EAAOiJ,gBAAkB1I,EACzBP,EAAOgJ,IAAkBzI,EAOzB,IAAI2I,GAAW,SAAUlB,EAAMmB,EAAUC,GACvCpB,EAAOoB,EAAepB,EAAOpC,EAAOyD,GAASC,GAAMtB,GAE/C/G,EAAIsI,QAAUH,IAAcpB,EAAKuB,MAAQhJ,GACzCU,EAAIuI,qBAAuBJ,IAAcpB,EAAKyB,KAAOlJ,GAGzD,IAAImJ,EAAQ,IAAIC,MACZR,IACFO,EAAME,QAAUT,EAChBO,EAAMG,OAASV,GAEjBO,EAAMI,IACJzH,EACA,eACAoC,OAAO4B,KAAK2B,GACTvB,OAAO,SAAUsD,GAChB,OAAO/B,EAAK+B,IAAQ1J,IAErBwI,IAAI,SAAUkB,GACb,OACElI,EAAuBkI,GACvB,IACAlI,EAAuBmG,EAAK+B,MAG/BjB,KAAK,KACR,SACAlC,KAAKD,OAILqD,GACF/J,EAAiBgK,UAAYjF,EAAKxB,EAAe,YAC/C0G,GAAkBF,IAAuB3I,EAEzC8I,GAAc,CAChBC,QA6oBJ,eA5oBIH,SAAUC,IASZ/J,EAAY,SAAUkK,GACpBA,EAAiBA,EAAeC,MAC5BD,EAAiB,IAAMA,EAAeC,MACtCD,EACJjK,EAAKiK,GACLnB,GACEtD,EAAOuE,GAAa,CAClBI,KAAM1J,EACNwD,MAAOgG,EACPG,KAAMrJ,EAAIsJ,WAEZpK,EACAE,IAMJ4B,EACEtB,EACA,SAAU6J,GACJA,EAAMC,WAA+C,EAAnCD,EAAMC,SAASC,QAAQ1K,IAC3CC,EAAUuK,EAAMG,UAGpBrK,GAOF,IAwDIsK,GAxDAC,GAAQpE,KAERqE,GAAW,EAOXC,GAAOhL,EAAiBgL,MAAQjG,EAAKxB,EAAe,QAGpD0H,MAvKsBC,GAuKClL,EAAiBiL,cAtKvBC,GAuKjBlL,EAAiBiL,WACjBlG,EAAKxB,EAAe,eAAiB/C,GACrCuE,EAAKxB,EAAe,aAAe/C,GACnCuE,EAAKxB,EAAe,gBAAkB/C,EAGtC2K,KACqC,SAAvCpG,EAAKxB,EAAe,iBACpBvD,EAAiBmL,cAAgB5K,GAI/B6K,GACFpL,EAAiBqL,UACjBtG,EAAKxB,EAAe,cACpBqE,GAAY,IAAMjH,EAGhB2K,GAAcpG,EAChBlF,EAAiBsL,aAAevG,EAAKxB,EAAe,iBAIlDoF,GAAczD,EAChBlF,EAAiB2I,aAAe5D,EAAKxB,EAAe,iBAIlDgI,GAAqBrG,EACvBlF,EAAiBuL,oBACfxG,EAAKxB,EAAe,yBAIpBiI,GACFxL,EAAiBwL,gBAAkBzG,EAAKxB,EAAe,mBAGrD2E,GACFlI,EAAiBkI,mBACjBnD,EAAKxB,EAAe,sBAItB,IAEEsH,GAAWvE,GAAsB,KAC7BmF,KAAKC,iBAAiBC,kBAAkBC,SACxCxL,EACJ,MAAOgE,IACPjE,EAAKiE,IAOP,IAAIyH,GAAU9L,EAAO8L,QACjBC,GACF9K,EAAI+K,WACJhM,EAAOiM,aACPjM,EAAOkM,aACPlM,EAAOmM,UACNL,KAAYA,GAAQM,QACrBpM,EAAOqM,YACPrM,EAAOsM,MACPjJ,GACAmE,KAAKC,UAAYD,KAAKC,SAGpB8E,GACFhG,GAAsB,MAAQA,GAAsB,QAElDwF,KAAK5B,GAAY4B,IAAMxL,GAE3B,IAAI8I,GAAUzD,EAAOuE,GAAa,CAEhCqC,GAAIjG,GAAsB,MAAQ9E,EAAYpB,EAE9CK,MAAOS,EAAImB,UAAY5B,EACvBoK,SAAUA,GACV2B,QAASF,GAAqB1F,KAASxG,EAGvCqM,WAAYnG,GAAsB,MAAQM,KAASxG,IA0BrD,GAvBAgJ,GAAQsD,IAAMnM,EAIVmC,IACF0G,GAAQuD,OAASjK,EAAOiK,OACxBvD,GAAQwD,OAAS5K,EAAUU,EAAOkK,SAS/BtL,EAAIuL,SAAS1M,EAAK,4CAInB8J,KAAoB7I,IACtBgI,GAAQ0D,kBAAoB1L,IAGzB6J,IAAclK,KAAcC,GAA0B,KAAnBA,EAAID,GAC1C,OAAOZ,EACLuB,EAAiBX,EAAa,oBAAsBmC,EAAU,SAK7B,GAAlC9B,EAAiBuJ,QAAQ,OACxB,aAAatH,KAAKjC,IACnB2I,IAED5J,EACE,mBACEiB,EACA,SACA8B,EACA,0BAON,IACI6J,GA0DAC,GA3DA3D,GAAO,GAGP4D,GAAc,WAKhB,OAFEjN,EAAiBkN,UAAYnI,EAAKxB,EAAe,aAGzBjC,EAAI4L,UAAY,IACrCpI,QAAQ1D,EAAkB6I,IAC1BnF,QAAQ,sDAAuD,MAC/DA,QAAQ,YAAa,OAAS1E,GAKjC8M,GAAWD,KAOXE,GAAW,EAEXC,GAAc,SAAUC,EAAIC,GAC9B,GAAKhB,GAAL,CAEA,IAAIiB,EAAS5H,EAAOuE,GAAa,CAC/BI,KAAM,SACNkD,YAAaF,EAAOD,EAAKjE,GAAQoD,UAenC,GAXIlG,GAAsB,OACxBiH,EAAOE,SAAWlG,KAAKmG,OAAOhH,KAAQoE,GAAQqC,IA3fnC,MA6fbA,GAAW,EACXrC,GAAQpE,KAGJJ,GAAsB,UACxBiH,EAAOxC,SAAWxD,KAAKoG,IAAI,EAAG5C,GAAU6C,OAGtCN,IAAStM,EAAI6M,WAEf5E,GAASsE,EAAQnN,EAAcE,QAE/B,IACEU,EAAI6M,WAAWC,KAAK9M,EAApBA,CAAyBoB,EAAa,UAAWJ,EAAUuL,IAC3D,MAAOQ,GAEP9E,GAASsE,EAAQnN,EAAcE,MAMrC4B,EACE,mBACA,WACMZ,EAAI0M,QACA,KAAOjL,KAAYhD,GAASqN,KAClCJ,GAActG,MACTyG,IAAYzG,KAAQsG,IAE7BzM,GAGF2B,EAAqBa,EAAUqK,GAAa7M,GAE5C,IAAI0N,GAAO3M,EAAI2M,MAAQ,GACnBL,GAAW,WACb,IACE,IAAIM,EAAuB5L,EAAgBQ,IAAiB,EACxDqL,EAAS5G,KAAKoG,IAChBM,GAAKrL,IAAiB,EACtBqL,GAAKpL,IAAiB,EACtBP,EAAgBQ,IAAiB,EACjCR,EAAgBM,IAAiB,EACjCN,EAAgBO,IAAiB,GAEnC,OAAO0E,KAAK6G,IACV,IAKI,EAJJ7G,KAAKmG,MACF,MAAQpL,EAAgB+L,WAAa,GAAKH,GACzCC,EACA,IAGN,MAAO/J,IAEP,OADAjE,EAAKiE,IACE,IAIXlC,EAAqB,OAAQ,WAC3B6I,GAAW6C,KACX1L,EACEO,EACA,WACMsI,GAAW6C,OAAY7C,GAAW6C,OAExCrN,KAQJ,IAgCI+N,GAkCAC,GAAUC,GAlEVC,GAAU,SAAUC,GACtB,IAAInE,EAAO,GAIX,IACEA,EAAOmE,GAAa5M,EAAuBZ,EAAIsJ,UAC/C,MAAOpG,IACPjE,EAAKiE,IAGP,IAAIuK,EAAyB5O,EAAOyL,IACpC,GAAI/D,GAAWkH,GACb,IACEpE,EAAOoE,EAAuB/K,KAAK7D,EAAQ,CAAEwK,KAAMA,KAAWA,EAC9D,MAAOnG,IACPF,EAAe,OAAQE,IAK3B,IA5YiB,SAAUmG,GAC3B,IAAK,IAAIqE,KAAKtD,GAAa,CACzB,IAAIuD,EAAgBvD,GAAYsD,GAChC,GAAKC,EAAL,CAGA,IAAIC,EAtOI,KAuOND,EAAc,GAAcA,EAvOtB,IAuO8CA,EAEtD,GACEC,IAAevE,GACf,IAAI9D,OACF,IAAM7B,EAAYkK,GAAYhK,QAAQ,SAAU,QAAU,IAC1D,KACAzB,KAAKkH,GAEP,OAAOjK,GAEX,OAAOC,EA0XHwO,CAAaxE,GAQjB,MAFY,QAARS,IAAkB9J,EAAI8N,OAAMzE,GAAQrJ,EAAI8N,KAAKzJ,MAAM,KAAK,IAErDgF,EAPLpK,EAAKuB,EAAiB,YAAc6I,IA8CpC0E,GAAW,SACbC,EACAC,EACArH,EACAsH,IAEKA,GAAe3H,GAAWK,KAAWsH,EAActH,GACxD,IACIuH,EAGEC,EAJFpG,EAAWzB,GAAW2H,GAAeA,EAAc,aAEnD1K,EAASyK,KAAgD,EAA9BA,EAAcxE,QAAQ,OAGnDwE,GADIG,EAAQH,EAAc5J,MAAM,MACVgK,QACtBF,EAAc,IAAMC,EAAMzG,KAAK,MAGjC,IAAI0B,EAAOkE,GAAQU,GAGnB,GAAK5E,GAAQwC,IAAgBxC,EAA7B,CAEAwC,GAAexC,EACflB,GAAKkB,KAAOA,EAGRjE,GAAsB,OACxB+C,GAAKmG,eACHjI,KAAKoG,IAAIrL,EAA2B,aAAK,EAAGvC,EAAO0P,YAAc,IACjE,KACFpG,GAAKqG,gBACHnI,KAAKoG,IACHrL,EAAgBQ,IAAiB,EACjC/C,EAAO4P,aAAe,IACnB,MAILrJ,GAAsB,MACpBtF,EAAIuB,KAAW8G,GAAK9G,GAAYvB,EAAIuB,IAItCe,GAAUgD,GAAsB,QAClC+C,GAAKuG,aAAetM,EAAOuM,MAC3BxG,GAAKyG,cAAgBxM,EAAO6K,QAI9B,IAII4B,EAJAC,EAAOjQ,EAAOkQ,YACdC,EAAiB,aAIrB,IACEH,EAAsBC,EAAKG,iBAAiBD,GAAgB,GAAG5F,KAC/D,MAAOlG,IACPjE,EAAKiE,IAGPoK,GAAgBuB,GAC+C,EAA3D,CAAC,SAAU,gBAAgBpF,QAAQoF,GAGnCC,GACAA,EAAKE,KACwC,EAA7C,CAAC,EAAG,GAAGvF,QAAQqF,EAAKE,GAAgB5F,MAGxC,IAAI8F,EAA0BlD,GAC1BA,GAAS3H,MAhuBH,KAguBgB,GACtBnF,EACJmO,GAAWrB,IACgD,EAAvD3B,GAAmBZ,QAAQyF,IAC3BA,GAA2BhP,EAC3Bb,EAGJ8I,GAAKgH,OACH,QAAQhN,KAAK4J,OAAkBiC,GAAeV,GAC1CjO,GACCgO,GAEPzG,EAAWD,GAAeC,EAAU,CAClCwC,KAAM5J,EACN6J,KAAMlB,GAAKkB,OAGb,IAAI+F,EAAsB,WACxB3O,EAA2BrB,EAC3B,IAAIiQ,EACFrB,GAAeV,KAAkBlI,GAAsB,MA3H1C,SACjB4I,EACAsB,EACAjC,EACAkC,EACA3I,EACAoB,GAEIgG,GAAa9B,GAAY,GAAKhE,GAAQoD,QAASlM,GAC/CgM,KAAoBlD,GAAQoD,QAAU5F,MAE1C,IAAI8J,EAAczG,GAAkBwE,KAEpCxF,GACE,CACEoE,GAAIjE,GAAQoD,QACZlC,KAAM5J,EACNwM,UAAWsD,GAAoBjC,EAAWrB,GAAW,KACrDuD,MAAOA,GAASrI,GAAeoI,GAE/B1I,SAAU9F,EAAU8F,IAEtBoB,GAGFoF,GAAmBpB,GACnBA,GAAWwD,EAEXvN,IAgGEwN,CACEzB,EACAqB,EACAhC,GACAc,EAAcjH,GAAemI,EAAQlB,GAAejP,EACpD0H,EACAoB,IAIJ,GAAKvH,EAmBH2O,SAjBA,IACM5N,GAAU+E,GAAW/E,EAAOkO,sBAC9BlO,EACGkO,qBAAqB,CAAC5N,EAAcC,IACpC4N,KAAK,SAAUC,GACd1H,GAAQ2H,QAAUD,EAAkB9N,GACpCoG,GAAQ4H,WAAaF,EAAkB7N,GACvCqN,MAEDW,SAAMX,GAETA,IAEF,MAAOvC,GACPuC,OAWFY,GAAMnR,EAAOoR,QACbC,GAAeF,GAAMA,GAAIG,UAAYjR,EACrCkR,GAAMvR,EAAOwR,cACbC,GAAgB,YAIhBrG,IAAeiG,IAAgBK,OAASH,KAqB1CJ,GAAIG,WAnBEK,GAAOR,GADiB5G,GAoBAkH,IAlBrB,WACL,IAEI/G,EAFA5E,EAAMhC,UACN8N,EAAKD,GAAKzN,MAAM2N,KAAM/L,GAY1B,OAVI4B,GAAWgK,OACbhH,EAAQ,IAAIgH,MAAMnH,KAIlBG,EAAQnJ,EAAIuQ,YAAY,UAClBC,UAAUxH,GAAMhK,EAASA,GAEjCmK,EAAM5G,UAAYgC,EAClByL,GAAI7G,GACGkH,IAMXzP,EACEsP,GACA,WACEvC,GAAS,IAEX1O,GAGF2B,EACE,WACA,WACE+M,GAAS,IAEX1O,IAKA4K,IAAuB,QAARH,IAAkB,iBAAkBjL,GACrDmC,EACE,aACA,WACE+M,GAAS,IAEX1O,GAIA4K,IAAa8D,KAEjBlP,EAAOgS,YAAc,SAAUxH,EAAMzC,EAAUoB,GAC7C+F,GAAS,EAAG1E,EAAMzC,EAAUoB,IAQ9B,IAAI8I,GAAa,CAAC,SAAU,UAExBC,GAAY,SAAUxH,EAAO3C,EAAUsH,IACpCA,GAAe3H,GAAWK,KAAWsH,EAActH,GAExD,IAAIoK,EAAkBzK,GAAWgD,GAC7BvB,EAAWzB,GAAW2H,GAAeA,EAAc,aACnD+C,SAAmB1H,EAEvB,GAAIuH,GAAWrH,QAAQwH,GAAa,IAAMD,EAExC,OADAhO,EAAekH,GAAmBzK,EAAY,aAAewR,GACtDjJ,IAGT,IACE,GAAIgJ,EAAiB,CACnB,IAAIE,EAAc3H,IAClB,GAAIuH,GAAWrH,eAAeyH,GAAe,EAK3C,OAJAlO,EACEkH,GACAX,EAAQ,uBAAyB2H,GAE5BlJ,IAETuB,EAAQ2H,GAEV,MAAOhO,IAEP,OADAF,EAAekH,GAAmBhH,IAC3B8E,IAGTuB,GAAS,GAAKA,GAAO3F,QAAQ,eAAgB,KAAKA,QAAQ,WAAY,IAEtE,IAAIuN,EAAc,CAAE/H,KAAM3J,EAAW8J,MAAOA,GACxC6H,GAAa9D,IAAiBrL,EAAQ,EAE1C2E,EAAWD,GAAeC,EAAUuK,GAEhC5H,GACFxB,GACEtD,EAAO0M,EAAa,CAClBhF,GAAIzG,KACJ6J,MAAOrI,IAAgBkK,GACvBpF,UACGoF,GAAa/D,KAAajI,GAAsB,KAC7CgI,GACA,KAENxG,SAAU9F,EAAU8F,KAEtBoB,IAKFqJ,GAAmB,SAAU9H,EAAO3C,EAAUoB,GAChD+I,GAAUxH,EAAO3C,EAAUoB,IAIxBnJ,EAAOqL,MACVrL,EAAOqL,IAAqBmH,IAE9B,IAAIC,GAAYzS,EAAOqL,IAGnBqH,GAAQD,IAAaA,GAAUE,EAAIF,GAAUE,EAAI,GAMrD,IAAK,IAAIjI,MAHT1K,EAAOqL,IAAqBmH,GAGVE,GACZpO,EAAQoO,GAAOhI,MACjBrF,MAAMC,QAAQoN,GAAMhI,KAChBwH,GAAUhO,MAAM,KAAMwO,GAAMhI,KAC5BwH,GAAUQ,GAAMhI,MAGxB,MAAOsD,IACP7N,EAAU6N,IA7IY,IAAUzD,GACxBoH,GA3mBkBxG,GAnN9B,CA68BEnL,OACA,uBACA"} \ No newline at end of file diff --git a/dist/latest/latest.dev.js b/dist/latest/latest.dev.js index a2127a9e..17543b84 100644 --- a/dist/latest/latest.dev.js +++ b/dist/latest/latest.dev.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy friendly analytics (docs.simpleanalytics.com/script; 2023-05-03; ed1a; v11) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; 80f5; v12) */ /* eslint-env browser */ (function ( @@ -110,8 +110,8 @@ return Array.isArray(csv) ? csv : isString(csv) && csv.length - ? csv.split(/, ?/) - : []; + ? csv.split(/, ?/) + : []; }; var isObject = function (object) { @@ -191,11 +191,17 @@ attr(scriptElement, namespaceText) || defaultNamespace; - var metadataObject = window[namespace + "_metadata"]; var appendMetadata = function (metadata, data) { + var metadataObject = window[namespace + "_metadata"]; if (isObject(metadataObject)) metadata = assign(metadata, metadataObject); var metadataCollectorFunction = window[metadataCollector]; - if (!isFunction(metadataCollectorFunction)) return metadata; + if (!isFunction(metadataCollectorFunction)) { + if (metadataCollector) + warn( + metadataCollector + " not found, set window." + metadataCollector + ); + return metadata; + } try { return assign( metadata, @@ -216,9 +222,9 @@ overwriteOptions.strictUtm || attr(scriptElement, "strict-utm") == trueText; - var getQueryParams = function (ignoreSource) { + var getQueryParams = function (ignoreSource, overwriteSearch) { return ( - loc.search + (overwriteSearch || loc.search) .slice(1) .split("&") .filter(function (keyValue) { @@ -432,12 +438,13 @@ // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS // + var phantom = window.phantom; var bot = nav.webdriver || window.__nightmare || window.callPhantom || window._phantom || - window.phantom || + (phantom && !phantom.solana) || window.__polypane || window._bot || isBotAgent || @@ -512,8 +519,12 @@ var lastSendPath; var getReferrer = function () { + // Customers can overwrite their referrer, here we check for that + var overwrittenReferrer = + overwriteOptions.referrer || attr(scriptElement, "referrer"); + return ( - (doc.referrer || "") + (overwrittenReferrer || doc.referrer || "") .replace(locationHostname, definedHostname) .replace(/^https?:\/\/((m|l|w{2,3}([0-9]+)?)\.)?([^?#]+)(.*)$/, "$4") .replace(/^([^/]+)$/, "$1") || undefinedVar @@ -554,7 +565,12 @@ // sendData will assign payload to request sendData(append, undefinedVar, trueVar); } else { - nav.sendBeacon(fullApiUrl + "/append", stringify(append)); + try { + nav.sendBeacon.bind(nav)(fullApiUrl + "/append", stringify(append)); + } catch (e) { + // Fallback for browsers throwing "Illegal invocation" when the URL is invalid + sendData(append, undefinedVar, trueVar); + } } }; @@ -651,21 +667,26 @@ isPushState, deleteSourceInfo, sameSite, - metadata + query, + metadata, + callback ) { if (isPushState) sendOnLeave("" + payload.page_id, trueVar); if (collectDataOnLeave) payload.page_id = uuid(); var currentPage = definedHostname + getPath(); - sendData({ - id: payload.page_id, - type: pageviewText, - referrer: !deleteSourceInfo || sameSite ? referrer : null, - query: getQueryParams(deleteSourceInfo), + sendData( + { + id: payload.page_id, + type: pageviewText, + referrer: !deleteSourceInfo || sameSite ? referrer : null, + query: query || getQueryParams(deleteSourceInfo), - metadata: stringify(metadata), - }); + metadata: stringify(metadata), + }, + callback + ); previousReferrer = referrer; referrer = currentPage; @@ -675,7 +696,21 @@ var sameSite, userNavigated; - var pageview = function (isPushState, pathOverwrite, metadata) { + var pageview = function ( + isPushState, + pathOverwrite, + metadata, + callbackRaw + ) { + if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata; + var callback = isFunction(callbackRaw) ? callbackRaw : function () {}; + var querySearch; + if (isString(pathOverwrite) && pathOverwrite.indexOf("?") > -1) { + // keep query from manual path + var parts = pathOverwrite.split("?"); + pathOverwrite = parts.shift(); + querySearch = "?" + parts.join("?"); + } // Obfuscate personal data in URL by dropping the search and hash var path = getPath(pathOverwrite); @@ -738,7 +773,10 @@ : falseVar; // We set unique variable based on pushstate or back navigation, if no match we check the referrer - page.unique = isPushState || userNavigated ? falseVar : !sameSite; + page.unique = + /__cf_/.test(getReferrer()) || isPushState || userNavigated + ? falseVar + : !sameSite; metadata = appendMetadata(metadata, { type: pageviewText, @@ -747,11 +785,15 @@ var triggerSendPageView = function () { fetchedHighEntropyValues = trueVar; + var delSrc = + isPushState || userNavigated || !collectMetricByString("r"); sendPageView( isPushState, - isPushState || userNavigated || !collectMetricByString("r"), // r = referrers + delSrc, // r = referrers sameSite, - metadata + querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar, + metadata, + callback ); }; @@ -841,11 +883,11 @@ } if (autoCollect) pageview(); - else { - window.sa_pageview = function (path, metadata) { - pageview(0, path, metadata); - }; - } + + window.sa_pageview = function (path, metadata, callback) { + pageview(0, path, metadata, callback); + }; + ///////////////////// // EVENTS @@ -938,6 +980,6 @@ {}, "simpleanalyticscdn.com", "queue.", - "cdn_latest_dev_11", + "cdn_latest_dev_12", "sa" ); diff --git a/dist/latest/latest.js b/dist/latest/latest.js index 15d59a31..b24f2ad2 100644 --- a/dist/latest/latest.js +++ b/dist/latest/latest.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy friendly analytics (docs.simpleanalytics.com/script; 2023-05-03; f270; v11) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; ce07; v12) */ -!function(l,t,e,n,p){try{var h=undefined,f=!0,d=!1,r="true",a="https:",m="pageview",u="event",i="error",o=l.console,c="doNotTrack",g=l.navigator,s=l.location,v=s.host,y=l.document,_=g.userAgent,w="Not sending request ",b=w+"when ",E=d,O=encodeURIComponent,x=decodeURIComponent,S=JSON.stringify,M=l.addEventListener,k="https://queue."+e,q=y.documentElement||{},A="language",$="Height",j="scroll",D=g.userAgentData,C=j+$,R="offset"+$,H="client"+$,P="pagehide",T="platform",U="platformVersion",I="https://docs.simpleanalytics.com",V=0,B=/(bot|spider|crawl)/i.test(_)&&!/(cubot)/i.test(_),N=l.screen,z=y.currentScript||y.querySelector('script[src*="'+e+'"]');p=function(){var t=[].slice.call(arguments);return t.unshift("Simple Analytics:"),Function.prototype.apply.call(o.warn,o,t)};var F=function(t,e){p("Error in your "+t+" function:",e)},W=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},G=function(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},J=function(t,e){return t&&t.getAttribute("data-"+e)},L=function(t){return Array.isArray(t)?t:"string"==typeof t&&t.length?t.split(/, ?/):[]},Y=function(t){return t&&t.constructor===Object},Z=function(){for(var t={},e=arguments,n=0;n>t/4).toString(16)})}catch(r){return t.replace(n,function(t){var e=16*Math.random()|0;return(t<2?e:3&e|8).toString(16)})}},rt=function(t){return"function"==typeof t},at="namespace",it=t[at]||J(z,at)||"sa",ot=l[it+"_metadata"],ct=function(t,e){Y(ot)&&(t=Z(t,ot));var n=l[Mt];if(!rt(n))return t;try{return Z(t,n.call(l,Z(t,e)))}catch(r){F("metadata",r)}},st=t.strictUtm||J(z,"strict-utm")==r,ut=function(a){return s.search.slice(1).split("&").filter(function(t){var e=a||!tt("ut"),n=Ot.map(G).join("|"),r=e?"^("+n+")=":"^((utm_)"+(st?"":"?")+"(source|medium|content|term|campaign)"+(st?"":"|ref")+"|"+n+")=";return e&&!Ot.length?d:new RegExp(r).test(t)}).join("&")||h},lt=it+"_loaded";if(l[lt]==f)return p(w+"twice");l.sa_event_loaded=f,l[lt]=f;var pt=function(e,t,n){e=n?e:Z(At,Dt,e),g.brave&&!n&&(e.brave=f),g._duckduckgoloader_&&!n&&(e.duck=f);var r=new Image;t&&(r.onerror=t,r.onload=t),r.src=k+"/simple.gif?"+Object.keys(e).filter(function(t){return e[t]!=h}).map(function(t){return O(t)+"="+O(e[t])}).join("&")+"&time="+Date.now()},ht=t.hostname||J(z,"hostname"),ft=ht||v,dt={version:"cdn_latest_11",hostname:ft};n=function(t){t=t.stack?t+" "+t.stack:t,p(t),pt(Z(dt,{type:i,error:t,path:s.pathname}),h,f)},M(i,function(t){t.filename&&-1>t/4).toString(16)})}catch(r){return t.replace(n,function(t){var e=16*Math.random()|0;return(t<2?e:3&e|8).toString(16)})}},at=function(t){return"function"==typeof t},it="namespace",ot=t[it]||L(z,it)||"sa",ct=function(t,e){var n=d[ot+"_metadata"];Z(n)&&(t=K(t,n));var r=d[Mt];if(!at(r))return Mt&&m(Mt+" not found, set window."+Mt),t;try{return K(t,r.call(d,K(t,e)))}catch(a){F("metadata",a)}},st=t.strictUtm||L(z,"strict-utm")==r,ut=function(a,t){return(t||s.search).slice(1).split("&").filter(function(t){var e=a||!et("ut"),n=Et.map(J).join("|"),r=e?"^("+n+")=":"^((utm_)"+(st?"":"?")+"(source|medium|content|term|campaign)"+(st?"":"|ref")+"|"+n+")=";return e&&!Et.length?y:new RegExp(r).test(t)}).join("&")||v},lt=ot+"_loaded";if(d[lt]==g)return m(f+"twice");d.sa_event_loaded=g,d[lt]=g;var pt=function(e,t,n){e=n?e:K($t,Ct,e),w.brave&&!n&&(e.brave=g),w._duckduckgoloader_&&!n&&(e.duck=g);var r=new Image;t&&(r.onerror=t,r.onload=t),r.src=k+"/simple.gif?"+Object.keys(e).filter(function(t){return e[t]!=v}).map(function(t){return E(t)+"="+E(e[t])}).join("&")+"&time="+Date.now()},ft=t.hostname||L(z,"hostname"),ht=ft||b,dt={version:"cdn_latest_12",hostname:ht};n=function(t){t=t.stack?t+" "+t.stack:t,m(t),pt(K(dt,{type:i,error:t,path:s.pathname}),v,g)},M(i,function(t){t.filename&&-1> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n var metadataObject = window[namespace + \"_metadata\"];\n var appendMetadata = function (metadata, data) {\n if (isObject(metadataObject)) metadata = assign(metadata, metadataObject);\n var metadataCollectorFunction = window[metadataCollector];\n if (!isFunction(metadataCollectorFunction)) return metadata;\n try {\n return assign(\n metadata,\n metadataCollectorFunction.call(window, assign(metadata, data))\n );\n } catch (error) {\n warnInFunction(\"metadata\", error);\n }\n };\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource) {\n return (\n loc.search\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n var paramsRegexList = allowParams.map(filterRegex).join(\"|\");\n var regex = ignore\n ? \"^(\" + paramsRegexList + \")=\"\n : \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \"|\" +\n paramsRegexList +\n \")=\";\n if (ignore && !allowParams.length) return falseVar;\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n // Ignore pages specified in data-ignore-pages\n var shouldIgnore = function (path) {\n for (var i in ignorePages) {\n var ignorePageRaw = ignorePages[i];\n if (!ignorePageRaw) continue;\n\n // Prepend a slash when it's missing\n var ignorePage =\n ignorePageRaw[0] == slash ? ignorePageRaw : slash + ignorePageRaw;\n\n if (\n ignorePage === path ||\n new RegExp(\n \"^\" + filterRegex(ignorePage).replace(/\\\\\\*/gi, \"(.*)\") + \"$\",\n \"i\"\n ).test(path)\n )\n return trueVar;\n }\n return falseVar;\n };\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n if (callback) {\n image.onerror = callback;\n image.onload = callback;\n }\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n /////////////////////\n // ERROR FUNCTIONS\n //\n\n // Send errors\n // no var because it's scoped outside of the try/catch\n sendError = function (errorOrMessage) {\n errorOrMessage = errorOrMessage.stack\n ? errorOrMessage + \" \" + errorOrMessage.stack\n : errorOrMessage;\n warn(errorOrMessage);\n sendData(\n assign(basePayload, {\n type: errorText,\n error: errorOrMessage,\n path: loc.pathname,\n }),\n undefinedVar,\n trueVar\n );\n };\n\n // We listen for the error events and only send errors that are\n // from our script (checked by filename) to our server.\n addEventListenerFunc(\n errorText,\n function (event) {\n if (event.filename && event.filename.indexOf(baseUrl) > -1) {\n sendError(event.message);\n }\n },\n falseVar\n );\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n var start = now();\n\n var scrolled = 0;\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n // Should we record Do Not Track visits?\n var collectDnt = isBoolean(overwriteOptions.collectDnt)\n ? overwriteOptions.collectDnt\n : attr(scriptElement, \"ignore-dnt\") == trueText ||\n attr(scriptElement, \"skip-dnt\") == trueText ||\n attr(scriptElement, \"collect-dnt\") == trueText;\n\n // Some customers want to collect page views manually\n var autoCollect = !(\n attr(scriptElement, \"auto-collect\") == \"false\" ||\n overwriteOptions.autoCollect === falseVar\n );\n\n // Event function name\n var eventFunctionName =\n overwriteOptions.saGlobal ||\n attr(scriptElement, \"sa-global\") ||\n namespace + \"_\" + eventText;\n\n // Customers can ignore certain pages\n var ignorePages = convertCommaSeparatedToArray(\n overwriteOptions.ignorePages || attr(scriptElement, \"ignore-pages\")\n );\n\n // Customers can allow params\n var allowParams = convertCommaSeparatedToArray(\n overwriteOptions.allowParams || attr(scriptElement, \"allow-params\")\n );\n\n // Customers can allow params\n var nonUniqueHostnames = convertCommaSeparatedToArray(\n overwriteOptions.nonUniqueHostnames ||\n attr(scriptElement, \"non-unique-hostnames\")\n );\n\n // Customers can overwrite certain values\n var pathOverwriter =\n overwriteOptions.pathOverwriter || attr(scriptElement, \"path-overwriter\");\n\n // Customers can add metadata to events and pageviews via a function\n var metadataCollector =\n overwriteOptions.metadataCollector ||\n attr(scriptElement, \"metadata-collector\");\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var bot =\n nav.webdriver ||\n window.__nightmare ||\n window.callPhantom ||\n window._phantom ||\n window.phantom ||\n window.__polypane ||\n window._bot ||\n isBotAgent ||\n Math.random() == Math.random();\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = falseVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n // Warn when no document.doctype is defined (this breaks some documentElement dimensions)\n if (!doc.doctype) warn(\"Add DOCTYPE html for accurate dimensions\");\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (!collectDnt && doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n return (\n (doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n // t = timeonpage\n if (collectMetricByString(\"t\")) {\n append.duration = Math.round((now() - start - msHidden) / thousand);\n }\n msHidden = 0;\n start = now();\n\n // scro = scrolled\n if (collectMetricByString(\"scro\")) {\n append.scrolled = Math.max(0, scrolled, position());\n }\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n nav.sendBeacon(fullApiUrl + \"/append\", stringify(append));\n }\n };\n\n var hiddenStart;\n addEventListenerFunc(\n \"visibilitychange\",\n function () {\n if (doc.hidden) {\n if (!(\"on\" + pagehide in window)) sendOnLeave();\n hiddenStart = now();\n } else msHidden += now() - hiddenStart;\n },\n falseVar\n );\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n var body = doc.body || {};\n var position = function () {\n try {\n var documentClientHeight = documentElement[clientHeight] || 0;\n var height = Math.max(\n body[scrollHeight] || 0,\n body[offsetHeight] || 0,\n documentElement[clientHeight] || 0,\n documentElement[scrollHeight] || 0,\n documentElement[offsetHeight] || 0\n );\n return Math.min(\n 100,\n Math.round(\n (100 * ((documentElement.scrollTop || 0) + documentClientHeight)) /\n height /\n 5\n ) * 5\n );\n } catch (error) {\n warn(error);\n return 0;\n }\n };\n\n addEventListenerFunc(\"load\", function () {\n scrolled = position();\n addEventListenerFunc(\n scroll,\n function () {\n if (scrolled < position()) scrolled = position();\n },\n falseVar\n );\n });\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n var pathOverwriterFunction = window[pathOverwriter];\n if (isFunction(pathOverwriterFunction)) {\n try {\n path = pathOverwriterFunction.call(window, { path: path }) || path;\n } catch (error) {\n warnInFunction(\"path\", error);\n }\n }\n\n // Ignore pages specified in data-ignore-pages\n if (shouldIgnore(path)) {\n warn(notSendingWhen + \"ignoring \" + path);\n return;\n }\n\n // Add hash to path when script is put in to hash mode\n if (mode == \"hash\" && loc.hash) path += loc.hash.split(\"?\")[0];\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n metadata\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData({\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: getQueryParams(deleteSourceInfo),\n\n metadata: stringify(metadata),\n });\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (isPushState, pathOverwrite, metadata) {\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n // v = viewportsizes\n if (collectMetricByString(\"v\")) {\n page.viewport_width =\n Math.max(documentElement[clientWidth] || 0, window.innerWidth || 0) ||\n null;\n page.viewport_height =\n Math.max(\n documentElement[clientHeight] || 0,\n window.innerHeight || 0\n ) || null;\n }\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n // sc = screensizes\n if (screen && collectMetricByString(\"sc\")) {\n page.screen_width = screen.width;\n page.screen_height = screen.height;\n }\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n var currentReferrerHostname = referrer\n ? referrer.split(slash)[0]\n : undefinedVar;\n sameSite = referrer\n ? nonUniqueHostnames.indexOf(currentReferrerHostname) > -1 ||\n currentReferrerHostname == locationHostname\n : falseVar;\n\n // We set unique variable based on pushstate or back navigation, if no match we check the referrer\n page.unique = isPushState || userNavigated ? falseVar : !sameSite;\n\n metadata = appendMetadata(metadata, {\n type: pageviewText,\n path: page.path,\n });\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n sendPageView(\n isPushState,\n isPushState || userNavigated || !collectMetricByString(\"r\"), // r = referrers\n sameSite,\n metadata\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n /////////////////////\n // AUTOMATED PAGE VIEW COLLECTION\n //\n\n var his = window.history;\n var hisPushState = his ? his.pushState : undefinedVar;\n var dis = window.dispatchEvent;\n var pushStateText = \"pushState\";\n\n // Overwrite history pushState function to\n // allow listening on the pushState event\n if (autoCollect && hisPushState && Event && dis) {\n var stateListener = function (type) {\n var orig = his[type];\n return function () {\n var arg = arguments;\n var rv = orig.apply(this, arg);\n var event;\n if (isFunction(Event)) {\n event = new Event(type);\n } else {\n // Fix for IE\n // https://github.com/simpleanalytics/scripts/issues/8\n event = doc.createEvent(\"Event\");\n event.initEvent(type, trueVar, trueVar);\n }\n event.arguments = arg;\n dis(event);\n return rv;\n };\n };\n\n his.pushState = stateListener(pushStateText);\n\n addEventListenerFunc(\n pushStateText,\n function () {\n pageview(1);\n },\n falseVar\n );\n\n addEventListenerFunc(\n \"popstate\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n // When in hash mode, we record a pageview based on the onhashchange function\n if (autoCollect && mode == \"hash\" && \"onhashchange\" in window) {\n addEventListenerFunc(\n \"hashchange\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n if (autoCollect) pageview();\n else {\n window.sa_pageview = function (path, metadata) {\n pageview(0, path, metadata);\n };\n }\n\n /////////////////////\n // EVENTS\n //\n\n var validTypes = [\"string\", \"number\"];\n\n var sendEvent = function (event, metadata, callbackRaw) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n\n var eventIsFunction = isFunction(event);\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var eventType = typeof event;\n\n if (validTypes.indexOf(eventType) < 0 && !eventIsFunction) {\n warnInFunction(eventFunctionName, eventText + \" can't be \" + eventType);\n return callback();\n }\n\n try {\n if (eventIsFunction) {\n var eventOutput = event();\n if (validTypes.indexOf(typeof eventOutput) < 0) {\n warnInFunction(\n eventFunctionName,\n event + \" returns no string: \" + eventOutput\n );\n return callback();\n }\n event = eventOutput;\n }\n } catch (error) {\n warnInFunction(eventFunctionName, error);\n return callback();\n }\n\n event = (\"\" + event).replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_|_$)/g, \"\");\n\n var eventParams = { type: eventText, event: event };\n var firstPage = !userNavigated && pages < 2;\n\n metadata = appendMetadata(metadata, eventParams);\n\n if (event) {\n sendData(\n assign(eventParams, {\n id: uuid(),\n query: getQueryParams(!firstPage),\n referrer:\n (firstPage || sameSite) && collectMetricByString(\"r\")\n ? previousReferrer\n : null,\n\n metadata: stringify(metadata),\n }),\n callback\n );\n }\n };\n\n var defaultEventFunc = function (event, metadata, callback) {\n sendEvent(event, metadata, callback);\n };\n\n // Set default function if user didn't define a function\n if (!window[eventFunctionName])\n window[eventFunctionName] = defaultEventFunc;\n\n var eventFunc = window[eventFunctionName];\n\n // Read queue of the user defined function\n var queue = eventFunc && eventFunc.q ? eventFunc.q : [];\n\n // Overwrite user defined function\n window[eventFunctionName] = defaultEventFunc;\n\n // Post events from the queue of the user defined function\n for (var event in queue) {\n if (hasProp(queue, event)) {\n Array.isArray(queue[event])\n ? sendEvent.apply(null, queue[event])\n : sendEvent(queue[event]);\n }\n }\n } catch (e) {\n sendError(e);\n }\n})(\n window,\n {},\n \"simpleanalyticscdn.com\",\n \"queue.\",\n \"cdn_latest_11\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","sendError","warn","undefinedVar","undefined","trueVar","falseVar","trueText","https","pageviewText","eventText","errorText","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","notSendingWhen","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","protocol","documentElement","language","Height","scroll","uaData","userAgentData","scrollHeight","offsetHeight","clientHeight","pagehide","platformText","platformVersionText","docsUrl","pages","isBotAgent","test","screen","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","warnInFunction","name","error","hasProp","obj","prop","Object","hasOwnProperty","filterRegex","item","replace","attr","attribute","getAttribute","convertCommaSeparatedToArray","csv","Array","isArray","length","split","isObject","object","constructor","assign","to","arg","index","nextSource","nextKey","settings","sa_settings","logSettings","keys","ignoreMetrics","collectMetricByString","metricAbbreviation","filter","RegExp","now","Date","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","c","getRandomValues","Uint8Array","toString","r","Math","random","isFunction","func","namespaceText","namespace","metadataObject","appendMetadata","metadata","data","metadataCollectorFunction","metadataCollector","strictUtm","getQueryParams","ignoreSource","search","keyValue","ignore","paramsRegexList","allowParams","map","join","regex","loadedVariable","sa_event_loaded","sendData","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","image","Image","onerror","onload","src","key","overwrittenHostname","hostname","definedHostname","basePayload","version","errorOrMessage","stack","type","path","pathname","event","filename","indexOf","message","timezone","start","scrolled","mode","collectDnt","value","autoCollect","eventFunctionName","saGlobal","ignorePages","nonUniqueHostnames","pathOverwriter","Intl","DateTimeFormat","resolvedOptions","timeZone","bot","webdriver","__nightmare","callPhantom","_phantom","phantom","__polypane","_bot","collectDataOnLeave","ua","page_id","session_id","sri","mobile","brands","doctype","hostname_original","lastSendPath","hiddenStart","referrer","msHidden","sendOnLeave","id","push","append","original_id","duration","round","max","position","sendBeacon","hidden","body","documentClientHeight","height","min","scrollTop","previousReferrer","sameSite","userNavigated","getPath","overwrite","pathOverwriterFunction","i","ignorePageRaw","ignorePage","shouldIgnore","hash","pageview","isPushState","pathOverwrite","viewport_width","innerWidth","viewport_height","innerHeight","screen_width","width","screen_height","performaceEntryType","perf","performance","navigationText","getEntriesByType","currentReferrerHostname","unique","triggerSendPageView","deleteSourceInfo","currentPage","query","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","e","his","history","hisPushState","pushState","dis","dispatchEvent","pushStateText","Event","orig","rv","this","createEvent","initEvent","sa_pageview","validTypes","sendEvent","callbackRaw","eventIsFunction","eventType","eventOutput","eventParams","firstPage","defaultEventFunc","eventFunc","queue","q"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"latest.source.js","sources":["latest.source.js"],"sourcesContent":["/* eslint-env browser */\n\n(function (\n window,\n overwriteOptions,\n baseUrl,\n apiUrlPrefix,\n version,\n defaultNamespace,\n sendError,\n warn\n) {\n try {\n /////////////////////\n // PREDEFINED VARIABLES FOR BETTER MINIFICATION\n //\n\n // This seems like a lot of repetition, but it makes our script available for\n // multple destination which prevents us to need multiple scripts. The minified\n // version stays small.\n var undefinedVar = undefined;\n var trueVar = true;\n var falseVar = false;\n var trueText = \"true\";\n var https = \"https:\";\n var pageviewText = \"pageview\";\n var eventText = \"event\";\n var errorText = \"error\";\n var slash = \"/\";\n var protocol = https + \"//\";\n var con = window.console;\n var doNotTrack = \"doNotTrack\";\n var nav = window.navigator;\n var loc = window.location;\n var locationHostname = loc.host;\n var doc = window.document;\n var userAgent = nav.userAgent;\n var notSending = \"Not sending request \";\n var notSendingWhen = notSending + \"when \";\n var fetchedHighEntropyValues = falseVar;\n var encodeURIComponentFunc = encodeURIComponent;\n var decodeURIComponentFunc = decodeURIComponent;\n var stringify = JSON.stringify;\n var thousand = 1000;\n var addEventListenerFunc = window.addEventListener;\n var fullApiUrl = protocol + apiUrlPrefix + baseUrl;\n var documentElement = doc.documentElement || {};\n var language = \"language\";\n var Height = \"Height\";\n var Width = \"Width\";\n var scroll = \"scroll\";\n var uaData = nav.userAgentData;\n var scrollHeight = scroll + Height;\n var offsetHeight = \"offset\" + Height;\n var clientHeight = \"client\" + Height;\n var clientWidth = \"client\" + Width;\n var pagehide = \"pagehide\";\n var platformText = \"platform\";\n var platformVersionText = \"platformVersion\";\n var docsUrl = \"https://docs.simpleanalytics.com\";\n var pages = 0;\n var isBotAgent =\n /(bot|spider|crawl)/i.test(userAgent) && !/(cubot)/i.test(userAgent);\n var screen = window.screen;\n\n\n // Find the script element where options can be set on\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"' + baseUrl + '\"]');\n\n /////////////////////\n // HELPER FUNCTIONS\n //\n\n // A simple log function so the user knows why a request is not being send\n warn = function () {\n // 1. Convert args to a normal array\n var args = [].slice.call(arguments);\n\n // 2. Prepend log prefix\n args.unshift(\"Simple Analytics:\");\n\n // 3. Pass along arguments to console.warn\n // Function.prototype.apply.call is needed for Internet Explorer\n return Function.prototype.apply.call(con.warn, con, args);\n };\n\n var warnInFunction = function (name, error) {\n warn(\"Error in your \" + name + \" function:\", error);\n };\n\n var hasProp = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n\n var isString = function (string) {\n return typeof string == \"string\";\n };\n\n var filterRegex = function (item) {\n return item.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n var attr = function (scriptElement, attribute) {\n return scriptElement && scriptElement.getAttribute(\"data-\" + attribute);\n };\n\n var convertCommaSeparatedToArray = function (csv) {\n return Array.isArray(csv)\n ? csv\n : isString(csv) && csv.length\n ? csv.split(/, ?/)\n : [];\n };\n\n var isObject = function (object) {\n return object && object.constructor === Object;\n };\n\n var assign = function () {\n var to = {};\n var arg = arguments;\n for (var index = 0; index < arg.length; index++) {\n var nextSource = arg[index];\n if (isObject(nextSource)) {\n for (var nextKey in nextSource) {\n if (hasProp(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n\n var settings = window.sa_settings;\n var logSettings = settings || Object.keys(overwriteOptions).length;\n\n // Merge overwriteOptions with sa_settings\n overwriteOptions = assign(overwriteOptions, settings);\n\n if (logSettings) warn(\"Settings\", overwriteOptions);\n\n // Customers can skip data points\n var ignoreMetrics = convertCommaSeparatedToArray(\n overwriteOptions.ignoreMetrics || attr(scriptElement, \"ignore-metrics\")\n );\n\n var collectMetricByString = function (metricAbbreviation) {\n // Can't use Array.find() here because we need to support IE9\n return (\n ignoreMetrics.filter(function (item) {\n return new RegExp(\"^\" + metricAbbreviation).test(item);\n }).length === 0\n );\n };\n\n var now = Date.now;\n\n var uuid = function () {\n var cryptoObject = window.crypto || window.msCrypto;\n var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;\n var uuidRegex = /[018]/g;\n\n try {\n return emptyUUID.replace(uuidRegex, function (c) {\n return (\n c ^\n (cryptoObject.getRandomValues(new Uint8Array(1))[0] &\n (15 >> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n var appendMetadata = function (metadata, data) {\n var metadataObject = window[namespace + \"_metadata\"];\n if (isObject(metadataObject)) metadata = assign(metadata, metadataObject);\n var metadataCollectorFunction = window[metadataCollector];\n if (!isFunction(metadataCollectorFunction)) {\n if (metadataCollector)\n warn(\n metadataCollector + \" not found, set window.\" + metadataCollector\n );\n return metadata;\n }\n try {\n return assign(\n metadata,\n metadataCollectorFunction.call(window, assign(metadata, data))\n );\n } catch (error) {\n warnInFunction(\"metadata\", error);\n }\n };\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource, overwriteSearch) {\n return (\n (overwriteSearch || loc.search)\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n var paramsRegexList = allowParams.map(filterRegex).join(\"|\");\n var regex = ignore\n ? \"^(\" + paramsRegexList + \")=\"\n : \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \"|\" +\n paramsRegexList +\n \")=\";\n if (ignore && !allowParams.length) return falseVar;\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n // Ignore pages specified in data-ignore-pages\n var shouldIgnore = function (path) {\n for (var i in ignorePages) {\n var ignorePageRaw = ignorePages[i];\n if (!ignorePageRaw) continue;\n\n // Prepend a slash when it's missing\n var ignorePage =\n ignorePageRaw[0] == slash ? ignorePageRaw : slash + ignorePageRaw;\n\n if (\n ignorePage === path ||\n new RegExp(\n \"^\" + filterRegex(ignorePage).replace(/\\\\\\*/gi, \"(.*)\") + \"$\",\n \"i\"\n ).test(path)\n )\n return trueVar;\n }\n return falseVar;\n };\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n if (callback) {\n image.onerror = callback;\n image.onload = callback;\n }\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n /////////////////////\n // ERROR FUNCTIONS\n //\n\n // Send errors\n // no var because it's scoped outside of the try/catch\n sendError = function (errorOrMessage) {\n errorOrMessage = errorOrMessage.stack\n ? errorOrMessage + \" \" + errorOrMessage.stack\n : errorOrMessage;\n warn(errorOrMessage);\n sendData(\n assign(basePayload, {\n type: errorText,\n error: errorOrMessage,\n path: loc.pathname,\n }),\n undefinedVar,\n trueVar\n );\n };\n\n // We listen for the error events and only send errors that are\n // from our script (checked by filename) to our server.\n addEventListenerFunc(\n errorText,\n function (event) {\n if (event.filename && event.filename.indexOf(baseUrl) > -1) {\n sendError(event.message);\n }\n },\n falseVar\n );\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n var start = now();\n\n var scrolled = 0;\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n // Should we record Do Not Track visits?\n var collectDnt = isBoolean(overwriteOptions.collectDnt)\n ? overwriteOptions.collectDnt\n : attr(scriptElement, \"ignore-dnt\") == trueText ||\n attr(scriptElement, \"skip-dnt\") == trueText ||\n attr(scriptElement, \"collect-dnt\") == trueText;\n\n // Some customers want to collect page views manually\n var autoCollect = !(\n attr(scriptElement, \"auto-collect\") == \"false\" ||\n overwriteOptions.autoCollect === falseVar\n );\n\n // Event function name\n var eventFunctionName =\n overwriteOptions.saGlobal ||\n attr(scriptElement, \"sa-global\") ||\n namespace + \"_\" + eventText;\n\n // Customers can ignore certain pages\n var ignorePages = convertCommaSeparatedToArray(\n overwriteOptions.ignorePages || attr(scriptElement, \"ignore-pages\")\n );\n\n // Customers can allow params\n var allowParams = convertCommaSeparatedToArray(\n overwriteOptions.allowParams || attr(scriptElement, \"allow-params\")\n );\n\n // Customers can allow params\n var nonUniqueHostnames = convertCommaSeparatedToArray(\n overwriteOptions.nonUniqueHostnames ||\n attr(scriptElement, \"non-unique-hostnames\")\n );\n\n // Customers can overwrite certain values\n var pathOverwriter =\n overwriteOptions.pathOverwriter || attr(scriptElement, \"path-overwriter\");\n\n // Customers can add metadata to events and pageviews via a function\n var metadataCollector =\n overwriteOptions.metadataCollector ||\n attr(scriptElement, \"metadata-collector\");\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var phantom = window.phantom;\n var bot =\n nav.webdriver ||\n window.__nightmare ||\n window.callPhantom ||\n window._phantom ||\n (phantom && !phantom.solana) ||\n window.__polypane ||\n window._bot ||\n isBotAgent ||\n Math.random() == Math.random();\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = falseVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n // Warn when no document.doctype is defined (this breaks some documentElement dimensions)\n if (!doc.doctype) warn(\"Add DOCTYPE html for accurate dimensions\");\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (!collectDnt && doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n // Customers can overwrite their referrer, here we check for that\n var overwrittenReferrer =\n overwriteOptions.referrer || attr(scriptElement, \"referrer\");\n\n return (\n (overwrittenReferrer || doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n // t = timeonpage\n if (collectMetricByString(\"t\")) {\n append.duration = Math.round((now() - start - msHidden) / thousand);\n }\n msHidden = 0;\n start = now();\n\n // scro = scrolled\n if (collectMetricByString(\"scro\")) {\n append.scrolled = Math.max(0, scrolled, position());\n }\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n try {\n nav.sendBeacon.bind(nav)(fullApiUrl + \"/append\", stringify(append));\n } catch (e) {\n // Fallback for browsers throwing \"Illegal invocation\" when the URL is invalid\n sendData(append, undefinedVar, trueVar);\n }\n }\n };\n\n var hiddenStart;\n addEventListenerFunc(\n \"visibilitychange\",\n function () {\n if (doc.hidden) {\n if (!(\"on\" + pagehide in window)) sendOnLeave();\n hiddenStart = now();\n } else msHidden += now() - hiddenStart;\n },\n falseVar\n );\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n var body = doc.body || {};\n var position = function () {\n try {\n var documentClientHeight = documentElement[clientHeight] || 0;\n var height = Math.max(\n body[scrollHeight] || 0,\n body[offsetHeight] || 0,\n documentElement[clientHeight] || 0,\n documentElement[scrollHeight] || 0,\n documentElement[offsetHeight] || 0\n );\n return Math.min(\n 100,\n Math.round(\n (100 * ((documentElement.scrollTop || 0) + documentClientHeight)) /\n height /\n 5\n ) * 5\n );\n } catch (error) {\n warn(error);\n return 0;\n }\n };\n\n addEventListenerFunc(\"load\", function () {\n scrolled = position();\n addEventListenerFunc(\n scroll,\n function () {\n if (scrolled < position()) scrolled = position();\n },\n falseVar\n );\n });\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n var pathOverwriterFunction = window[pathOverwriter];\n if (isFunction(pathOverwriterFunction)) {\n try {\n path = pathOverwriterFunction.call(window, { path: path }) || path;\n } catch (error) {\n warnInFunction(\"path\", error);\n }\n }\n\n // Ignore pages specified in data-ignore-pages\n if (shouldIgnore(path)) {\n warn(notSendingWhen + \"ignoring \" + path);\n return;\n }\n\n // Add hash to path when script is put in to hash mode\n if (mode == \"hash\" && loc.hash) path += loc.hash.split(\"?\")[0];\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n query,\n metadata,\n callback\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData(\n {\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: query || getQueryParams(deleteSourceInfo),\n\n metadata: stringify(metadata),\n },\n callback\n );\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (\n isPushState,\n pathOverwrite,\n metadata,\n callbackRaw\n ) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var querySearch;\n if (isString(pathOverwrite) && pathOverwrite.indexOf(\"?\") > -1) {\n // keep query from manual path\n var parts = pathOverwrite.split(\"?\");\n pathOverwrite = parts.shift();\n querySearch = \"?\" + parts.join(\"?\");\n }\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n // v = viewportsizes\n if (collectMetricByString(\"v\")) {\n page.viewport_width =\n Math.max(documentElement[clientWidth] || 0, window.innerWidth || 0) ||\n null;\n page.viewport_height =\n Math.max(\n documentElement[clientHeight] || 0,\n window.innerHeight || 0\n ) || null;\n }\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n // sc = screensizes\n if (screen && collectMetricByString(\"sc\")) {\n page.screen_width = screen.width;\n page.screen_height = screen.height;\n }\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n var currentReferrerHostname = referrer\n ? referrer.split(slash)[0]\n : undefinedVar;\n sameSite = referrer\n ? nonUniqueHostnames.indexOf(currentReferrerHostname) > -1 ||\n currentReferrerHostname == locationHostname\n : falseVar;\n\n // We set unique variable based on pushstate or back navigation, if no match we check the referrer\n page.unique =\n /__cf_/.test(getReferrer()) || isPushState || userNavigated\n ? falseVar\n : !sameSite;\n\n metadata = appendMetadata(metadata, {\n type: pageviewText,\n path: page.path,\n });\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n var delSrc =\n isPushState || userNavigated || !collectMetricByString(\"r\");\n sendPageView(\n isPushState,\n delSrc, // r = referrers\n sameSite,\n querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar,\n metadata,\n callback\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n /////////////////////\n // AUTOMATED PAGE VIEW COLLECTION\n //\n\n var his = window.history;\n var hisPushState = his ? his.pushState : undefinedVar;\n var dis = window.dispatchEvent;\n var pushStateText = \"pushState\";\n\n // Overwrite history pushState function to\n // allow listening on the pushState event\n if (autoCollect && hisPushState && Event && dis) {\n var stateListener = function (type) {\n var orig = his[type];\n return function () {\n var arg = arguments;\n var rv = orig.apply(this, arg);\n var event;\n if (isFunction(Event)) {\n event = new Event(type);\n } else {\n // Fix for IE\n // https://github.com/simpleanalytics/scripts/issues/8\n event = doc.createEvent(\"Event\");\n event.initEvent(type, trueVar, trueVar);\n }\n event.arguments = arg;\n dis(event);\n return rv;\n };\n };\n\n his.pushState = stateListener(pushStateText);\n\n addEventListenerFunc(\n pushStateText,\n function () {\n pageview(1);\n },\n falseVar\n );\n\n addEventListenerFunc(\n \"popstate\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n // When in hash mode, we record a pageview based on the onhashchange function\n if (autoCollect && mode == \"hash\" && \"onhashchange\" in window) {\n addEventListenerFunc(\n \"hashchange\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n if (autoCollect) pageview();\n\n window.sa_pageview = function (path, metadata, callback) {\n pageview(0, path, metadata, callback);\n };\n\n\n /////////////////////\n // EVENTS\n //\n\n var validTypes = [\"string\", \"number\"];\n\n var sendEvent = function (event, metadata, callbackRaw) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n\n var eventIsFunction = isFunction(event);\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var eventType = typeof event;\n\n if (validTypes.indexOf(eventType) < 0 && !eventIsFunction) {\n warnInFunction(eventFunctionName, eventText + \" can't be \" + eventType);\n return callback();\n }\n\n try {\n if (eventIsFunction) {\n var eventOutput = event();\n if (validTypes.indexOf(typeof eventOutput) < 0) {\n warnInFunction(\n eventFunctionName,\n event + \" returns no string: \" + eventOutput\n );\n return callback();\n }\n event = eventOutput;\n }\n } catch (error) {\n warnInFunction(eventFunctionName, error);\n return callback();\n }\n\n event = (\"\" + event).replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_|_$)/g, \"\");\n\n var eventParams = { type: eventText, event: event };\n var firstPage = !userNavigated && pages < 2;\n\n metadata = appendMetadata(metadata, eventParams);\n\n if (event) {\n sendData(\n assign(eventParams, {\n id: uuid(),\n query: getQueryParams(!firstPage),\n referrer:\n (firstPage || sameSite) && collectMetricByString(\"r\")\n ? previousReferrer\n : null,\n\n metadata: stringify(metadata),\n }),\n callback\n );\n }\n };\n\n var defaultEventFunc = function (event, metadata, callback) {\n sendEvent(event, metadata, callback);\n };\n\n // Set default function if user didn't define a function\n if (!window[eventFunctionName])\n window[eventFunctionName] = defaultEventFunc;\n\n var eventFunc = window[eventFunctionName];\n\n // Read queue of the user defined function\n var queue = eventFunc && eventFunc.q ? eventFunc.q : [];\n\n // Overwrite user defined function\n window[eventFunctionName] = defaultEventFunc;\n\n // Post events from the queue of the user defined function\n for (var event in queue) {\n if (hasProp(queue, event)) {\n Array.isArray(queue[event])\n ? sendEvent.apply(null, queue[event])\n : sendEvent(queue[event]);\n }\n }\n } catch (e) {\n sendError(e);\n }\n})(\n window,\n {},\n \"simpleanalyticscdn.com\",\n \"queue.\",\n \"cdn_latest_12\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","sendError","warn","undefinedVar","undefined","trueVar","falseVar","trueText","https","pageviewText","eventText","errorText","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","notSendingWhen","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","protocol","documentElement","language","Height","scroll","uaData","userAgentData","scrollHeight","offsetHeight","clientHeight","pagehide","platformText","platformVersionText","docsUrl","pages","isBotAgent","test","screen","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","warnInFunction","name","error","hasProp","obj","prop","Object","hasOwnProperty","isString","string","filterRegex","item","replace","attr","attribute","getAttribute","convertCommaSeparatedToArray","csv","Array","isArray","length","split","isObject","object","constructor","assign","to","arg","index","nextSource","nextKey","settings","sa_settings","logSettings","keys","ignoreMetrics","collectMetricByString","metricAbbreviation","filter","RegExp","now","Date","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","c","getRandomValues","Uint8Array","toString","r","Math","random","isFunction","func","namespaceText","namespace","appendMetadata","metadata","data","metadataObject","metadataCollectorFunction","metadataCollector","strictUtm","getQueryParams","ignoreSource","overwriteSearch","search","keyValue","ignore","paramsRegexList","allowParams","map","join","regex","loadedVariable","sa_event_loaded","sendData","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","image","Image","onerror","onload","src","key","overwrittenHostname","hostname","definedHostname","basePayload","version","errorOrMessage","stack","type","path","pathname","event","filename","indexOf","message","timezone","start","scrolled","mode","collectDnt","value","autoCollect","eventFunctionName","saGlobal","ignorePages","nonUniqueHostnames","pathOverwriter","Intl","DateTimeFormat","resolvedOptions","timeZone","phantom","bot","webdriver","__nightmare","callPhantom","_phantom","solana","__polypane","_bot","collectDataOnLeave","ua","page_id","session_id","sri","mobile","brands","doctype","hostname_original","lastSendPath","hiddenStart","getReferrer","referrer","msHidden","sendOnLeave","id","push","append","original_id","duration","round","max","position","sendBeacon","bind","e","hidden","body","documentClientHeight","height","min","scrollTop","previousReferrer","sameSite","userNavigated","getPath","overwrite","pathOverwriterFunction","i","ignorePageRaw","ignorePage","shouldIgnore","hash","pageview","isPushState","pathOverwrite","callbackRaw","querySearch","parts","shift","viewport_width","innerWidth","viewport_height","innerHeight","screen_width","width","screen_height","performaceEntryType","perf","performance","navigationText","getEntriesByType","currentReferrerHostname","unique","triggerSendPageView","delSrc","deleteSourceInfo","query","currentPage","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","his","history","hisPushState","pushState","dis","dispatchEvent","pushStateText","Event","orig","rv","this","createEvent","initEvent","sa_pageview","validTypes","sendEvent","eventIsFunction","eventType","eventOutput","eventParams","firstPage","defaultEventFunc","eventFunc","queue","q"],"mappings":"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"} \ No newline at end of file diff --git a/dist/latest/light.js b/dist/latest/light.js index 1e539119..dda15604 100644 --- a/dist/latest/light.js +++ b/dist/latest/light.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy friendly analytics (docs.simpleanalytics.com/script; 2023-05-03; c569; v11) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; bc2f; v12) */ -!function(s,e,t,u){try{var i=undefined,n="https:",r=s.console,a="doNotTrack",p=s.navigator,c=s.location,d=c.host,o=s.document,l=p.userAgent,m="Not sending request ",f=!1,g=encodeURIComponent,h=decodeURIComponent,v=JSON.stringify,y=s.addEventListener,_="https://queue."+t,w=(o.documentElement,"language"),b=p.userAgentData,O="platform",S="platformVersion",k="https://docs.simpleanalytics.com",j=/(bot|spider|crawl)/i.test(l)&&!/(cubot)/i.test(l),E=o.currentScript||o.querySelector('script[src*="'+t+'"]');u=function(){var e=[].slice.call(arguments);return e.unshift("Simple Analytics:"),Function.prototype.apply.call(r.warn,r,e)};var q=function(e,t){return e&&e.getAttribute("data-"+t)},A=function(){for(var e,t,n,r={},a=arguments,o=0;o>e/4).toString(16)})}catch(r){return e.replace(n,function(e){var t=16*Math.random()|0;return(e<2?t:3&t|8).toString(16)})}},I="namespace",N=e[I]||q(E,I)||"sa",R=e.strictUtm||"true"==q(E,"strict-utm"),U=N+"_loaded";if(1==s[U])return u(m+"twice");s.sa_event_loaded=!0,s[U]=!0;var V,B=function(t,e,n){t=n?t:A(H,J,t),p.brave&&!n&&(t.brave=!0),p._duckduckgoloader_&&!n&&(t.duck=!0),(new Image).src=_+"/simple.gif?"+Object.keys(t).filter(function(e){return t[e]!=i}).map(function(e){return g(e)+"="+g(t[e])}).join("&")+"&time="+Date.now()},C=e.hostname||q(E,"hostname"),T=C||d,F={version:"cdn_light_11",hostname:T};e.mode||q(E,"mode");try{V=Intl.DateTimeFormat().resolvedOptions().timeZone}catch(Q){u(Q)}j&&(F.bot=!0);var H=A(F,{ua:l,https:c.protocol==n,timezone:V,page_id:D(),session_id:D()});if(H.sri=!1,b&&(H.mobile=b.mobile,H.brands=v(b.brands)),T!==d&&(H.hostname_original=d),a in p&&"1"==p[a])return u("Not sending request when "+a+" is enabled. See "+k+"/dnt");-1!=d.indexOf(".")&&!/^[0-9.:]+$/.test(d)||C||u("Set hostname on "+d+". See "+k+"/overwrite-domain-name");var z,J={},L=(o.referrer||"").replace(d,T).replace(/^https?:\/\/((m|l|w{2,3}([0-9]+)?)\.)?([^?#]+)(.*)$/,"$4").replace(/^([^/]+)$/,"$1")||i,M=function(e,t){var n=A(F,{type:"append",original_id:t?e:H.page_id});t||!p.sendBeacon?B(n,0,!0):p.sendBeacon(_+"/append",v(n))};y("pagehide",M,!1);var P,Z,G=function(e){var t="";try{t=e||h(c.pathname)}catch(Q){u(Q)}return t},K=function(e,t,n,r){e&&M(""+H.page_id,!0),H.page_id=D();var a,o=T+G();B({id:H.page_id,type:"pageview",referrer:!t||n?L:null,query:(a=t,c.search.slice(1).split("&").filter(function(e){return!a&&new RegExp("^((utm_)"+(R?"":"?")+"(source|medium|content|term|campaign)"+(R?"":"|ref")+")=").test(e)}).join("&")||i)}),L=o,0};!function(e,t){var n=G(t);if(n&&z!=n){z=n,J.path=n,p[w]&&(J[w]=p[w]);var r,a=s.performance,o="navigation";try{r=a.getEntriesByType(o)[0].type}catch(Q){u(Q)}Z=r?-1<["reload","back_forward"].indexOf(r):a&&a[o]&&-1<[1,2].indexOf(a[o].type),P=!!L&&L.split("/")[0]==d;var i=function(){f=!0,K(e,e||Z||!1,P)};if(f)i();else try{b&&"function"==typeof b.getHighEntropyValues?b.getHighEntropyValues([O,S]).then(function(e){H.os_name=e[O],H.os_version=e[S],i()})["catch"](i):i()}catch(c){i()}}}()}catch(W){u(W)}}(window,{},"simpleanalyticscdn.com"); +!function(l,e,t,f){try{var m=undefined,n="https:",r=l.console,a="doNotTrack",g=l.navigator,i=l.location,h=i.host,o=l.document,c=g.userAgent,s="Not sending request ",v=!1,u=encodeURIComponent,p=decodeURIComponent,d=JSON.stringify,y=l.addEventListener,_="https://queue."+t,b=(o.documentElement,"language"),w=g.userAgentData,O="platform",S="platformVersion",j="https://docs.simpleanalytics.com",k=/(bot|spider|crawl)/i.test(c)&&!/(cubot)/i.test(c),E=o.currentScript||o.querySelector('script[src*="'+t+'"]');f=function(){var e=[].slice.call(arguments);return e.unshift("Simple Analytics:"),Function.prototype.apply.call(r.warn,r,e)};var q=function(e){return"string"==typeof e},x=function(e,t){return e&&e.getAttribute("data-"+t)},A=function(){for(var e,t,n,r={},a=arguments,i=0;i>e/4).toString(16)})}catch(r){return e.replace(n,function(e){var t=16*Math.random()|0;return(e<2?t:3&t|8).toString(16)})}},N=function(e){return"function"==typeof e},R="namespace",U=e[R]||x(E,R)||"sa",V=e.strictUtm||"true"==x(E,"strict-utm"),B=function(t,e){return(e||i.search).slice(1).split("&").filter(function(e){return!t&&new RegExp("^((utm_)"+(V?"":"?")+"(source|medium|content|term|campaign)"+(V?"":"|ref")+")=").test(e)}).join("&")||m},C=U+"_loaded";if(1==l[C])return f(s+"twice");l.sa_event_loaded=!0,l[C]=!0;var T,F=function(t,e,n){t=n?t:A(L,P,t),g.brave&&!n&&(t.brave=!0),g._duckduckgoloader_&&!n&&(t.duck=!0),(new Image).src=_+"/simple.gif?"+Object.keys(t).filter(function(e){return t[e]!=m}).map(function(e){return u(e)+"="+u(t[e])}).join("&")+"&time="+Date.now()},H=e.hostname||x(E,"hostname"),z=H||h,J={version:"cdn_light_12",hostname:z};e.mode||x(E,"mode");try{T=Intl.DateTimeFormat().resolvedOptions().timeZone}catch(X){f(X)}k&&(J.bot=!0);var L=A(J,{ua:c,https:i.protocol==n,timezone:T,page_id:I(),session_id:I()});if(L.sri=!1,w&&(L.mobile=w.mobile,L.brands=d(w.brands)),z!==h&&(L.hostname_original=h),a in g&&"1"==g[a])return f("Not sending request when "+a+" is enabled. See "+j+"/dnt");-1!=h.indexOf(".")&&!/^[0-9.:]+$/.test(h)||H||f("Set hostname on "+h+". See "+j+"/overwrite-domain-name");var M,P={},Z=(e.referrer||x(E,"referrer")||o.referrer||"").replace(h,z).replace(/^https?:\/\/((m|l|w{2,3}([0-9]+)?)\.)?([^?#]+)(.*)$/,"$4").replace(/^([^/]+)$/,"$1")||m,G=function(e,t){var n=A(J,{type:"append",original_id:t?e:L.page_id});if(t||!g.sendBeacon)F(n,0,!0);else try{g.sendBeacon.bind(g)(_+"/append",d(n))}catch(r){F(n,0,!0)}};y("pagehide",G,!1);var K,Q,W=function(e){var t="";try{t=e||p(i.pathname)}catch(X){f(X)}return t};!function(t,e,n,r){!r&&N(n)&&(r=n);var a,i;N(r);q(e)&&-1> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource) {\n return (\n loc.search\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n if (ignore) return falseVar;\n var regex =\n \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \")=\";\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n\n\n\n\n\n\n\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var bot = isBotAgent;\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = falseVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n return (\n (doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n nav.sendBeacon(fullApiUrl + \"/append\", stringify(append));\n }\n };\n\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n\n\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n metadata\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData({\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: getQueryParams(deleteSourceInfo),\n\n });\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (isPushState, pathOverwrite, metadata) {\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n sameSite = referrer\n ? referrer.split(slash)[0] == locationHostname\n : falseVar;\n\n\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n sendPageView(\n isPushState,\n isPushState || userNavigated || !collectMetricByString(\"r\"), // r = referrers\n sameSite,\n metadata\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n\n\n pageview();\n\n } catch (e) {\n warn(e);\n }\n})(\n window,\n {},\n \"simpleanalyticscdn.com\",\n \"queue.\",\n \"cdn_light_11\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","warn","undefinedVar","undefined","https","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","protocol","language","documentElement","uaData","userAgentData","platformText","platformVersionText","docsUrl","isBotAgent","test","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","attr","attribute","getAttribute","assign","obj","prop","object","to","arg","index","length","nextSource","constructor","Object","nextKey","hasOwnProperty","settings","sa_settings","logSettings","keys","Date","now","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","replace","c","getRandomValues","Uint8Array","toString","error","r","Math","random","namespaceText","namespace","strictUtm","loadedVariable","sa_event_loaded","timezone","sendData","data","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","Image","src","filter","key","map","join","overwrittenHostname","hostname","definedHostname","basePayload","version","mode","Intl","DateTimeFormat","resolvedOptions","timeZone","bot","ua","page_id","session_id","sri","mobile","brands","hostname_original","indexOf","lastSendPath","referrer","sendOnLeave","id","push","append","type","original_id","sendBeacon","sameSite","userNavigated","getPath","overwrite","path","pathname","sendPageView","isPushState","deleteSourceInfo","metadata","ignoreSource","currentPage","query","search","split","keyValue","RegExp","pages","pathOverwrite","performaceEntryType","perf","performance","navigationText","getEntriesByType","triggerSendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","e","pageview"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"light.source.js","sources":["light.source.js"],"sourcesContent":["/* eslint-env browser */\n\n(function (\n window,\n overwriteOptions,\n baseUrl,\n apiUrlPrefix,\n version,\n defaultNamespace,\n sendError,\n warn\n) {\n try {\n /////////////////////\n // PREDEFINED VARIABLES FOR BETTER MINIFICATION\n //\n\n // This seems like a lot of repetition, but it makes our script available for\n // multple destination which prevents us to need multiple scripts. The minified\n // version stays small.\n var undefinedVar = undefined;\n var trueVar = true;\n var falseVar = false;\n var trueText = \"true\";\n var https = \"https:\";\n var pageviewText = \"pageview\";\n var eventText = \"event\";\n var slash = \"/\";\n var protocol = https + \"//\";\n var con = window.console;\n var doNotTrack = \"doNotTrack\";\n var nav = window.navigator;\n var loc = window.location;\n var locationHostname = loc.host;\n var doc = window.document;\n var userAgent = nav.userAgent;\n var notSending = \"Not sending request \";\n var notSendingWhen = notSending + \"when \";\n var fetchedHighEntropyValues = falseVar;\n var encodeURIComponentFunc = encodeURIComponent;\n var decodeURIComponentFunc = decodeURIComponent;\n var stringify = JSON.stringify;\n var thousand = 1000;\n var addEventListenerFunc = window.addEventListener;\n var fullApiUrl = protocol + apiUrlPrefix + baseUrl;\n var documentElement = doc.documentElement || {};\n var language = \"language\";\n var Height = \"Height\";\n var Width = \"Width\";\n var scroll = \"scroll\";\n var uaData = nav.userAgentData;\n var scrollHeight = scroll + Height;\n var offsetHeight = \"offset\" + Height;\n var clientHeight = \"client\" + Height;\n var clientWidth = \"client\" + Width;\n var pagehide = \"pagehide\";\n var platformText = \"platform\";\n var platformVersionText = \"platformVersion\";\n var docsUrl = \"https://docs.simpleanalytics.com\";\n var pages = 0;\n var isBotAgent =\n /(bot|spider|crawl)/i.test(userAgent) && !/(cubot)/i.test(userAgent);\n\n\n // Find the script element where options can be set on\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"' + baseUrl + '\"]');\n\n /////////////////////\n // HELPER FUNCTIONS\n //\n\n // A simple log function so the user knows why a request is not being send\n warn = function () {\n // 1. Convert args to a normal array\n var args = [].slice.call(arguments);\n\n // 2. Prepend log prefix\n args.unshift(\"Simple Analytics:\");\n\n // 3. Pass along arguments to console.warn\n // Function.prototype.apply.call is needed for Internet Explorer\n return Function.prototype.apply.call(con.warn, con, args);\n };\n\n var warnInFunction = function (name, error) {\n warn(\"Error in your \" + name + \" function:\", error);\n };\n\n var hasProp = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n\n var isString = function (string) {\n return typeof string == \"string\";\n };\n\n var filterRegex = function (item) {\n return item.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n var attr = function (scriptElement, attribute) {\n return scriptElement && scriptElement.getAttribute(\"data-\" + attribute);\n };\n\n var convertCommaSeparatedToArray = function (csv) {\n return Array.isArray(csv)\n ? csv\n : isString(csv) && csv.length\n ? csv.split(/, ?/)\n : [];\n };\n\n var isObject = function (object) {\n return object && object.constructor === Object;\n };\n\n var assign = function () {\n var to = {};\n var arg = arguments;\n for (var index = 0; index < arg.length; index++) {\n var nextSource = arg[index];\n if (isObject(nextSource)) {\n for (var nextKey in nextSource) {\n if (hasProp(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n\n var settings = window.sa_settings;\n var logSettings = settings || Object.keys(overwriteOptions).length;\n\n // Merge overwriteOptions with sa_settings\n overwriteOptions = assign(overwriteOptions, settings);\n\n if (logSettings) warn(\"Settings\", overwriteOptions);\n\n\n var collectMetricByString = function (metricAbbreviation) {\n // eslint-disable-next-line no-unreachable\n return true;\n };\n\n var now = Date.now;\n\n var uuid = function () {\n var cryptoObject = window.crypto || window.msCrypto;\n var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;\n var uuidRegex = /[018]/g;\n\n try {\n return emptyUUID.replace(uuidRegex, function (c) {\n return (\n c ^\n (cryptoObject.getRandomValues(new Uint8Array(1))[0] &\n (15 >> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource, overwriteSearch) {\n return (\n (overwriteSearch || loc.search)\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n if (ignore) return falseVar;\n // eslint-disable-next-line no-redeclare\n var regex =\n \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \")=\";\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n\n\n\n\n\n\n\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n // eslint-disable-next-line no-redeclare\n var bot = isBotAgent;\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = falseVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n // Customers can overwrite their referrer, here we check for that\n var overwrittenReferrer =\n overwriteOptions.referrer || attr(scriptElement, \"referrer\");\n\n return (\n (overwrittenReferrer || doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n try {\n nav.sendBeacon.bind(nav)(fullApiUrl + \"/append\", stringify(append));\n } catch (e) {\n // Fallback for browsers throwing \"Illegal invocation\" when the URL is invalid\n sendData(append, undefinedVar, trueVar);\n }\n }\n };\n\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n\n\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n query,\n metadata,\n callback\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData(\n {\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: query || getQueryParams(deleteSourceInfo),\n\n },\n callback\n );\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (\n isPushState,\n pathOverwrite,\n metadata,\n callbackRaw\n ) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var querySearch;\n if (isString(pathOverwrite) && pathOverwrite.indexOf(\"?\") > -1) {\n // keep query from manual path\n var parts = pathOverwrite.split(\"?\");\n pathOverwrite = parts.shift();\n querySearch = \"?\" + parts.join(\"?\");\n }\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n sameSite = referrer\n ? referrer.split(slash)[0] == locationHostname\n : falseVar;\n\n\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n var delSrc =\n isPushState || userNavigated || !collectMetricByString(\"r\");\n sendPageView(\n isPushState,\n delSrc, // r = referrers\n sameSite,\n querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar,\n metadata,\n callback\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n\n\n pageview();\n\n } catch (e) {\n warn(e);\n }\n})(\n window,\n {},\n \"simpleanalyticscdn.com\",\n \"queue.\",\n \"cdn_light_12\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","warn","undefinedVar","undefined","https","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","protocol","language","documentElement","uaData","userAgentData","platformText","platformVersionText","docsUrl","isBotAgent","test","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","isString","string","attr","attribute","getAttribute","assign","obj","prop","object","to","arg","index","length","nextSource","constructor","Object","nextKey","hasOwnProperty","settings","sa_settings","logSettings","keys","Date","now","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","replace","c","getRandomValues","Uint8Array","toString","error","r","Math","random","isFunction","func","namespaceText","namespace","strictUtm","getQueryParams","ignoreSource","overwriteSearch","search","split","filter","keyValue","RegExp","join","loadedVariable","sa_event_loaded","timezone","sendData","data","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","Image","src","key","map","overwrittenHostname","hostname","definedHostname","basePayload","version","mode","Intl","DateTimeFormat","resolvedOptions","timeZone","bot","ua","page_id","session_id","sri","mobile","brands","hostname_original","indexOf","lastSendPath","referrer","sendOnLeave","id","push","append","type","original_id","sendBeacon","bind","e","sameSite","userNavigated","getPath","overwrite","path","pathname","isPushState","pathOverwrite","metadata","callbackRaw","querySearch","parts","shift","performaceEntryType","perf","performance","navigationText","getEntriesByType","triggerSendPageView","delSrc","deleteSourceInfo","query","currentPage","pages","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","pageview"],"mappings":"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"} \ No newline at end of file diff --git a/dist/v12/app.js b/dist/v12/app.js new file mode 100644 index 00000000..43e62216 --- /dev/null +++ b/dist/v12/app.js @@ -0,0 +1,4 @@ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; 5efc; SRI-version; v12) */ + +!function(d,t,e,n,m){try{var v=undefined,g=!0,y=!1,r="true",a="https:",_="pageview",u="event",i="error",o=d.console,c="doNotTrack",w=d.navigator,s=d.location,b=s.host,l=d.document,p=w.userAgent,f="Not sending request ",h=f+"when ",O=y,E=encodeURIComponent,x=decodeURIComponent,S=JSON.stringify,M=d.addEventListener,k="https://queue."+e,q=l.documentElement||{},A="language",$="Height",j="scroll",D=w.userAgentData,C=j+$,R="offset"+$,H="client"+$,P="pagehide",T="platform",U="platformVersion",I="https://docs.simpleanalytics.com",V=0,B=/(bot|spider|crawl)/i.test(p)&&!/(cubot)/i.test(p),N=d.screen,z=l.currentScript||l.querySelector('script[src*="'+e+'"]');m=function(){var t=[].slice.call(arguments);return t.unshift("Simple Analytics:"),Function.prototype.apply.call(o.warn,o,t)};var F=function(t,e){m("Error in your "+t+" function:",e)},W=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},G=function(t){return"string"==typeof t},J=function(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},L=function(t,e){return t&&t.getAttribute("data-"+e)},Y=function(t){return Array.isArray(t)?t:G(t)&&t.length?t.split(/, ?/):[]},Z=function(t){return t&&t.constructor===Object},K=function(){for(var t={},e=arguments,n=0;n>t/4).toString(16)})}catch(r){return t.replace(n,function(t){var e=16*Math.random()|0;return(t<2?e:3&e|8).toString(16)})}},at=function(t){return"function"==typeof t},it="namespace",ot=t[it]||L(z,it)||"sa",ct=function(t,e){var n=d[ot+"_metadata"];Z(n)&&(t=K(t,n));var r=d[Mt];if(!at(r))return Mt&&m(Mt+" not found, set window."+Mt),t;try{return K(t,r.call(d,K(t,e)))}catch(a){F("metadata",a)}},st=t.strictUtm||L(z,"strict-utm")==r,ut=function(a,t){return(t||s.search).slice(1).split("&").filter(function(t){var e=a||!et("ut"),n=Et.map(J).join("|"),r=e?"^("+n+")=":"^((utm_)"+(st?"":"?")+"(source|medium|content|term|campaign)"+(st?"":"|ref")+"|"+n+")=";return e&&!Et.length?y:new RegExp(r).test(t)}).join("&")||v},lt=ot+"_loaded";if(d[lt]==g)return m(f+"twice");d.sa_event_loaded=g,d[lt]=g;var pt=function(e,t,n){e=n?e:K($t,Ct,e),w.brave&&!n&&(e.brave=g),w._duckduckgoloader_&&!n&&(e.duck=g);var r=new Image;t&&(r.onerror=t,r.onload=t),r.src=k+"/simple.gif?"+Object.keys(e).filter(function(t){return e[t]!=v}).map(function(t){return E(t)+"="+E(e[t])}).join("&")+"&time="+Date.now()},ft=t.hostname||L(z,"hostname"),ht=ft||b,dt={version:"cdn_latest_12",hostname:ht};n=function(t){t=t.stack?t+" "+t.stack:t,m(t),pt(K(dt,{type:i,error:t,path:s.pathname}),v,g)},M(i,function(t){t.filename&&-1> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n var appendMetadata = function (metadata, data) {\n var metadataObject = window[namespace + \"_metadata\"];\n if (isObject(metadataObject)) metadata = assign(metadata, metadataObject);\n var metadataCollectorFunction = window[metadataCollector];\n if (!isFunction(metadataCollectorFunction)) {\n if (metadataCollector)\n warn(\n metadataCollector + \" not found, set window.\" + metadataCollector\n );\n return metadata;\n }\n try {\n return assign(\n metadata,\n metadataCollectorFunction.call(window, assign(metadata, data))\n );\n } catch (error) {\n warnInFunction(\"metadata\", error);\n }\n };\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource, overwriteSearch) {\n return (\n (overwriteSearch || loc.search)\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n var paramsRegexList = allowParams.map(filterRegex).join(\"|\");\n var regex = ignore\n ? \"^(\" + paramsRegexList + \")=\"\n : \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \"|\" +\n paramsRegexList +\n \")=\";\n if (ignore && !allowParams.length) return falseVar;\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n // Ignore pages specified in data-ignore-pages\n var shouldIgnore = function (path) {\n for (var i in ignorePages) {\n var ignorePageRaw = ignorePages[i];\n if (!ignorePageRaw) continue;\n\n // Prepend a slash when it's missing\n var ignorePage =\n ignorePageRaw[0] == slash ? ignorePageRaw : slash + ignorePageRaw;\n\n if (\n ignorePage === path ||\n new RegExp(\n \"^\" + filterRegex(ignorePage).replace(/\\\\\\*/gi, \"(.*)\") + \"$\",\n \"i\"\n ).test(path)\n )\n return trueVar;\n }\n return falseVar;\n };\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n if (callback) {\n image.onerror = callback;\n image.onload = callback;\n }\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n /////////////////////\n // ERROR FUNCTIONS\n //\n\n // Send errors\n // no var because it's scoped outside of the try/catch\n sendError = function (errorOrMessage) {\n errorOrMessage = errorOrMessage.stack\n ? errorOrMessage + \" \" + errorOrMessage.stack\n : errorOrMessage;\n warn(errorOrMessage);\n sendData(\n assign(basePayload, {\n type: errorText,\n error: errorOrMessage,\n path: loc.pathname,\n }),\n undefinedVar,\n trueVar\n );\n };\n\n // We listen for the error events and only send errors that are\n // from our script (checked by filename) to our server.\n addEventListenerFunc(\n errorText,\n function (event) {\n if (event.filename && event.filename.indexOf(baseUrl) > -1) {\n sendError(event.message);\n }\n },\n falseVar\n );\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n var start = now();\n\n var scrolled = 0;\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n // Should we record Do Not Track visits?\n var collectDnt = isBoolean(overwriteOptions.collectDnt)\n ? overwriteOptions.collectDnt\n : attr(scriptElement, \"ignore-dnt\") == trueText ||\n attr(scriptElement, \"skip-dnt\") == trueText ||\n attr(scriptElement, \"collect-dnt\") == trueText;\n\n // Some customers want to collect page views manually\n var autoCollect = !(\n attr(scriptElement, \"auto-collect\") == \"false\" ||\n overwriteOptions.autoCollect === falseVar\n );\n\n // Event function name\n var eventFunctionName =\n overwriteOptions.saGlobal ||\n attr(scriptElement, \"sa-global\") ||\n namespace + \"_\" + eventText;\n\n // Customers can ignore certain pages\n var ignorePages = convertCommaSeparatedToArray(\n overwriteOptions.ignorePages || attr(scriptElement, \"ignore-pages\")\n );\n\n // Customers can allow params\n var allowParams = convertCommaSeparatedToArray(\n overwriteOptions.allowParams || attr(scriptElement, \"allow-params\")\n );\n\n // Customers can allow params\n var nonUniqueHostnames = convertCommaSeparatedToArray(\n overwriteOptions.nonUniqueHostnames ||\n attr(scriptElement, \"non-unique-hostnames\")\n );\n\n // Customers can overwrite certain values\n var pathOverwriter =\n overwriteOptions.pathOverwriter || attr(scriptElement, \"path-overwriter\");\n\n // Customers can add metadata to events and pageviews via a function\n var metadataCollector =\n overwriteOptions.metadataCollector ||\n attr(scriptElement, \"metadata-collector\");\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var phantom = window.phantom;\n var bot =\n nav.webdriver ||\n window.__nightmare ||\n window.callPhantom ||\n window._phantom ||\n (phantom && !phantom.solana) ||\n window.__polypane ||\n window._bot ||\n isBotAgent ||\n Math.random() == Math.random();\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = trueVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n // Warn when no document.doctype is defined (this breaks some documentElement dimensions)\n if (!doc.doctype) warn(\"Add DOCTYPE html for accurate dimensions\");\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (!collectDnt && doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n // Customers can overwrite their referrer, here we check for that\n var overwrittenReferrer =\n overwriteOptions.referrer || attr(scriptElement, \"referrer\");\n\n return (\n (overwrittenReferrer || doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n // t = timeonpage\n if (collectMetricByString(\"t\")) {\n append.duration = Math.round((now() - start - msHidden) / thousand);\n }\n msHidden = 0;\n start = now();\n\n // scro = scrolled\n if (collectMetricByString(\"scro\")) {\n append.scrolled = Math.max(0, scrolled, position());\n }\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n try {\n nav.sendBeacon.bind(nav)(fullApiUrl + \"/append\", stringify(append));\n } catch (e) {\n // Fallback for browsers throwing \"Illegal invocation\" when the URL is invalid\n sendData(append, undefinedVar, trueVar);\n }\n }\n };\n\n var hiddenStart;\n addEventListenerFunc(\n \"visibilitychange\",\n function () {\n if (doc.hidden) {\n if (!(\"on\" + pagehide in window)) sendOnLeave();\n hiddenStart = now();\n } else msHidden += now() - hiddenStart;\n },\n falseVar\n );\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n var body = doc.body || {};\n var position = function () {\n try {\n var documentClientHeight = documentElement[clientHeight] || 0;\n var height = Math.max(\n body[scrollHeight] || 0,\n body[offsetHeight] || 0,\n documentElement[clientHeight] || 0,\n documentElement[scrollHeight] || 0,\n documentElement[offsetHeight] || 0\n );\n return Math.min(\n 100,\n Math.round(\n (100 * ((documentElement.scrollTop || 0) + documentClientHeight)) /\n height /\n 5\n ) * 5\n );\n } catch (error) {\n warn(error);\n return 0;\n }\n };\n\n addEventListenerFunc(\"load\", function () {\n scrolled = position();\n addEventListenerFunc(\n scroll,\n function () {\n if (scrolled < position()) scrolled = position();\n },\n falseVar\n );\n });\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n var pathOverwriterFunction = window[pathOverwriter];\n if (isFunction(pathOverwriterFunction)) {\n try {\n path = pathOverwriterFunction.call(window, { path: path }) || path;\n } catch (error) {\n warnInFunction(\"path\", error);\n }\n }\n\n // Ignore pages specified in data-ignore-pages\n if (shouldIgnore(path)) {\n warn(notSendingWhen + \"ignoring \" + path);\n return;\n }\n\n // Add hash to path when script is put in to hash mode\n if (mode == \"hash\" && loc.hash) path += loc.hash.split(\"?\")[0];\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n query,\n metadata,\n callback\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData(\n {\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: query || getQueryParams(deleteSourceInfo),\n\n metadata: stringify(metadata),\n },\n callback\n );\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (\n isPushState,\n pathOverwrite,\n metadata,\n callbackRaw\n ) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var querySearch;\n if (isString(pathOverwrite) && pathOverwrite.indexOf(\"?\") > -1) {\n // keep query from manual path\n var parts = pathOverwrite.split(\"?\");\n pathOverwrite = parts.shift();\n querySearch = \"?\" + parts.join(\"?\");\n }\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n // v = viewportsizes\n if (collectMetricByString(\"v\")) {\n page.viewport_width =\n Math.max(documentElement[clientWidth] || 0, window.innerWidth || 0) ||\n null;\n page.viewport_height =\n Math.max(\n documentElement[clientHeight] || 0,\n window.innerHeight || 0\n ) || null;\n }\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n // sc = screensizes\n if (screen && collectMetricByString(\"sc\")) {\n page.screen_width = screen.width;\n page.screen_height = screen.height;\n }\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n var currentReferrerHostname = referrer\n ? referrer.split(slash)[0]\n : undefinedVar;\n sameSite = referrer\n ? nonUniqueHostnames.indexOf(currentReferrerHostname) > -1 ||\n currentReferrerHostname == locationHostname\n : falseVar;\n\n // We set unique variable based on pushstate or back navigation, if no match we check the referrer\n page.unique =\n /__cf_/.test(getReferrer()) || isPushState || userNavigated\n ? falseVar\n : !sameSite;\n\n metadata = appendMetadata(metadata, {\n type: pageviewText,\n path: page.path,\n });\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n var delSrc =\n isPushState || userNavigated || !collectMetricByString(\"r\");\n sendPageView(\n isPushState,\n delSrc, // r = referrers\n sameSite,\n querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar,\n metadata,\n callback\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n /////////////////////\n // AUTOMATED PAGE VIEW COLLECTION\n //\n\n var his = window.history;\n var hisPushState = his ? his.pushState : undefinedVar;\n var dis = window.dispatchEvent;\n var pushStateText = \"pushState\";\n\n // Overwrite history pushState function to\n // allow listening on the pushState event\n if (autoCollect && hisPushState && Event && dis) {\n var stateListener = function (type) {\n var orig = his[type];\n return function () {\n var arg = arguments;\n var rv = orig.apply(this, arg);\n var event;\n if (isFunction(Event)) {\n event = new Event(type);\n } else {\n // Fix for IE\n // https://github.com/simpleanalytics/scripts/issues/8\n event = doc.createEvent(\"Event\");\n event.initEvent(type, trueVar, trueVar);\n }\n event.arguments = arg;\n dis(event);\n return rv;\n };\n };\n\n his.pushState = stateListener(pushStateText);\n\n addEventListenerFunc(\n pushStateText,\n function () {\n pageview(1);\n },\n falseVar\n );\n\n addEventListenerFunc(\n \"popstate\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n // When in hash mode, we record a pageview based on the onhashchange function\n if (autoCollect && mode == \"hash\" && \"onhashchange\" in window) {\n addEventListenerFunc(\n \"hashchange\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n if (autoCollect) pageview();\n\n window.sa_pageview = function (path, metadata, callback) {\n pageview(0, path, metadata, callback);\n };\n\n\n /////////////////////\n // EVENTS\n //\n\n var validTypes = [\"string\", \"number\"];\n\n var sendEvent = function (event, metadata, callbackRaw) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n\n var eventIsFunction = isFunction(event);\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var eventType = typeof event;\n\n if (validTypes.indexOf(eventType) < 0 && !eventIsFunction) {\n warnInFunction(eventFunctionName, eventText + \" can't be \" + eventType);\n return callback();\n }\n\n try {\n if (eventIsFunction) {\n var eventOutput = event();\n if (validTypes.indexOf(typeof eventOutput) < 0) {\n warnInFunction(\n eventFunctionName,\n event + \" returns no string: \" + eventOutput\n );\n return callback();\n }\n event = eventOutput;\n }\n } catch (error) {\n warnInFunction(eventFunctionName, error);\n return callback();\n }\n\n event = (\"\" + event).replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_|_$)/g, \"\");\n\n var eventParams = { type: eventText, event: event };\n var firstPage = !userNavigated && pages < 2;\n\n metadata = appendMetadata(metadata, eventParams);\n\n if (event) {\n sendData(\n assign(eventParams, {\n id: uuid(),\n query: getQueryParams(!firstPage),\n referrer:\n (firstPage || sameSite) && collectMetricByString(\"r\")\n ? previousReferrer\n : null,\n\n metadata: stringify(metadata),\n }),\n callback\n );\n }\n };\n\n var defaultEventFunc = function (event, metadata, callback) {\n sendEvent(event, metadata, callback);\n };\n\n // Set default function if user didn't define a function\n if (!window[eventFunctionName])\n window[eventFunctionName] = defaultEventFunc;\n\n var eventFunc = window[eventFunctionName];\n\n // Read queue of the user defined function\n var queue = eventFunc && eventFunc.q ? eventFunc.q : [];\n\n // Overwrite user defined function\n window[eventFunctionName] = defaultEventFunc;\n\n // Post events from the queue of the user defined function\n for (var event in queue) {\n if (hasProp(queue, event)) {\n Array.isArray(queue[event])\n ? sendEvent.apply(null, queue[event])\n : sendEvent(queue[event]);\n }\n }\n } catch (e) {\n sendError(e);\n }\n})(\n window,\n {},\n \"simpleanalyticscdn.com\",\n \"queue.\",\n \"cdn_latest_12\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","sendError","warn","undefinedVar","undefined","trueVar","falseVar","trueText","https","pageviewText","eventText","errorText","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","notSendingWhen","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","protocol","documentElement","language","Height","scroll","uaData","userAgentData","scrollHeight","offsetHeight","clientHeight","pagehide","platformText","platformVersionText","docsUrl","pages","isBotAgent","test","screen","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","warnInFunction","name","error","hasProp","obj","prop","Object","hasOwnProperty","isString","string","filterRegex","item","replace","attr","attribute","getAttribute","convertCommaSeparatedToArray","csv","Array","isArray","length","split","isObject","object","constructor","assign","to","arg","index","nextSource","nextKey","settings","sa_settings","logSettings","keys","ignoreMetrics","collectMetricByString","metricAbbreviation","filter","RegExp","now","Date","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","c","getRandomValues","Uint8Array","toString","r","Math","random","isFunction","func","namespaceText","namespace","appendMetadata","metadata","data","metadataObject","metadataCollectorFunction","metadataCollector","strictUtm","getQueryParams","ignoreSource","overwriteSearch","search","keyValue","ignore","paramsRegexList","allowParams","map","join","regex","loadedVariable","sa_event_loaded","sendData","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","image","Image","onerror","onload","src","key","overwrittenHostname","hostname","definedHostname","basePayload","version","errorOrMessage","stack","type","path","pathname","event","filename","indexOf","message","timezone","start","scrolled","mode","collectDnt","value","autoCollect","eventFunctionName","saGlobal","ignorePages","nonUniqueHostnames","pathOverwriter","Intl","DateTimeFormat","resolvedOptions","timeZone","phantom","bot","webdriver","__nightmare","callPhantom","_phantom","solana","__polypane","_bot","collectDataOnLeave","ua","page_id","session_id","sri","mobile","brands","doctype","hostname_original","lastSendPath","hiddenStart","getReferrer","referrer","msHidden","sendOnLeave","id","push","append","original_id","duration","round","max","position","sendBeacon","bind","e","hidden","body","documentClientHeight","height","min","scrollTop","previousReferrer","sameSite","userNavigated","getPath","overwrite","pathOverwriterFunction","i","ignorePageRaw","ignorePage","shouldIgnore","hash","pageview","isPushState","pathOverwrite","callbackRaw","querySearch","parts","shift","viewport_width","innerWidth","viewport_height","innerHeight","screen_width","width","screen_height","performaceEntryType","perf","performance","navigationText","getEntriesByType","currentReferrerHostname","unique","triggerSendPageView","delSrc","deleteSourceInfo","query","currentPage","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","his","history","hisPushState","pushState","dis","dispatchEvent","pushStateText","Event","orig","rv","this","createEvent","initEvent","sa_pageview","validTypes","sendEvent","eventIsFunction","eventType","eventOutput","eventParams","firstPage","defaultEventFunc","eventFunc","queue","q"],"mappings":"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"} \ No newline at end of file diff --git a/dist/v12/auto-events.js b/dist/v12/auto-events.js new file mode 100644 index 00000000..410b2bc3 --- /dev/null +++ b/dist/v12/auto-events.js @@ -0,0 +1,4 @@ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; 7048; SRI-version; v12) */ + +function r(t,e){var a,n;t.hasAttribute("data-simple-event")||(a=!1,h.downloads&&/^https?:\/\//i.test(t.href)&&new RegExp("\\.("+(h.downloadsExtensions||[]).join("|")+")$","i").test(t.pathname)?a="download":h.outbound&&/^https?:\/\//i.test(t.href)&&t.hostname!==m.location.hostname?a="outbound":h.emails&&/^mailto:/i.test(t.href)&&(a="email"),a&&(e?(n="saAutomatedLink(this, '"+a+"');",t.hasAttribute("target")&&"_self"!==t.getAttribute("target")||(n+=" return false;"),t.setAttribute("onclick",n)):t.addEventListener("click",function(){g(t,a)})))}function e(){try{for(var t=document.getElementsByTagName("a"),e=0;e -1,\n emails: collectTypes.indexOf(\"emails\") > -1,\n downloads: collectTypes.indexOf(\"downloads\") > -1,\n // Downloads: enter file extensions you want to collect\n downloadsExtensions: setting(\"extensions\", \"array\", [\n \"pdf\",\n \"csv\",\n \"docx\",\n \"xlsx\",\n \"zip\",\n \"doc\",\n \"xls\",\n ]),\n\n // All: use title attribute if set for event name (for all events)\n // THIS TAKES PRECEDENCE OVER OTHER SETTINGS BELOW\n title: setting(\"useTitle\", \"bool\", true),\n // Outbound: use full URL of the links? false for just the hostname\n outboundFullUrl: fullUrls,\n // Downloads: if taking event name from URL, use full URL or just filename (default)\n downloadsFullUrl: fullUrls,\n };\n\n var saGlobal = setting(\"saGlobal\", \"string\", \"sa_event\");\n\n // For compiling the script\n var optionsLink = options;\n\n if (typeof optionsLink === \"undefined\")\n log(\"options object not found, please specify\", \"warn\");\n\n var saAutomatedLink = function saAutomatedLink(element, type) {\n try {\n if (!element) return log(\"no element found\");\n var sent = false;\n\n var callback = function () {\n if (!sent && !element.hasAttribute(\"target\"))\n document.location = element.getAttribute(\"href\");\n sent = true;\n };\n\n if (window[saGlobal] && window[saGlobal + \"_loaded\"]) {\n var hostname = element.hostname;\n var pathname = element.pathname;\n\n var event;\n var metadata = {\n title: element.getAttribute(\"title\") || undefined,\n };\n var url = element.href || undefined;\n\n var useTitle = false;\n if (optionsLink.title && element.hasAttribute(\"title\")) {\n var theTitle = element.getAttribute(\"title\").trim();\n if (theTitle != \"\") useTitle = true;\n }\n\n if (useTitle) {\n event = theTitle;\n } else {\n switch (type) {\n case \"outbound\": {\n event = hostname + (optionsLink.outboundFullUrl ? pathname : \"\");\n metadata.url = url;\n break;\n }\n case \"download\": {\n event = optionsLink.downloadsFullUrl\n ? hostname + pathname\n : pathname.split(\"/\").pop();\n metadata.url = url;\n break;\n }\n case \"email\": {\n var href = element.getAttribute(\"href\");\n event = (href.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.email = event;\n break;\n }\n }\n }\n\n var clean =\n type +\n \"_\" +\n event.replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_+|_+$)/g, \"\");\n\n window[saGlobal](clean, metadata, callback);\n\n log(\"collected \" + clean);\n\n return type === \"email\"\n ? callback()\n : window.setTimeout(callback, 5000);\n } else {\n log(saGlobal + \" is not defined\", \"warn\");\n return callback();\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n };\n\n window.saAutomatedLink = saAutomatedLink;\n\n function collectLink(link, onclick) {\n if (link.hasAttribute(\"data-simple-event\")) return;\n var collect = false;\n\n // Collect download clicks\n if (\n optionsLink.downloads &&\n /^https?:\\/\\//i.test(link.href) &&\n new RegExp(\n \"\\\\.(\" + (optionsLink.downloadsExtensions || []).join(\"|\") + \")$\",\n \"i\"\n ).test(link.pathname)\n ) {\n collect = \"download\";\n\n // Collect outbound links clicks\n } else if (\n optionsLink.outbound &&\n /^https?:\\/\\//i.test(link.href) &&\n link.hostname !== window.location.hostname\n ) {\n collect = \"outbound\";\n\n // Collect email clicks\n } else if (optionsLink.emails && /^mailto:/i.test(link.href)) {\n collect = \"email\";\n }\n\n if (!collect) return;\n\n if (onclick) {\n var onClickAttribute = \"saAutomatedLink(this, '\" + collect + \"');\";\n\n if (\n !link.hasAttribute(\"target\") ||\n link.getAttribute(\"target\") === \"_self\"\n )\n onClickAttribute += \" return false;\";\n\n link.setAttribute(\"onclick\", onClickAttribute);\n } else {\n link.addEventListener(\"click\", function () {\n saAutomatedLink(link, collect);\n });\n }\n }\n\n function onDOMContentLoaded() {\n try {\n var a = document.getElementsByTagName(\"a\");\n\n // Loop over all links on the page\n for (var i = 0; i < a.length; i++) {\n var link = a[i];\n var href = link.getAttribute(\"href\");\n\n // Skip links that don't have an href\n if (!href) continue;\n\n // We don't want to overwrite website behaviour so we check for the onclick attribute\n if (!link.getAttribute(\"onclick\") && !/^mailto:/.test(href)) {\n collectLink(link, true);\n } else {\n collectLink(link, false);\n }\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n }\n\n if (doc.readyState === \"ready\" || doc.readyState === \"complete\") {\n onDOMContentLoaded();\n } else {\n document.addEventListener(\"readystatechange\", function (event) {\n if (event.target.readyState === \"complete\") onDOMContentLoaded();\n });\n }\n})(window);\n"],"names":["collectLink","link","onclick","collect","onClickAttribute","hasAttribute","optionsLink","downloads","test","href","RegExp","downloadsExtensions","join","pathname","outbound","hostname","window","location","emails","getAttribute","setAttribute","addEventListener","saAutomatedLink","onDOMContentLoaded","a","document","getElementsByTagName","i","length","error","log","message","doc","scriptElement","setting","collectTypes","fullUrls","options","saGlobal","type","logger","console","warn","info","currentScript","querySelector","attribute","defaultValue","value","dataset","split","map","item","trim","filter","Boolean","indexOf","title","outboundFullUrl","downloadsFullUrl","element","sent","callback","theTitle","metadata","undefined","url","useTitle","event","pop","email","clean","replace","setTimeout","readyState","target"],"mappings":"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"} \ No newline at end of file diff --git a/dist/v12/custom/app.js b/dist/v12/custom/app.js new file mode 100644 index 00000000..6dbb1336 --- /dev/null +++ b/dist/v12/custom/app.js @@ -0,0 +1,4 @@ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; af71; SRI-version; v12) */ + +!function(d,t,e,n,m){try{var g=undefined,v=!0,y=!1,r="true",a="https:",_="pageview",u="event",i="error",o=d.console,c="doNotTrack",w=d.navigator,s=d.location,b=s.host,l=d.document,p=w.userAgent,f="Not sending request ",h=f+"when ",O=y,E=encodeURIComponent,x=decodeURIComponent,S=JSON.stringify,M=d.addEventListener,k="https://"+e,A=l.documentElement||{},q="language",$="Height",j="scroll",D=w.userAgentData,C=j+$,H="offset"+$,R="client"+$,P="pagehide",T="platform",U="platformVersion",I="https://docs.simpleanalytics.com",V=0,B=/(bot|spider|crawl)/i.test(p)&&!/(cubot)/i.test(p),N=d.screen,z=l.currentScript||l.querySelector('script[src*="'+e+'"]');m=function(){var t=[].slice.call(arguments);return t.unshift("Simple Analytics:"),Function.prototype.apply.call(o.warn,o,t)};var F=function(t,e){m("Error in your "+t+" function:",e)},W=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},G=function(t){return"string"==typeof t},J=function(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},L=function(t,e){return t&&t.getAttribute("data-"+e)},Y=function(t){return Array.isArray(t)?t:G(t)&&t.length?t.split(/, ?/):[]},Z=function(t){return t&&t.constructor===Object},K=function(){for(var t={},e=arguments,n=0;n>t/4).toString(16)})}catch(r){return t.replace(n,function(t){var e=16*Math.random()|0;return(t<2?e:3&e|8).toString(16)})}},at=function(t){return"function"==typeof t},it="namespace",ot=t[it]||L(z,it)||"sa",ct=function(t,e){var n=d[ot+"_metadata"];Z(n)&&(t=K(t,n));var r=d[Mt];if(!at(r))return Mt&&m(Mt+" not found, set window."+Mt),t;try{return K(t,r.call(d,K(t,e)))}catch(a){F("metadata",a)}},st=t.strictUtm||L(z,"strict-utm")==r,ut=function(a,t){return(t||s.search).slice(1).split("&").filter(function(t){var e=a||!et("ut"),n=Et.map(J).join("|"),r=e?"^("+n+")=":"^((utm_)"+(st?"":"?")+"(source|medium|content|term|campaign)"+(st?"":"|ref")+"|"+n+")=";return e&&!Et.length?y:new RegExp(r).test(t)}).join("&")||g},lt=ot+"_loaded";if(d[lt]==v)return m(f+"twice");d.sa_event_loaded=v,d[lt]=v;var pt=function(e,t,n){e=n?e:K($t,Ct,e),w.brave&&!n&&(e.brave=v),w._duckduckgoloader_&&!n&&(e.duck=v);var r=new Image;t&&(r.onerror=t,r.onload=t),r.src=k+"/simple.gif?"+Object.keys(e).filter(function(t){return e[t]!=g}).map(function(t){return E(t)+"="+E(e[t])}).join("&")+"&time="+Date.now()},ft=t.hostname||L(z,"hostname"),ht=ft||b,dt={version:"custom_app_12",hostname:ht};n=function(t){t=t.stack?t+" "+t.stack:t,m(t),pt(K(dt,{type:i,error:t,path:s.pathname}),g,v)},M(i,function(t){t.filename&&-1"); +//# sourceMappingURL=app.js.map \ No newline at end of file diff --git a/dist/v12/custom/app.js.map b/dist/v12/custom/app.js.map new file mode 100644 index 00000000..c66414f9 --- /dev/null +++ b/dist/v12/custom/app.js.map @@ -0,0 +1 @@ +{"version":3,"file":"app.source.js","sources":["app.source.js"],"sourcesContent":["/* eslint-env browser */\n\n(function (\n window,\n overwriteOptions,\n baseUrl,\n apiUrlPrefix,\n version,\n defaultNamespace,\n sendError,\n warn\n) {\n try {\n /////////////////////\n // PREDEFINED VARIABLES FOR BETTER MINIFICATION\n //\n\n // This seems like a lot of repetition, but it makes our script available for\n // multple destination which prevents us to need multiple scripts. The minified\n // version stays small.\n var undefinedVar = undefined;\n var trueVar = true;\n var falseVar = false;\n var trueText = \"true\";\n var https = \"https:\";\n var pageviewText = \"pageview\";\n var eventText = \"event\";\n var errorText = \"error\";\n var slash = \"/\";\n var protocol = https + \"//\";\n var con = window.console;\n var doNotTrack = \"doNotTrack\";\n var nav = window.navigator;\n var loc = window.location;\n var locationHostname = loc.host;\n var doc = window.document;\n var userAgent = nav.userAgent;\n var notSending = \"Not sending request \";\n var notSendingWhen = notSending + \"when \";\n var fetchedHighEntropyValues = falseVar;\n var encodeURIComponentFunc = encodeURIComponent;\n var decodeURIComponentFunc = decodeURIComponent;\n var stringify = JSON.stringify;\n var thousand = 1000;\n var addEventListenerFunc = window.addEventListener;\n var fullApiUrl = protocol + apiUrlPrefix + baseUrl;\n var documentElement = doc.documentElement || {};\n var language = \"language\";\n var Height = \"Height\";\n var Width = \"Width\";\n var scroll = \"scroll\";\n var uaData = nav.userAgentData;\n var scrollHeight = scroll + Height;\n var offsetHeight = \"offset\" + Height;\n var clientHeight = \"client\" + Height;\n var clientWidth = \"client\" + Width;\n var pagehide = \"pagehide\";\n var platformText = \"platform\";\n var platformVersionText = \"platformVersion\";\n var docsUrl = \"https://docs.simpleanalytics.com\";\n var pages = 0;\n var isBotAgent =\n /(bot|spider|crawl)/i.test(userAgent) && !/(cubot)/i.test(userAgent);\n var screen = window.screen;\n\n\n // Find the script element where options can be set on\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"' + baseUrl + '\"]');\n\n /////////////////////\n // HELPER FUNCTIONS\n //\n\n // A simple log function so the user knows why a request is not being send\n warn = function () {\n // 1. Convert args to a normal array\n var args = [].slice.call(arguments);\n\n // 2. Prepend log prefix\n args.unshift(\"Simple Analytics:\");\n\n // 3. Pass along arguments to console.warn\n // Function.prototype.apply.call is needed for Internet Explorer\n return Function.prototype.apply.call(con.warn, con, args);\n };\n\n var warnInFunction = function (name, error) {\n warn(\"Error in your \" + name + \" function:\", error);\n };\n\n var hasProp = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n\n var isString = function (string) {\n return typeof string == \"string\";\n };\n\n var filterRegex = function (item) {\n return item.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n var attr = function (scriptElement, attribute) {\n return scriptElement && scriptElement.getAttribute(\"data-\" + attribute);\n };\n\n var convertCommaSeparatedToArray = function (csv) {\n return Array.isArray(csv)\n ? csv\n : isString(csv) && csv.length\n ? csv.split(/, ?/)\n : [];\n };\n\n var isObject = function (object) {\n return object && object.constructor === Object;\n };\n\n var assign = function () {\n var to = {};\n var arg = arguments;\n for (var index = 0; index < arg.length; index++) {\n var nextSource = arg[index];\n if (isObject(nextSource)) {\n for (var nextKey in nextSource) {\n if (hasProp(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n\n var settings = window.sa_settings;\n var logSettings = settings || Object.keys(overwriteOptions).length;\n\n // Merge overwriteOptions with sa_settings\n overwriteOptions = assign(overwriteOptions, settings);\n\n if (logSettings) warn(\"Settings\", overwriteOptions);\n\n // Customers can skip data points\n var ignoreMetrics = convertCommaSeparatedToArray(\n overwriteOptions.ignoreMetrics || attr(scriptElement, \"ignore-metrics\")\n );\n\n var collectMetricByString = function (metricAbbreviation) {\n // Can't use Array.find() here because we need to support IE9\n return (\n ignoreMetrics.filter(function (item) {\n return new RegExp(\"^\" + metricAbbreviation).test(item);\n }).length === 0\n );\n };\n\n var now = Date.now;\n\n var uuid = function () {\n var cryptoObject = window.crypto || window.msCrypto;\n var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;\n var uuidRegex = /[018]/g;\n\n try {\n return emptyUUID.replace(uuidRegex, function (c) {\n return (\n c ^\n (cryptoObject.getRandomValues(new Uint8Array(1))[0] &\n (15 >> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n var appendMetadata = function (metadata, data) {\n var metadataObject = window[namespace + \"_metadata\"];\n if (isObject(metadataObject)) metadata = assign(metadata, metadataObject);\n var metadataCollectorFunction = window[metadataCollector];\n if (!isFunction(metadataCollectorFunction)) {\n if (metadataCollector)\n warn(\n metadataCollector + \" not found, set window.\" + metadataCollector\n );\n return metadata;\n }\n try {\n return assign(\n metadata,\n metadataCollectorFunction.call(window, assign(metadata, data))\n );\n } catch (error) {\n warnInFunction(\"metadata\", error);\n }\n };\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource, overwriteSearch) {\n return (\n (overwriteSearch || loc.search)\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n var paramsRegexList = allowParams.map(filterRegex).join(\"|\");\n var regex = ignore\n ? \"^(\" + paramsRegexList + \")=\"\n : \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \"|\" +\n paramsRegexList +\n \")=\";\n if (ignore && !allowParams.length) return falseVar;\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n // Ignore pages specified in data-ignore-pages\n var shouldIgnore = function (path) {\n for (var i in ignorePages) {\n var ignorePageRaw = ignorePages[i];\n if (!ignorePageRaw) continue;\n\n // Prepend a slash when it's missing\n var ignorePage =\n ignorePageRaw[0] == slash ? ignorePageRaw : slash + ignorePageRaw;\n\n if (\n ignorePage === path ||\n new RegExp(\n \"^\" + filterRegex(ignorePage).replace(/\\\\\\*/gi, \"(.*)\") + \"$\",\n \"i\"\n ).test(path)\n )\n return trueVar;\n }\n return falseVar;\n };\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n if (callback) {\n image.onerror = callback;\n image.onload = callback;\n }\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n /////////////////////\n // ERROR FUNCTIONS\n //\n\n // Send errors\n // no var because it's scoped outside of the try/catch\n sendError = function (errorOrMessage) {\n errorOrMessage = errorOrMessage.stack\n ? errorOrMessage + \" \" + errorOrMessage.stack\n : errorOrMessage;\n warn(errorOrMessage);\n sendData(\n assign(basePayload, {\n type: errorText,\n error: errorOrMessage,\n path: loc.pathname,\n }),\n undefinedVar,\n trueVar\n );\n };\n\n // We listen for the error events and only send errors that are\n // from our script (checked by filename) to our server.\n addEventListenerFunc(\n errorText,\n function (event) {\n if (event.filename && event.filename.indexOf(baseUrl) > -1) {\n sendError(event.message);\n }\n },\n falseVar\n );\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n var start = now();\n\n var scrolled = 0;\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n // Should we record Do Not Track visits?\n var collectDnt = isBoolean(overwriteOptions.collectDnt)\n ? overwriteOptions.collectDnt\n : attr(scriptElement, \"ignore-dnt\") == trueText ||\n attr(scriptElement, \"skip-dnt\") == trueText ||\n attr(scriptElement, \"collect-dnt\") == trueText;\n\n // Some customers want to collect page views manually\n var autoCollect = !(\n attr(scriptElement, \"auto-collect\") == \"false\" ||\n overwriteOptions.autoCollect === falseVar\n );\n\n // Event function name\n var eventFunctionName =\n overwriteOptions.saGlobal ||\n attr(scriptElement, \"sa-global\") ||\n namespace + \"_\" + eventText;\n\n // Customers can ignore certain pages\n var ignorePages = convertCommaSeparatedToArray(\n overwriteOptions.ignorePages || attr(scriptElement, \"ignore-pages\")\n );\n\n // Customers can allow params\n var allowParams = convertCommaSeparatedToArray(\n overwriteOptions.allowParams || attr(scriptElement, \"allow-params\")\n );\n\n // Customers can allow params\n var nonUniqueHostnames = convertCommaSeparatedToArray(\n overwriteOptions.nonUniqueHostnames ||\n attr(scriptElement, \"non-unique-hostnames\")\n );\n\n // Customers can overwrite certain values\n var pathOverwriter =\n overwriteOptions.pathOverwriter || attr(scriptElement, \"path-overwriter\");\n\n // Customers can add metadata to events and pageviews via a function\n var metadataCollector =\n overwriteOptions.metadataCollector ||\n attr(scriptElement, \"metadata-collector\");\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var phantom = window.phantom;\n var bot =\n nav.webdriver ||\n window.__nightmare ||\n window.callPhantom ||\n window._phantom ||\n (phantom && !phantom.solana) ||\n window.__polypane ||\n window._bot ||\n isBotAgent ||\n Math.random() == Math.random();\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = trueVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n // Warn when no document.doctype is defined (this breaks some documentElement dimensions)\n if (!doc.doctype) warn(\"Add DOCTYPE html for accurate dimensions\");\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (!collectDnt && doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n // Customers can overwrite their referrer, here we check for that\n var overwrittenReferrer =\n overwriteOptions.referrer || attr(scriptElement, \"referrer\");\n\n return (\n (overwrittenReferrer || doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n // t = timeonpage\n if (collectMetricByString(\"t\")) {\n append.duration = Math.round((now() - start - msHidden) / thousand);\n }\n msHidden = 0;\n start = now();\n\n // scro = scrolled\n if (collectMetricByString(\"scro\")) {\n append.scrolled = Math.max(0, scrolled, position());\n }\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n try {\n nav.sendBeacon.bind(nav)(fullApiUrl + \"/append\", stringify(append));\n } catch (e) {\n // Fallback for browsers throwing \"Illegal invocation\" when the URL is invalid\n sendData(append, undefinedVar, trueVar);\n }\n }\n };\n\n var hiddenStart;\n addEventListenerFunc(\n \"visibilitychange\",\n function () {\n if (doc.hidden) {\n if (!(\"on\" + pagehide in window)) sendOnLeave();\n hiddenStart = now();\n } else msHidden += now() - hiddenStart;\n },\n falseVar\n );\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n var body = doc.body || {};\n var position = function () {\n try {\n var documentClientHeight = documentElement[clientHeight] || 0;\n var height = Math.max(\n body[scrollHeight] || 0,\n body[offsetHeight] || 0,\n documentElement[clientHeight] || 0,\n documentElement[scrollHeight] || 0,\n documentElement[offsetHeight] || 0\n );\n return Math.min(\n 100,\n Math.round(\n (100 * ((documentElement.scrollTop || 0) + documentClientHeight)) /\n height /\n 5\n ) * 5\n );\n } catch (error) {\n warn(error);\n return 0;\n }\n };\n\n addEventListenerFunc(\"load\", function () {\n scrolled = position();\n addEventListenerFunc(\n scroll,\n function () {\n if (scrolled < position()) scrolled = position();\n },\n falseVar\n );\n });\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n var pathOverwriterFunction = window[pathOverwriter];\n if (isFunction(pathOverwriterFunction)) {\n try {\n path = pathOverwriterFunction.call(window, { path: path }) || path;\n } catch (error) {\n warnInFunction(\"path\", error);\n }\n }\n\n // Ignore pages specified in data-ignore-pages\n if (shouldIgnore(path)) {\n warn(notSendingWhen + \"ignoring \" + path);\n return;\n }\n\n // Add hash to path when script is put in to hash mode\n if (mode == \"hash\" && loc.hash) path += loc.hash.split(\"?\")[0];\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n query,\n metadata,\n callback\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData(\n {\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: query || getQueryParams(deleteSourceInfo),\n\n metadata: stringify(metadata),\n },\n callback\n );\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (\n isPushState,\n pathOverwrite,\n metadata,\n callbackRaw\n ) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var querySearch;\n if (isString(pathOverwrite) && pathOverwrite.indexOf(\"?\") > -1) {\n // keep query from manual path\n var parts = pathOverwrite.split(\"?\");\n pathOverwrite = parts.shift();\n querySearch = \"?\" + parts.join(\"?\");\n }\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n // v = viewportsizes\n if (collectMetricByString(\"v\")) {\n page.viewport_width =\n Math.max(documentElement[clientWidth] || 0, window.innerWidth || 0) ||\n null;\n page.viewport_height =\n Math.max(\n documentElement[clientHeight] || 0,\n window.innerHeight || 0\n ) || null;\n }\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n // sc = screensizes\n if (screen && collectMetricByString(\"sc\")) {\n page.screen_width = screen.width;\n page.screen_height = screen.height;\n }\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n var currentReferrerHostname = referrer\n ? referrer.split(slash)[0]\n : undefinedVar;\n sameSite = referrer\n ? nonUniqueHostnames.indexOf(currentReferrerHostname) > -1 ||\n currentReferrerHostname == locationHostname\n : falseVar;\n\n // We set unique variable based on pushstate or back navigation, if no match we check the referrer\n page.unique =\n /__cf_/.test(getReferrer()) || isPushState || userNavigated\n ? falseVar\n : !sameSite;\n\n metadata = appendMetadata(metadata, {\n type: pageviewText,\n path: page.path,\n });\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n var delSrc =\n isPushState || userNavigated || !collectMetricByString(\"r\");\n sendPageView(\n isPushState,\n delSrc, // r = referrers\n sameSite,\n querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar,\n metadata,\n callback\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n /////////////////////\n // AUTOMATED PAGE VIEW COLLECTION\n //\n\n var his = window.history;\n var hisPushState = his ? his.pushState : undefinedVar;\n var dis = window.dispatchEvent;\n var pushStateText = \"pushState\";\n\n // Overwrite history pushState function to\n // allow listening on the pushState event\n if (autoCollect && hisPushState && Event && dis) {\n var stateListener = function (type) {\n var orig = his[type];\n return function () {\n var arg = arguments;\n var rv = orig.apply(this, arg);\n var event;\n if (isFunction(Event)) {\n event = new Event(type);\n } else {\n // Fix for IE\n // https://github.com/simpleanalytics/scripts/issues/8\n event = doc.createEvent(\"Event\");\n event.initEvent(type, trueVar, trueVar);\n }\n event.arguments = arg;\n dis(event);\n return rv;\n };\n };\n\n his.pushState = stateListener(pushStateText);\n\n addEventListenerFunc(\n pushStateText,\n function () {\n pageview(1);\n },\n falseVar\n );\n\n addEventListenerFunc(\n \"popstate\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n // When in hash mode, we record a pageview based on the onhashchange function\n if (autoCollect && mode == \"hash\" && \"onhashchange\" in window) {\n addEventListenerFunc(\n \"hashchange\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n if (autoCollect) pageview();\n\n window.sa_pageview = function (path, metadata, callback) {\n pageview(0, path, metadata, callback);\n };\n\n\n /////////////////////\n // EVENTS\n //\n\n var validTypes = [\"string\", \"number\"];\n\n var sendEvent = function (event, metadata, callbackRaw) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n\n var eventIsFunction = isFunction(event);\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var eventType = typeof event;\n\n if (validTypes.indexOf(eventType) < 0 && !eventIsFunction) {\n warnInFunction(eventFunctionName, eventText + \" can't be \" + eventType);\n return callback();\n }\n\n try {\n if (eventIsFunction) {\n var eventOutput = event();\n if (validTypes.indexOf(typeof eventOutput) < 0) {\n warnInFunction(\n eventFunctionName,\n event + \" returns no string: \" + eventOutput\n );\n return callback();\n }\n event = eventOutput;\n }\n } catch (error) {\n warnInFunction(eventFunctionName, error);\n return callback();\n }\n\n event = (\"\" + event).replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_|_$)/g, \"\");\n\n var eventParams = { type: eventText, event: event };\n var firstPage = !userNavigated && pages < 2;\n\n metadata = appendMetadata(metadata, eventParams);\n\n if (event) {\n sendData(\n assign(eventParams, {\n id: uuid(),\n query: getQueryParams(!firstPage),\n referrer:\n (firstPage || sameSite) && collectMetricByString(\"r\")\n ? previousReferrer\n : null,\n\n metadata: stringify(metadata),\n }),\n callback\n );\n }\n };\n\n var defaultEventFunc = function (event, metadata, callback) {\n sendEvent(event, metadata, callback);\n };\n\n // Set default function if user didn't define a function\n if (!window[eventFunctionName])\n window[eventFunctionName] = defaultEventFunc;\n\n var eventFunc = window[eventFunctionName];\n\n // Read queue of the user defined function\n var queue = eventFunc && eventFunc.q ? eventFunc.q : [];\n\n // Overwrite user defined function\n window[eventFunctionName] = defaultEventFunc;\n\n // Post events from the queue of the user defined function\n for (var event in queue) {\n if (hasProp(queue, event)) {\n Array.isArray(queue[event])\n ? sendEvent.apply(null, queue[event])\n : sendEvent(queue[event]);\n }\n }\n } catch (e) {\n sendError(e);\n }\n})(\n window,\n {},\n \"\",\n \"\",\n \"custom_app_12\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","sendError","warn","undefinedVar","undefined","trueVar","falseVar","trueText","https","pageviewText","eventText","errorText","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","notSendingWhen","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","documentElement","language","Height","scroll","uaData","userAgentData","scrollHeight","offsetHeight","clientHeight","pagehide","platformText","platformVersionText","docsUrl","pages","isBotAgent","test","screen","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","warnInFunction","name","error","hasProp","obj","prop","Object","hasOwnProperty","isString","string","filterRegex","item","replace","attr","attribute","getAttribute","convertCommaSeparatedToArray","csv","Array","isArray","length","split","isObject","object","constructor","assign","to","arg","index","nextSource","nextKey","settings","sa_settings","logSettings","keys","ignoreMetrics","collectMetricByString","metricAbbreviation","filter","RegExp","now","Date","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","c","getRandomValues","Uint8Array","toString","r","Math","random","isFunction","func","namespaceText","namespace","appendMetadata","metadata","data","metadataObject","metadataCollectorFunction","metadataCollector","strictUtm","getQueryParams","ignoreSource","overwriteSearch","search","keyValue","ignore","paramsRegexList","allowParams","map","join","regex","loadedVariable","sa_event_loaded","sendData","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","image","Image","onerror","onload","src","key","overwrittenHostname","hostname","definedHostname","basePayload","version","errorOrMessage","stack","type","path","pathname","event","filename","indexOf","message","timezone","start","scrolled","mode","collectDnt","value","autoCollect","eventFunctionName","saGlobal","ignorePages","nonUniqueHostnames","pathOverwriter","Intl","DateTimeFormat","resolvedOptions","timeZone","phantom","bot","webdriver","__nightmare","callPhantom","_phantom","solana","__polypane","_bot","collectDataOnLeave","ua","protocol","page_id","session_id","sri","mobile","brands","doctype","hostname_original","lastSendPath","hiddenStart","getReferrer","referrer","msHidden","sendOnLeave","id","push","append","original_id","duration","round","max","position","sendBeacon","bind","e","hidden","body","documentClientHeight","height","min","scrollTop","previousReferrer","sameSite","userNavigated","getPath","overwrite","pathOverwriterFunction","i","ignorePageRaw","ignorePage","shouldIgnore","hash","pageview","isPushState","pathOverwrite","callbackRaw","querySearch","parts","shift","viewport_width","innerWidth","viewport_height","innerHeight","screen_width","width","screen_height","performaceEntryType","perf","performance","navigationText","getEntriesByType","currentReferrerHostname","unique","triggerSendPageView","delSrc","deleteSourceInfo","query","currentPage","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","his","history","hisPushState","pushState","dis","dispatchEvent","pushStateText","Event","orig","rv","this","createEvent","initEvent","sa_pageview","validTypes","sendEvent","eventIsFunction","eventType","eventOutput","eventParams","firstPage","defaultEventFunc","eventFunc","queue","q"],"mappings":";;CAEA,SACEA,EACAC,EACAC,EAIAC,EACAC,GAEA,IAQE,IAAIC,EAAeC,UACfC,GAAU,EACVC,GAAW,EACXC,EAAW,OACXC,EAAQ,SACRC,EAAe,WACfC,EAAY,QACZC,EAAY,QAGZC,EAAMd,EAAOe,QACbC,EAAa,aACbC,EAAMjB,EAAOkB,UACbC,EAAMnB,EAAOoB,SACbC,EAAmBF,EAAIG,KACvBC,EAAMvB,EAAOwB,SACbC,EAAYR,EAAIQ,UAChBC,EAAa,uBACbC,EAAiBD,EAAa,QAC9BE,EAA2BpB,EAC3BqB,EAAyBC,mBACzBC,EAAyBC,mBACzBC,EAAYC,KAAKD,UAEjBE,EAAuBnC,EAAOoC,iBAC9BC,EAhBW3B,WAgB4BR,EACvCoC,EAAkBf,EAAIe,iBAAmB,GACzCC,EAAW,WACXC,EAAS,SAETC,EAAS,SACTC,EAASzB,EAAI0B,cACbC,EAAeH,EAASD,EACxBK,EAAe,SAAWL,EAC1BM,EAAe,SAAWN,EAE1BO,EAAW,WACXC,EAAe,WACfC,EAAsB,kBACtBC,EAAU,mCACVC,EAAQ,EACRC,EACF,sBAAsBC,KAAK5B,KAAe,WAAW4B,KAAK5B,GACxD6B,EAAStD,EAAOsD,OAIhBC,EACFhC,EAAIiC,eAAiBjC,EAAIkC,cAAc,gBAAkBvD,EAAU,MAOrEE,EAAO,WAEL,IAAIsD,EAAO,GAAGC,MAAMC,KAAKC,WAOzB,OAJAH,EAAKI,QAAQ,qBAINC,SAASC,UAAUC,MAAML,KAAK9C,EAAIV,KAAMU,EAAK4C,IAGtD,IAAIQ,EAAiB,SAAUC,EAAMC,GACnChE,EAAK,iBAAmB+D,EAAO,aAAcC,IAG3CC,EAAU,SAAUC,EAAKC,GAC3B,OAAOC,OAAOR,UAAUS,eAAeb,KAAKU,EAAKC,IAG/CG,EAAW,SAAUC,GACvB,MAAwB,iBAAVA,GAGZC,EAAc,SAAUC,GAC1B,OAAOA,EAAKC,QAAQ,sBAAuB,SAGzCC,EAAO,SAAUxB,EAAeyB,GAClC,OAAOzB,GAAiBA,EAAc0B,aAAa,QAAUD,IAG3DE,EAA+B,SAAUC,GAC3C,OAAOC,MAAMC,QAAQF,GACjBA,EACAT,EAASS,IAAQA,EAAIG,OACnBH,EAAII,MAAM,OACV,IAGJC,EAAW,SAAUC,GACvB,OAAOA,GAAUA,EAAOC,cAAgBlB,QAGtCmB,EAAS,WAGX,IAFA,IAAIC,EAAK,GACLC,EAAMhC,UACDiC,EAAQ,EAAGA,EAAQD,EAAIP,OAAQQ,IAAS,CAC/C,IAAIC,EAAaF,EAAIC,GACrB,GAAIN,EAASO,GACX,IAAK,IAAIC,KAAWD,EACd1B,EAAQ0B,EAAYC,KACtBJ,EAAGI,GAAWD,EAAWC,IAKjC,OAAOJ,GAGLK,EAAWjG,EAAOkG,YAClBC,EAAcF,GAAYzB,OAAO4B,KAAKnG,GAAkBqF,OAG5DrF,EAAmB0F,EAAO1F,EAAkBgG,GAExCE,GAAa/F,EAAK,WAAYH,GAGlC,IAAIoG,GAAgBnB,EAClBjF,EAAiBoG,eAAiBtB,EAAKxB,EAAe,mBAGpD+C,GAAwB,SAAUC,GAEpC,OAGgB,IAFdF,GAAcG,OAAO,SAAU3B,GAC7B,OAAO,IAAI4B,OAAO,IAAMF,GAAoBlD,KAAKwB,KAChDS,QAIHoB,GAAMC,KAAKD,IAEXE,GAAO,WACT,IAAIC,EAAe7G,EAAO8G,QAAU9G,EAAO+G,SACvCC,EAAY,CAAC,MAAQ,KAAO,KAAO,KAAO,KAC1CC,EAAY,SAEhB,IACE,OAAOD,EAAUlC,QAAQmC,EAAW,SAAUC,GAC5C,OACEA,EACCL,EAAaM,gBAAgB,IAAIC,WAAW,IAAI,GAC9C,IAAOF,EAAI,GACdG,SAAS,MAEb,MAAOjD,GACP,OAAO4C,EAAUlC,QAAQmC,EAAW,SAAUC,GAC5C,IAAII,EAAqB,GAAhBC,KAAKC,SAAiB,EAE/B,OADMN,EAAI,EAAII,EAAS,EAAJA,EAAW,GACrBD,SAAS,QAKpBI,GAAa,SAAUC,GACzB,MAAsB,mBAARA,GAIZC,GAAgB,YAChBC,GACF3H,EAAiB0H,KACjB5C,EAAKxB,EAAeoE,KAuxBxB,KApxBME,GAAiB,SAAUC,EAAUC,GACvC,IAAIC,EAAiBhI,EAAO4H,GAAY,aACpCpC,EAASwC,KAAiBF,EAAWnC,EAAOmC,EAAUE,IAC1D,IAAIC,EAA4BjI,EAAOkI,IACvC,IAAKT,GAAWQ,GAKd,OAJIC,IACF9H,EACE8H,GAAoB,0BAA4BA,IAE7CJ,EAET,IACE,OAAOnC,EACLmC,EACAG,EAA0BrE,KAAK5D,EAAQ2F,EAAOmC,EAAUC,KAE1D,MAAO3D,GACPF,EAAe,WAAYE,KAU3B+D,GACFlI,EAAiBkI,WACjBpD,EAAKxB,EAAe,eAAiB9C,EAEnC2H,GAAiB,SAAUC,EAAcC,GAC3C,OACGA,GAAmBnH,EAAIoH,QACrB5E,MAAM,GACN4B,MAAM,KACNiB,OAAO,SAAUgC,GAChB,IAAIC,EAASJ,IAAiB/B,GAAsB,MAEhDoC,EAAkBC,GAAYC,IAAIhE,GAAaiE,KAAK,KACpDC,EAAQL,EACR,KAAOC,EAAkB,KACzB,YACCP,GAAY,GAAK,KAClB,yCACCA,GAAY,GAAK,QAClB,IACAO,EACA,KACJ,OAAID,IAAWE,GAAYrD,OAAe9E,EAInC,IAAIiG,OAAOqC,GAAOzF,KAAKmF,KAE/BK,KAAK,MAAQxI,GAgChB0I,GAAiBnB,GAAY,UACjC,GAAI5H,EAAO+I,KAAmBxI,EAAS,OAAOH,EAAKsB,EAAa,SAChE1B,EAAOgJ,gBAAkBzI,EACzBP,EAAO+I,IAAkBxI,EAOzB,IAAI0I,GAAW,SAAUlB,EAAMmB,EAAUC,GACvCpB,EAAOoB,EAAepB,EAAOpC,EAAOyD,GAASC,GAAMtB,GAE/C9G,EAAIqI,QAAUH,IAAcpB,EAAKuB,MAAQ/I,GACzCU,EAAIsI,qBAAuBJ,IAAcpB,EAAKyB,KAAOjJ,GAGzD,IAAIkJ,EAAQ,IAAIC,MACZR,IACFO,EAAME,QAAUT,EAChBO,EAAMG,OAASV,GAEjBO,EAAMI,IACJxH,EACA,eACAmC,OAAO4B,KAAK2B,GACTvB,OAAO,SAAUsD,GAChB,OAAO/B,EAAK+B,IAAQzJ,IAErBuI,IAAI,SAAUkB,GACb,OACEjI,EAAuBiI,GACvB,IACAjI,EAAuBkG,EAAK+B,MAG/BjB,KAAK,KACR,SACAlC,KAAKD,OAILqD,GACF9J,EAAiB+J,UAAYjF,EAAKxB,EAAe,YAC/C0G,GAAkBF,IAAuB1I,EAEzC6I,GAAc,CAChBC,QA6oBJ,gBA5oBIH,SAAUC,IASZ9J,EAAY,SAAUiK,GACpBA,EAAiBA,EAAeC,MAC5BD,EAAiB,IAAMA,EAAeC,MACtCD,EACJhK,EAAKgK,GACLnB,GACEtD,EAAOuE,GAAa,CAClBI,KAAMzJ,EACNuD,MAAOgG,EACPG,KAAMpJ,EAAIqJ,WAEZnK,EACAE,IAMJ4B,EACEtB,EACA,SAAU4J,GACJA,EAAMC,WAA+C,EAAnCD,EAAMC,SAASC,QAAQzK,IAC3CC,EAAUsK,EAAMG,UAGpBpK,GAOF,IAwDIqK,GAxDAC,GAAQpE,KAERqE,GAAW,EAOXC,GAAO/K,EAAiB+K,MAAQjG,EAAKxB,EAAe,QAGpD0H,MAvKsBC,GAuKCjL,EAAiBgL,cAtKvBC,GAuKjBjL,EAAiBgL,WACjBlG,EAAKxB,EAAe,eAAiB9C,GACrCsE,EAAKxB,EAAe,aAAe9C,GACnCsE,EAAKxB,EAAe,gBAAkB9C,EAGtC0K,KACqC,SAAvCpG,EAAKxB,EAAe,iBACpBtD,EAAiBkL,cAAgB3K,GAI/B4K,GACFnL,EAAiBoL,UACjBtG,EAAKxB,EAAe,cACpBqE,GAAY,IAAMhH,EAGhB0K,GAAcpG,EAChBjF,EAAiBqL,aAAevG,EAAKxB,EAAe,iBAIlDoF,GAAczD,EAChBjF,EAAiB0I,aAAe5D,EAAKxB,EAAe,iBAIlDgI,GAAqBrG,EACvBjF,EAAiBsL,oBACfxG,EAAKxB,EAAe,yBAIpBiI,GACFvL,EAAiBuL,gBAAkBzG,EAAKxB,EAAe,mBAGrD2E,GACFjI,EAAiBiI,mBACjBnD,EAAKxB,EAAe,sBAItB,IAEEsH,GAAWvE,GAAsB,KAC7BmF,KAAKC,iBAAiBC,kBAAkBC,SACxCvL,EACJ,MAAO+D,IACPhE,EAAKgE,IAOP,IAAIyH,GAAU7L,EAAO6L,QACjBC,GACF7K,EAAI8K,WACJ/L,EAAOgM,aACPhM,EAAOiM,aACPjM,EAAOkM,UACNL,KAAYA,GAAQM,QACrBnM,EAAOoM,YACPpM,EAAOqM,MACPjJ,GACAmE,KAAKC,UAAYD,KAAKC,SAGpB8E,GACFhG,GAAsB,MAAQA,GAAsB,QAElDwF,KAAK5B,GAAY4B,IAAMvL,GAE3B,IAAI6I,GAAUzD,EAAOuE,GAAa,CAEhCqC,GAAIjG,GAAsB,MAAQ7E,EAAYpB,EAE9CK,MAAOS,EAAIqL,UAAY9L,EACvBmK,SAAUA,GACV4B,QAASH,GAAqB1F,KAASvG,EAGvCqM,WAAYpG,GAAsB,MAAQM,KAASvG,IA0BrD,GAvBA+I,GAAQuD,IAAMpM,EAIVmC,IACF0G,GAAQwD,OAASlK,EAAOkK,OACxBxD,GAAQyD,OAAS5K,EAAUS,EAAOmK,SAS/BtL,EAAIuL,SAAS1M,EAAK,4CAInB6J,KAAoB5I,IACtB+H,GAAQ2D,kBAAoB1L,IAGzB4J,IAAcjK,KAAcC,GAA0B,KAAnBA,EAAID,GAC1C,OAAOZ,EACLuB,EAAiBX,EAAa,oBAAsBkC,EAAU,SAK7B,GAAlC7B,EAAiBsJ,QAAQ,OACxB,aAAatH,KAAKhC,IACnB0I,IAED3J,EACE,mBACEiB,EACA,SACA6B,EACA,0BAON,IACI8J,GA0DAC,GA3DA5D,GAAO,GAGP6D,GAAc,WAKhB,OAFEjN,EAAiBkN,UAAYpI,EAAKxB,EAAe,aAGzBhC,EAAI4L,UAAY,IACrCrI,QAAQzD,EAAkB4I,IAC1BnF,QAAQ,sDAAuD,MAC/DA,QAAQ,YAAa,OAASzE,GAKjC8M,GAAWD,KAOXE,GAAW,EAEXC,GAAc,SAAUC,EAAIC,GAC9B,GAAKjB,GAAL,CAEA,IAAIkB,EAAS7H,EAAOuE,GAAa,CAC/BI,KAAM,SACNmD,YAAaF,EAAOD,EAAKlE,GAAQqD,UAenC,GAXInG,GAAsB,OACxBkH,EAAOE,SAAWnG,KAAKoG,OAAOjH,KAAQoE,GAAQsC,IA3fnC,MA6fbA,GAAW,EACXtC,GAAQpE,KAGJJ,GAAsB,UACxBkH,EAAOzC,SAAWxD,KAAKqG,IAAI,EAAG7C,GAAU8C,OAGtCN,IAAStM,EAAI6M,WAEf7E,GAASuE,EAAQnN,EAAcE,QAE/B,IACEU,EAAI6M,WAAWC,KAAK9M,EAApBA,CAAyBoB,EAAa,UAAWJ,EAAUuL,IAC3D,MAAOQ,GAEP/E,GAASuE,EAAQnN,EAAcE,MAMrC4B,EACE,mBACA,WACMZ,EAAI0M,QACA,KAAOlL,KAAY/C,GAASqN,KAClCJ,GAAcvG,MACT0G,IAAY1G,KAAQuG,IAE7BzM,GAGF2B,EAAqBY,EAAUsK,GAAa7M,GAE5C,IAAI0N,GAAO3M,EAAI2M,MAAQ,GACnBL,GAAW,WACb,IACE,IAAIM,EAAuB7L,EAAgBQ,IAAiB,EACxDsL,EAAS7G,KAAKqG,IAChBM,GAAKtL,IAAiB,EACtBsL,GAAKrL,IAAiB,EACtBP,EAAgBQ,IAAiB,EACjCR,EAAgBM,IAAiB,EACjCN,EAAgBO,IAAiB,GAEnC,OAAO0E,KAAK8G,IACV,IAKI,EAJJ9G,KAAKoG,MACF,MAAQrL,EAAgBgM,WAAa,GAAKH,GACzCC,EACA,IAGN,MAAOhK,IAEP,OADAhE,EAAKgE,IACE,IAIXjC,EAAqB,OAAQ,WAC3B4I,GAAW8C,KACX1L,EACEM,EACA,WACMsI,GAAW8C,OAAY9C,GAAW8C,OAExCrN,KAQJ,IAgCI+N,GAkCAC,GAAUC,GAlEVC,GAAU,SAAUC,GACtB,IAAIpE,EAAO,GAIX,IACEA,EAAOoE,GAAa5M,EAAuBZ,EAAIqJ,UAC/C,MAAOpG,IACPhE,EAAKgE,IAGP,IAAIwK,EAAyB5O,EAAOwL,IACpC,GAAI/D,GAAWmH,GACb,IACErE,EAAOqE,EAAuBhL,KAAK5D,EAAQ,CAAEuK,KAAMA,KAAWA,EAC9D,MAAOnG,IACPF,EAAe,OAAQE,IAK3B,IA5YiB,SAAUmG,GAC3B,IAAK,IAAIsE,KAAKvD,GAAa,CACzB,IAAIwD,EAAgBxD,GAAYuD,GAChC,GAAKC,EAAL,CAGA,IAAIC,EAtOI,KAuOND,EAAc,GAAcA,EAvOtB,IAuO8CA,EAEtD,GACEC,IAAexE,GACf,IAAI9D,OACF,IAAM7B,EAAYmK,GAAYjK,QAAQ,SAAU,QAAU,IAC1D,KACAzB,KAAKkH,GAEP,OAAOhK,GAEX,OAAOC,EA0XHwO,CAAazE,GAQjB,MAFY,QAARS,IAAkB7J,EAAI8N,OAAM1E,GAAQpJ,EAAI8N,KAAK1J,MAAM,KAAK,IAErDgF,EAPLnK,EAAKuB,EAAiB,YAAc4I,IA8CpC2E,GAAW,SACbC,EACAC,EACAtH,EACAuH,IAEKA,GAAe5H,GAAWK,KAAWuH,EAAcvH,GACxD,IACIwH,EAGEC,EAJFrG,EAAWzB,GAAW4H,GAAeA,EAAc,aAEnD3K,EAAS0K,KAAgD,EAA9BA,EAAczE,QAAQ,OAGnDyE,GADIG,EAAQH,EAAc7J,MAAM,MACViK,QACtBF,EAAc,IAAMC,EAAM1G,KAAK,MAGjC,IAAI0B,EAAOmE,GAAQU,GAGnB,GAAK7E,GAAQyC,IAAgBzC,EAA7B,CAEAyC,GAAezC,EACflB,GAAKkB,KAAOA,EAGRjE,GAAsB,OACxB+C,GAAKoG,eACHlI,KAAKqG,IAAItL,EAA2B,aAAK,EAAGtC,EAAO0P,YAAc,IACjE,KACFrG,GAAKsG,gBACHpI,KAAKqG,IACHtL,EAAgBQ,IAAiB,EACjC9C,EAAO4P,aAAe,IACnB,MAILtJ,GAAsB,MACpBrF,EAAIsB,KAAW8G,GAAK9G,GAAYtB,EAAIsB,IAItCe,GAAUgD,GAAsB,QAClC+C,GAAKwG,aAAevM,EAAOwM,MAC3BzG,GAAK0G,cAAgBzM,EAAO8K,QAI9B,IAII4B,EAJAC,EAAOjQ,EAAOkQ,YACdC,EAAiB,aAIrB,IACEH,EAAsBC,EAAKG,iBAAiBD,GAAgB,GAAG7F,KAC/D,MAAOlG,IACPhE,EAAKgE,IAGPqK,GAAgBuB,GAC+C,EAA3D,CAAC,SAAU,gBAAgBrF,QAAQqF,GAGnCC,GACAA,EAAKE,KACwC,EAA7C,CAAC,EAAG,GAAGxF,QAAQsF,EAAKE,GAAgB7F,MAGxC,IAAI+F,EAA0BlD,GAC1BA,GAAS5H,MAhuBH,KAguBgB,GACtBlF,EACJmO,GAAWrB,IACgD,EAAvD5B,GAAmBZ,QAAQ0F,IAC3BA,GAA2BhP,EAC3Bb,EAGJ6I,GAAKiH,OACH,QAAQjN,KAAK6J,OAAkBiC,GAAeV,GAC1CjO,GACCgO,GAEP1G,EAAWD,GAAeC,EAAU,CAClCwC,KAAM3J,EACN4J,KAAMlB,GAAKkB,OAGb,IAAIgG,EAAsB,WACxB3O,EAA2BrB,EAC3B,IAAIiQ,EACFrB,GAAeV,KAAkBnI,GAAsB,MA3H1C,SACjB6I,EACAsB,EACAjC,EACAkC,EACA5I,EACAoB,GAEIiG,GAAa9B,GAAY,GAAKjE,GAAQqD,QAASlM,GAC/C+L,KAAoBlD,GAAQqD,QAAU7F,MAE1C,IAAI+J,EAAc1G,GAAkByE,KAEpCzF,GACE,CACEqE,GAAIlE,GAAQqD,QACZnC,KAAM3J,EACNwM,UAAWsD,GAAoBjC,EAAWrB,GAAW,KACrDuD,MAAOA,GAAStI,GAAeqI,GAE/B3I,SAAU7F,EAAU6F,IAEtBoB,GAGFqF,GAAmBpB,GACnBA,GAAWwD,EAEXxN,IAgGEyN,CACEzB,EACAqB,EACAhC,GACAc,EAAclH,GAAeoI,EAAQlB,GAAejP,EACpDyH,EACAoB,IAIJ,GAAKtH,EAmBH2O,SAjBA,IACM7N,GAAU+E,GAAW/E,EAAOmO,sBAC9BnO,EACGmO,qBAAqB,CAAC7N,EAAcC,IACpC6N,KAAK,SAAUC,GACd3H,GAAQ4H,QAAUD,EAAkB/N,GACpCoG,GAAQ6H,WAAaF,EAAkB9N,GACvCsN,MAEDW,SAAMX,GAETA,IAEF,MAAOvC,GACPuC,OAWFY,GAAMnR,EAAOoR,QACbC,GAAeF,GAAMA,GAAIG,UAAYjR,EACrCkR,GAAMvR,EAAOwR,cACbC,GAAgB,YAIhBtG,IAAekG,IAAgBK,OAASH,KAqB1CJ,GAAIG,WAnBEK,GAAOR,GADiB7G,GAoBAmH,IAlBrB,WACL,IAEIhH,EAFA5E,EAAMhC,UACN+N,EAAKD,GAAK1N,MAAM4N,KAAMhM,GAY1B,OAVI4B,GAAWiK,OACbjH,EAAQ,IAAIiH,MAAMpH,KAIlBG,EAAQlJ,EAAIuQ,YAAY,UAClBC,UAAUzH,GAAM/J,EAASA,GAEjCkK,EAAM5G,UAAYgC,EAClB0L,GAAI9G,GACGmH,IAMXzP,EACEsP,GACA,WACEvC,GAAS,IAEX1O,GAGF2B,EACE,WACA,WACE+M,GAAS,IAEX1O,IAKA2K,IAAuB,QAARH,IAAkB,iBAAkBhL,GACrDmC,EACE,aACA,WACE+M,GAAS,IAEX1O,GAIA2K,IAAa+D,KAEjBlP,EAAOgS,YAAc,SAAUzH,EAAMzC,EAAUoB,GAC7CgG,GAAS,EAAG3E,EAAMzC,EAAUoB,IAQ9B,IAAI+I,GAAa,CAAC,SAAU,UAExBC,GAAY,SAAUzH,EAAO3C,EAAUuH,IACpCA,GAAe5H,GAAWK,KAAWuH,EAAcvH,GAExD,IAAIqK,EAAkB1K,GAAWgD,GAC7BvB,EAAWzB,GAAW4H,GAAeA,EAAc,aACnD+C,SAAmB3H,EAEvB,GAAIwH,GAAWtH,QAAQyH,GAAa,IAAMD,EAExC,OADAjO,EAAekH,GAAmBxK,EAAY,aAAewR,GACtDlJ,IAGT,IACE,GAAIiJ,EAAiB,CACnB,IAAIE,EAAc5H,IAClB,GAAIwH,GAAWtH,eAAe0H,GAAe,EAK3C,OAJAnO,EACEkH,GACAX,EAAQ,uBAAyB4H,GAE5BnJ,IAETuB,EAAQ4H,GAEV,MAAOjO,IAEP,OADAF,EAAekH,GAAmBhH,IAC3B8E,IAGTuB,GAAS,GAAKA,GAAO3F,QAAQ,eAAgB,KAAKA,QAAQ,WAAY,IAEtE,IAAIwN,EAAc,CAAEhI,KAAM1J,EAAW6J,MAAOA,GACxC8H,GAAa9D,IAAiBtL,EAAQ,EAE1C2E,EAAWD,GAAeC,EAAUwK,GAEhC7H,GACFxB,GACEtD,EAAO2M,EAAa,CAClBhF,GAAI1G,KACJ8J,MAAOtI,IAAgBmK,GACvBpF,UACGoF,GAAa/D,KAAalI,GAAsB,KAC7CiI,GACA,KAENzG,SAAU7F,EAAU6F,KAEtBoB,IAKFsJ,GAAmB,SAAU/H,EAAO3C,EAAUoB,GAChDgJ,GAAUzH,EAAO3C,EAAUoB,IAIxBlJ,EAAOoL,MACVpL,EAAOoL,IAAqBoH,IAE9B,IAAIC,GAAYzS,EAAOoL,IAGnBsH,GAAQD,IAAaA,GAAUE,EAAIF,GAAUE,EAAI,GAMrD,IAAK,IAAIlI,MAHTzK,EAAOoL,IAAqBoH,GAGVE,GACZrO,EAAQqO,GAAOjI,MACjBrF,MAAMC,QAAQqN,GAAMjI,KAChByH,GAAUjO,MAAM,KAAMyO,GAAMjI,KAC5ByH,GAAUQ,GAAMjI,MAGxB,MAAOuD,IACP7N,EAAU6N,IA7IY,IAAU1D,GACxBqH,GA3mBkBzG,GAnN9B,CA68BElL,OACA,uBACA"} \ No newline at end of file diff --git a/dist/v12/custom/auto-events.js b/dist/v12/custom/auto-events.js new file mode 100644 index 00000000..410b2bc3 --- /dev/null +++ b/dist/v12/custom/auto-events.js @@ -0,0 +1,4 @@ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; 7048; SRI-version; v12) */ + +function r(t,e){var a,n;t.hasAttribute("data-simple-event")||(a=!1,h.downloads&&/^https?:\/\//i.test(t.href)&&new RegExp("\\.("+(h.downloadsExtensions||[]).join("|")+")$","i").test(t.pathname)?a="download":h.outbound&&/^https?:\/\//i.test(t.href)&&t.hostname!==m.location.hostname?a="outbound":h.emails&&/^mailto:/i.test(t.href)&&(a="email"),a&&(e?(n="saAutomatedLink(this, '"+a+"');",t.hasAttribute("target")&&"_self"!==t.getAttribute("target")||(n+=" return false;"),t.setAttribute("onclick",n)):t.addEventListener("click",function(){g(t,a)})))}function e(){try{for(var t=document.getElementsByTagName("a"),e=0;e -1,\n emails: collectTypes.indexOf(\"emails\") > -1,\n downloads: collectTypes.indexOf(\"downloads\") > -1,\n // Downloads: enter file extensions you want to collect\n downloadsExtensions: setting(\"extensions\", \"array\", [\n \"pdf\",\n \"csv\",\n \"docx\",\n \"xlsx\",\n \"zip\",\n \"doc\",\n \"xls\",\n ]),\n\n // All: use title attribute if set for event name (for all events)\n // THIS TAKES PRECEDENCE OVER OTHER SETTINGS BELOW\n title: setting(\"useTitle\", \"bool\", true),\n // Outbound: use full URL of the links? false for just the hostname\n outboundFullUrl: fullUrls,\n // Downloads: if taking event name from URL, use full URL or just filename (default)\n downloadsFullUrl: fullUrls,\n };\n\n var saGlobal = setting(\"saGlobal\", \"string\", \"sa_event\");\n\n // For compiling the script\n var optionsLink = options;\n\n if (typeof optionsLink === \"undefined\")\n log(\"options object not found, please specify\", \"warn\");\n\n var saAutomatedLink = function saAutomatedLink(element, type) {\n try {\n if (!element) return log(\"no element found\");\n var sent = false;\n\n var callback = function () {\n if (!sent && !element.hasAttribute(\"target\"))\n document.location = element.getAttribute(\"href\");\n sent = true;\n };\n\n if (window[saGlobal] && window[saGlobal + \"_loaded\"]) {\n var hostname = element.hostname;\n var pathname = element.pathname;\n\n var event;\n var metadata = {\n title: element.getAttribute(\"title\") || undefined,\n };\n var url = element.href || undefined;\n\n var useTitle = false;\n if (optionsLink.title && element.hasAttribute(\"title\")) {\n var theTitle = element.getAttribute(\"title\").trim();\n if (theTitle != \"\") useTitle = true;\n }\n\n if (useTitle) {\n event = theTitle;\n } else {\n switch (type) {\n case \"outbound\": {\n event = hostname + (optionsLink.outboundFullUrl ? pathname : \"\");\n metadata.url = url;\n break;\n }\n case \"download\": {\n event = optionsLink.downloadsFullUrl\n ? hostname + pathname\n : pathname.split(\"/\").pop();\n metadata.url = url;\n break;\n }\n case \"email\": {\n var href = element.getAttribute(\"href\");\n event = (href.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.email = event;\n break;\n }\n }\n }\n\n var clean =\n type +\n \"_\" +\n event.replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_+|_+$)/g, \"\");\n\n window[saGlobal](clean, metadata, callback);\n\n log(\"collected \" + clean);\n\n return type === \"email\"\n ? callback()\n : window.setTimeout(callback, 5000);\n } else {\n log(saGlobal + \" is not defined\", \"warn\");\n return callback();\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n };\n\n window.saAutomatedLink = saAutomatedLink;\n\n function collectLink(link, onclick) {\n if (link.hasAttribute(\"data-simple-event\")) return;\n var collect = false;\n\n // Collect download clicks\n if (\n optionsLink.downloads &&\n /^https?:\\/\\//i.test(link.href) &&\n new RegExp(\n \"\\\\.(\" + (optionsLink.downloadsExtensions || []).join(\"|\") + \")$\",\n \"i\"\n ).test(link.pathname)\n ) {\n collect = \"download\";\n\n // Collect outbound links clicks\n } else if (\n optionsLink.outbound &&\n /^https?:\\/\\//i.test(link.href) &&\n link.hostname !== window.location.hostname\n ) {\n collect = \"outbound\";\n\n // Collect email clicks\n } else if (optionsLink.emails && /^mailto:/i.test(link.href)) {\n collect = \"email\";\n }\n\n if (!collect) return;\n\n if (onclick) {\n var onClickAttribute = \"saAutomatedLink(this, '\" + collect + \"');\";\n\n if (\n !link.hasAttribute(\"target\") ||\n link.getAttribute(\"target\") === \"_self\"\n )\n onClickAttribute += \" return false;\";\n\n link.setAttribute(\"onclick\", onClickAttribute);\n } else {\n link.addEventListener(\"click\", function () {\n saAutomatedLink(link, collect);\n });\n }\n }\n\n function onDOMContentLoaded() {\n try {\n var a = document.getElementsByTagName(\"a\");\n\n // Loop over all links on the page\n for (var i = 0; i < a.length; i++) {\n var link = a[i];\n var href = link.getAttribute(\"href\");\n\n // Skip links that don't have an href\n if (!href) continue;\n\n // We don't want to overwrite website behaviour so we check for the onclick attribute\n if (!link.getAttribute(\"onclick\") && !/^mailto:/.test(href)) {\n collectLink(link, true);\n } else {\n collectLink(link, false);\n }\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n }\n\n if (doc.readyState === \"ready\" || doc.readyState === \"complete\") {\n onDOMContentLoaded();\n } else {\n document.addEventListener(\"readystatechange\", function (event) {\n if (event.target.readyState === \"complete\") onDOMContentLoaded();\n });\n }\n})(window);\n"],"names":["collectLink","link","onclick","collect","onClickAttribute","hasAttribute","optionsLink","downloads","test","href","RegExp","downloadsExtensions","join","pathname","outbound","hostname","window","location","emails","getAttribute","setAttribute","addEventListener","saAutomatedLink","onDOMContentLoaded","a","document","getElementsByTagName","i","length","error","log","message","doc","scriptElement","setting","collectTypes","fullUrls","options","saGlobal","type","logger","console","warn","info","currentScript","querySelector","attribute","defaultValue","value","dataset","split","map","item","trim","filter","Boolean","indexOf","title","outboundFullUrl","downloadsFullUrl","element","sent","callback","theTitle","metadata","undefined","url","useTitle","event","pop","email","clean","replace","setTimeout","readyState","target"],"mappings":"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"} \ No newline at end of file diff --git a/dist/v12/custom/light.js b/dist/v12/custom/light.js new file mode 100644 index 00000000..628e1ceb --- /dev/null +++ b/dist/v12/custom/light.js @@ -0,0 +1,4 @@ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; d3bf; SRI-version; v12) */ + +!function(l,e,t,f){try{var m=undefined,n="https:",r=l.console,a="doNotTrack",g=l.navigator,i=l.location,h=i.host,o=l.document,c=g.userAgent,s="Not sending request ",v=!1,u=encodeURIComponent,p=decodeURIComponent,d=JSON.stringify,y=l.addEventListener,_="https://"+t,b=(o.documentElement,"language"),w=g.userAgentData,O="platform",S="platformVersion",j="https://docs.simpleanalytics.com",k=/(bot|spider|crawl)/i.test(c)&&!/(cubot)/i.test(c),x=o.currentScript||o.querySelector('script[src*="'+t+'"]');f=function(){var e=[].slice.call(arguments);return e.unshift("Simple Analytics:"),Function.prototype.apply.call(r.warn,r,e)};var E=function(e){return"string"==typeof e},A=function(e,t){return e&&e.getAttribute("data-"+t)},$=function(){for(var e,t,n,r={},a=arguments,i=0;i>e/4).toString(16)})}catch(r){return e.replace(n,function(e){var t=16*Math.random()|0;return(e<2?t:3&t|8).toString(16)})}},N=function(e){return"function"==typeof e},R="namespace",U=e[R]||A(x,R)||"sa",V=e.strictUtm||"true"==A(x,"strict-utm"),B=function(t,e){return(e||i.search).slice(1).split("&").filter(function(e){return!t&&new RegExp("^((utm_)"+(V?"":"?")+"(source|medium|content|term|campaign)"+(V?"":"|ref")+")=").test(e)}).join("&")||m},C=U+"_loaded";if(1==l[C])return f(s+"twice");l.sa_event_loaded=!0,l[C]=!0;var H,T=function(t,e,n){t=n?t:$(L,P,t),g.brave&&!n&&(t.brave=!0),g._duckduckgoloader_&&!n&&(t.duck=!0),(new Image).src=_+"/simple.gif?"+Object.keys(t).filter(function(e){return t[e]!=m}).map(function(e){return u(e)+"="+u(t[e])}).join("&")+"&time="+Date.now()},F=e.hostname||A(x,"hostname"),z=F||h,J={version:"custom_light_12",hostname:z};e.mode||A(x,"mode");try{H=Intl.DateTimeFormat().resolvedOptions().timeZone}catch(X){f(X)}k&&(J.bot=!0);var L=$(J,{ua:c,https:i.protocol==n,timezone:H,page_id:I(),session_id:I()});if(L.sri=!0,w&&(L.mobile=w.mobile,L.brands=d(w.brands)),z!==h&&(L.hostname_original=h),a in g&&"1"==g[a])return f("Not sending request when "+a+" is enabled. See "+j+"/dnt");-1!=h.indexOf(".")&&!/^[0-9.:]+$/.test(h)||F||f("Set hostname on "+h+". See "+j+"/overwrite-domain-name");var M,P={},Z=(e.referrer||A(x,"referrer")||o.referrer||"").replace(h,z).replace(/^https?:\/\/((m|l|w{2,3}([0-9]+)?)\.)?([^?#]+)(.*)$/,"$4").replace(/^([^/]+)$/,"$1")||m,G=function(e,t){var n=$(J,{type:"append",original_id:t?e:L.page_id});if(t||!g.sendBeacon)T(n,0,!0);else try{g.sendBeacon.bind(g)(_+"/append",d(n))}catch(r){T(n,0,!0)}};y("pagehide",G,!1);var K,Q,W=function(e){var t="";try{t=e||p(i.pathname)}catch(X){f(X)}return t};!function(t,e,n,r){!r&&N(n)&&(r=n);var a,i;N(r);E(e)&&-1"); +//# sourceMappingURL=light.js.map \ No newline at end of file diff --git a/dist/v12/custom/light.js.map b/dist/v12/custom/light.js.map new file mode 100644 index 00000000..f64f97aa --- /dev/null +++ b/dist/v12/custom/light.js.map @@ -0,0 +1 @@ +{"version":3,"file":"light.source.js","sources":["light.source.js"],"sourcesContent":["/* eslint-env browser */\n\n(function (\n window,\n overwriteOptions,\n baseUrl,\n apiUrlPrefix,\n version,\n defaultNamespace,\n sendError,\n warn\n) {\n try {\n /////////////////////\n // PREDEFINED VARIABLES FOR BETTER MINIFICATION\n //\n\n // This seems like a lot of repetition, but it makes our script available for\n // multple destination which prevents us to need multiple scripts. The minified\n // version stays small.\n var undefinedVar = undefined;\n var trueVar = true;\n var falseVar = false;\n var trueText = \"true\";\n var https = \"https:\";\n var pageviewText = \"pageview\";\n var eventText = \"event\";\n var slash = \"/\";\n var protocol = https + \"//\";\n var con = window.console;\n var doNotTrack = \"doNotTrack\";\n var nav = window.navigator;\n var loc = window.location;\n var locationHostname = loc.host;\n var doc = window.document;\n var userAgent = nav.userAgent;\n var notSending = \"Not sending request \";\n var notSendingWhen = notSending + \"when \";\n var fetchedHighEntropyValues = falseVar;\n var encodeURIComponentFunc = encodeURIComponent;\n var decodeURIComponentFunc = decodeURIComponent;\n var stringify = JSON.stringify;\n var thousand = 1000;\n var addEventListenerFunc = window.addEventListener;\n var fullApiUrl = protocol + apiUrlPrefix + baseUrl;\n var documentElement = doc.documentElement || {};\n var language = \"language\";\n var Height = \"Height\";\n var Width = \"Width\";\n var scroll = \"scroll\";\n var uaData = nav.userAgentData;\n var scrollHeight = scroll + Height;\n var offsetHeight = \"offset\" + Height;\n var clientHeight = \"client\" + Height;\n var clientWidth = \"client\" + Width;\n var pagehide = \"pagehide\";\n var platformText = \"platform\";\n var platformVersionText = \"platformVersion\";\n var docsUrl = \"https://docs.simpleanalytics.com\";\n var pages = 0;\n var isBotAgent =\n /(bot|spider|crawl)/i.test(userAgent) && !/(cubot)/i.test(userAgent);\n\n\n // Find the script element where options can be set on\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"' + baseUrl + '\"]');\n\n /////////////////////\n // HELPER FUNCTIONS\n //\n\n // A simple log function so the user knows why a request is not being send\n warn = function () {\n // 1. Convert args to a normal array\n var args = [].slice.call(arguments);\n\n // 2. Prepend log prefix\n args.unshift(\"Simple Analytics:\");\n\n // 3. Pass along arguments to console.warn\n // Function.prototype.apply.call is needed for Internet Explorer\n return Function.prototype.apply.call(con.warn, con, args);\n };\n\n var warnInFunction = function (name, error) {\n warn(\"Error in your \" + name + \" function:\", error);\n };\n\n var hasProp = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n\n var isString = function (string) {\n return typeof string == \"string\";\n };\n\n var filterRegex = function (item) {\n return item.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n var attr = function (scriptElement, attribute) {\n return scriptElement && scriptElement.getAttribute(\"data-\" + attribute);\n };\n\n var convertCommaSeparatedToArray = function (csv) {\n return Array.isArray(csv)\n ? csv\n : isString(csv) && csv.length\n ? csv.split(/, ?/)\n : [];\n };\n\n var isObject = function (object) {\n return object && object.constructor === Object;\n };\n\n var assign = function () {\n var to = {};\n var arg = arguments;\n for (var index = 0; index < arg.length; index++) {\n var nextSource = arg[index];\n if (isObject(nextSource)) {\n for (var nextKey in nextSource) {\n if (hasProp(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n\n var settings = window.sa_settings;\n var logSettings = settings || Object.keys(overwriteOptions).length;\n\n // Merge overwriteOptions with sa_settings\n overwriteOptions = assign(overwriteOptions, settings);\n\n if (logSettings) warn(\"Settings\", overwriteOptions);\n\n\n var collectMetricByString = function (metricAbbreviation) {\n // eslint-disable-next-line no-unreachable\n return true;\n };\n\n var now = Date.now;\n\n var uuid = function () {\n var cryptoObject = window.crypto || window.msCrypto;\n var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;\n var uuidRegex = /[018]/g;\n\n try {\n return emptyUUID.replace(uuidRegex, function (c) {\n return (\n c ^\n (cryptoObject.getRandomValues(new Uint8Array(1))[0] &\n (15 >> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource, overwriteSearch) {\n return (\n (overwriteSearch || loc.search)\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n if (ignore) return falseVar;\n // eslint-disable-next-line no-redeclare\n var regex =\n \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \")=\";\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n\n\n\n\n\n\n\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n // eslint-disable-next-line no-redeclare\n var bot = isBotAgent;\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = trueVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n // Customers can overwrite their referrer, here we check for that\n var overwrittenReferrer =\n overwriteOptions.referrer || attr(scriptElement, \"referrer\");\n\n return (\n (overwrittenReferrer || doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n try {\n nav.sendBeacon.bind(nav)(fullApiUrl + \"/append\", stringify(append));\n } catch (e) {\n // Fallback for browsers throwing \"Illegal invocation\" when the URL is invalid\n sendData(append, undefinedVar, trueVar);\n }\n }\n };\n\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n\n\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n query,\n metadata,\n callback\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData(\n {\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: query || getQueryParams(deleteSourceInfo),\n\n },\n callback\n );\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (\n isPushState,\n pathOverwrite,\n metadata,\n callbackRaw\n ) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var querySearch;\n if (isString(pathOverwrite) && pathOverwrite.indexOf(\"?\") > -1) {\n // keep query from manual path\n var parts = pathOverwrite.split(\"?\");\n pathOverwrite = parts.shift();\n querySearch = \"?\" + parts.join(\"?\");\n }\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n sameSite = referrer\n ? referrer.split(slash)[0] == locationHostname\n : falseVar;\n\n\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n var delSrc =\n isPushState || userNavigated || !collectMetricByString(\"r\");\n sendPageView(\n isPushState,\n delSrc, // r = referrers\n sameSite,\n querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar,\n metadata,\n callback\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n\n\n pageview();\n\n } catch (e) {\n warn(e);\n }\n})(\n window,\n {},\n \"\",\n \"\",\n \"custom_light_12\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","warn","undefinedVar","undefined","https","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","language","documentElement","uaData","userAgentData","platformText","platformVersionText","docsUrl","isBotAgent","test","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","isString","string","attr","attribute","getAttribute","assign","obj","prop","object","to","arg","index","length","nextSource","constructor","Object","nextKey","hasOwnProperty","settings","sa_settings","logSettings","keys","Date","now","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","replace","c","getRandomValues","Uint8Array","toString","error","r","Math","random","isFunction","func","namespaceText","namespace","strictUtm","getQueryParams","ignoreSource","overwriteSearch","search","split","filter","keyValue","RegExp","join","loadedVariable","sa_event_loaded","timezone","sendData","data","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","Image","src","key","map","overwrittenHostname","hostname","definedHostname","basePayload","version","mode","Intl","DateTimeFormat","resolvedOptions","timeZone","bot","ua","protocol","page_id","session_id","sri","mobile","brands","hostname_original","indexOf","lastSendPath","referrer","sendOnLeave","id","push","append","type","original_id","sendBeacon","bind","e","sameSite","userNavigated","getPath","overwrite","path","pathname","isPushState","pathOverwrite","metadata","callbackRaw","querySearch","parts","shift","performaceEntryType","perf","performance","navigationText","getEntriesByType","triggerSendPageView","delSrc","deleteSourceInfo","query","currentPage","pages","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","pageview"],"mappings":"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"} \ No newline at end of file diff --git a/dist/v12/custom/proxy.js b/dist/v12/custom/proxy.js new file mode 100644 index 00000000..fefde6a6 --- /dev/null +++ b/dist/v12/custom/proxy.js @@ -0,0 +1,4 @@ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; 7647; SRI-version; v12) */ + +!function(d,t,e,n,m){try{var g=undefined,v=!0,y=!1,r="true",a="https:",_="pageview",u="event",i="error",o=d.console,c="doNotTrack",w=d.navigator,s=d.location,b=s.host,l=d.document,p=w.userAgent,f="Not sending request ",h=f+"when ",x=y,O=encodeURIComponent,E=decodeURIComponent,S=JSON.stringify,M=d.addEventListener,k="https://"+e,A=l.documentElement||{},q="language",$="Height",j="scroll",D=w.userAgentData,C=j+$,H="offset"+$,P="client"+$,R="pagehide",T="platform",U="platformVersion",I="https://docs.simpleanalytics.com",V=0,B=/(bot|spider|crawl)/i.test(p)&&!/(cubot)/i.test(p),N=d.screen,z=l.currentScript||l.querySelector('script[src*="'+e+'"]');m=function(){var t=[].slice.call(arguments);return t.unshift("Simple Analytics:"),Function.prototype.apply.call(o.warn,o,t)};var F=function(t,e){m("Error in your "+t+" function:",e)},W=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},G=function(t){return"string"==typeof t},J=function(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},L=function(t,e){return t&&t.getAttribute("data-"+e)},Y=function(t){return Array.isArray(t)?t:G(t)&&t.length?t.split(/, ?/):[]},Z=function(t){return t&&t.constructor===Object},K=function(){for(var t={},e=arguments,n=0;n>t/4).toString(16)})}catch(r){return t.replace(n,function(t){var e=16*Math.random()|0;return(t<2?e:3&e|8).toString(16)})}},at=function(t){return"function"==typeof t},it="namespace",ot=t[it]||L(z,it)||"sa",ct=function(t,e){var n=d[ot+"_metadata"];Z(n)&&(t=K(t,n));var r=d[Mt];if(!at(r))return Mt&&m(Mt+" not found, set window."+Mt),t;try{return K(t,r.call(d,K(t,e)))}catch(a){F("metadata",a)}},st=t.strictUtm||L(z,"strict-utm")==r,ut=function(a,t){return(t||s.search).slice(1).split("&").filter(function(t){var e=a||!et("ut"),n=Ot.map(J).join("|"),r=e?"^("+n+")=":"^((utm_)"+(st?"":"?")+"(source|medium|content|term|campaign)"+(st?"":"|ref")+"|"+n+")=";return e&&!Ot.length?y:new RegExp(r).test(t)}).join("&")||g},lt=ot+"_loaded";if(d[lt]==v)return m(f+"twice");d.sa_event_loaded=v,d[lt]=v;var pt=function(e,t,n){e=n?e:K($t,Ct,e),w.brave&&!n&&(e.brave=v),w._duckduckgoloader_&&!n&&(e.duck=v);var r=new Image;t&&(r.onerror=t,r.onload=t),r.src=k+"/simple.gif?"+Object.keys(e).filter(function(t){return e[t]!=g}).map(function(t){return O(t)+"="+O(e[t])}).join("&")+"&time="+Date.now()},ft=t.hostname||L(z,"hostname"),ht=ft||b,dt={version:"custom_proxy_12",hostname:ht};n=function(t){t=t.stack?t+" "+t.stack:t,m(t),pt(K(dt,{type:i,error:t,path:s.pathname}),g,v)},M(i,function(t){t.filename&&-1"); +//# sourceMappingURL=proxy.js.map \ No newline at end of file diff --git a/dist/v12/custom/proxy.js.map b/dist/v12/custom/proxy.js.map new file mode 100644 index 00000000..e7e6496d --- /dev/null +++ b/dist/v12/custom/proxy.js.map @@ -0,0 +1 @@ +{"version":3,"file":"proxy.source.js","sources":["proxy.source.js"],"sourcesContent":["/* eslint-env browser */\n\n(function (\n window,\n overwriteOptions,\n baseUrl,\n apiUrlPrefix,\n version,\n defaultNamespace,\n sendError,\n warn\n) {\n try {\n /////////////////////\n // PREDEFINED VARIABLES FOR BETTER MINIFICATION\n //\n\n // This seems like a lot of repetition, but it makes our script available for\n // multple destination which prevents us to need multiple scripts. The minified\n // version stays small.\n var undefinedVar = undefined;\n var trueVar = true;\n var falseVar = false;\n var trueText = \"true\";\n var https = \"https:\";\n var pageviewText = \"pageview\";\n var eventText = \"event\";\n var errorText = \"error\";\n var slash = \"/\";\n var protocol = https + \"//\";\n var con = window.console;\n var doNotTrack = \"doNotTrack\";\n var nav = window.navigator;\n var loc = window.location;\n var locationHostname = loc.host;\n var doc = window.document;\n var userAgent = nav.userAgent;\n var notSending = \"Not sending request \";\n var notSendingWhen = notSending + \"when \";\n var fetchedHighEntropyValues = falseVar;\n var encodeURIComponentFunc = encodeURIComponent;\n var decodeURIComponentFunc = decodeURIComponent;\n var stringify = JSON.stringify;\n var thousand = 1000;\n var addEventListenerFunc = window.addEventListener;\n var fullApiUrl = protocol + apiUrlPrefix + baseUrl;\n var documentElement = doc.documentElement || {};\n var language = \"language\";\n var Height = \"Height\";\n var Width = \"Width\";\n var scroll = \"scroll\";\n var uaData = nav.userAgentData;\n var scrollHeight = scroll + Height;\n var offsetHeight = \"offset\" + Height;\n var clientHeight = \"client\" + Height;\n var clientWidth = \"client\" + Width;\n var pagehide = \"pagehide\";\n var platformText = \"platform\";\n var platformVersionText = \"platformVersion\";\n var docsUrl = \"https://docs.simpleanalytics.com\";\n var pages = 0;\n var isBotAgent =\n /(bot|spider|crawl)/i.test(userAgent) && !/(cubot)/i.test(userAgent);\n var screen = window.screen;\n\n\n // Find the script element where options can be set on\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"' + baseUrl + '\"]');\n\n /////////////////////\n // HELPER FUNCTIONS\n //\n\n // A simple log function so the user knows why a request is not being send\n warn = function () {\n // 1. Convert args to a normal array\n var args = [].slice.call(arguments);\n\n // 2. Prepend log prefix\n args.unshift(\"Simple Analytics:\");\n\n // 3. Pass along arguments to console.warn\n // Function.prototype.apply.call is needed for Internet Explorer\n return Function.prototype.apply.call(con.warn, con, args);\n };\n\n var warnInFunction = function (name, error) {\n warn(\"Error in your \" + name + \" function:\", error);\n };\n\n var hasProp = function (obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n };\n\n var isString = function (string) {\n return typeof string == \"string\";\n };\n\n var filterRegex = function (item) {\n return item.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n };\n\n var attr = function (scriptElement, attribute) {\n return scriptElement && scriptElement.getAttribute(\"data-\" + attribute);\n };\n\n var convertCommaSeparatedToArray = function (csv) {\n return Array.isArray(csv)\n ? csv\n : isString(csv) && csv.length\n ? csv.split(/, ?/)\n : [];\n };\n\n var isObject = function (object) {\n return object && object.constructor === Object;\n };\n\n var assign = function () {\n var to = {};\n var arg = arguments;\n for (var index = 0; index < arg.length; index++) {\n var nextSource = arg[index];\n if (isObject(nextSource)) {\n for (var nextKey in nextSource) {\n if (hasProp(nextSource, nextKey)) {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n return to;\n };\n\n var settings = window.sa_settings;\n var logSettings = settings || Object.keys(overwriteOptions).length;\n\n // Merge overwriteOptions with sa_settings\n overwriteOptions = assign(overwriteOptions, settings);\n\n if (logSettings) warn(\"Settings\", overwriteOptions);\n\n // Customers can skip data points\n var ignoreMetrics = convertCommaSeparatedToArray(\n overwriteOptions.ignoreMetrics || attr(scriptElement, \"ignore-metrics\")\n );\n\n var collectMetricByString = function (metricAbbreviation) {\n // Can't use Array.find() here because we need to support IE9\n return (\n ignoreMetrics.filter(function (item) {\n return new RegExp(\"^\" + metricAbbreviation).test(item);\n }).length === 0\n );\n };\n\n var now = Date.now;\n\n var uuid = function () {\n var cryptoObject = window.crypto || window.msCrypto;\n var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;\n var uuidRegex = /[018]/g;\n\n try {\n return emptyUUID.replace(uuidRegex, function (c) {\n return (\n c ^\n (cryptoObject.getRandomValues(new Uint8Array(1))[0] &\n (15 >> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n var appendMetadata = function (metadata, data) {\n var metadataObject = window[namespace + \"_metadata\"];\n if (isObject(metadataObject)) metadata = assign(metadata, metadataObject);\n var metadataCollectorFunction = window[metadataCollector];\n if (!isFunction(metadataCollectorFunction)) {\n if (metadataCollector)\n warn(\n metadataCollector + \" not found, set window.\" + metadataCollector\n );\n return metadata;\n }\n try {\n return assign(\n metadata,\n metadataCollectorFunction.call(window, assign(metadata, data))\n );\n } catch (error) {\n warnInFunction(\"metadata\", error);\n }\n };\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource, overwriteSearch) {\n return (\n (overwriteSearch || loc.search)\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n var paramsRegexList = allowParams.map(filterRegex).join(\"|\");\n var regex = ignore\n ? \"^(\" + paramsRegexList + \")=\"\n : \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \"|\" +\n paramsRegexList +\n \")=\";\n if (ignore && !allowParams.length) return falseVar;\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n // Ignore pages specified in data-ignore-pages\n var shouldIgnore = function (path) {\n for (var i in ignorePages) {\n var ignorePageRaw = ignorePages[i];\n if (!ignorePageRaw) continue;\n\n // Prepend a slash when it's missing\n var ignorePage =\n ignorePageRaw[0] == slash ? ignorePageRaw : slash + ignorePageRaw;\n\n if (\n ignorePage === path ||\n new RegExp(\n \"^\" + filterRegex(ignorePage).replace(/\\\\\\*/gi, \"(.*)\") + \"$\",\n \"i\"\n ).test(path)\n )\n return trueVar;\n }\n return falseVar;\n };\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n if (callback) {\n image.onerror = callback;\n image.onload = callback;\n }\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n /////////////////////\n // ERROR FUNCTIONS\n //\n\n // Send errors\n // no var because it's scoped outside of the try/catch\n sendError = function (errorOrMessage) {\n errorOrMessage = errorOrMessage.stack\n ? errorOrMessage + \" \" + errorOrMessage.stack\n : errorOrMessage;\n warn(errorOrMessage);\n sendData(\n assign(basePayload, {\n type: errorText,\n error: errorOrMessage,\n path: loc.pathname,\n }),\n undefinedVar,\n trueVar\n );\n };\n\n // We listen for the error events and only send errors that are\n // from our script (checked by filename) to our server.\n addEventListenerFunc(\n errorText,\n function (event) {\n if (event.filename && event.filename.indexOf(baseUrl) > -1) {\n sendError(event.message);\n }\n },\n falseVar\n );\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n var start = now();\n\n var scrolled = 0;\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n // Should we record Do Not Track visits?\n var collectDnt = isBoolean(overwriteOptions.collectDnt)\n ? overwriteOptions.collectDnt\n : attr(scriptElement, \"ignore-dnt\") == trueText ||\n attr(scriptElement, \"skip-dnt\") == trueText ||\n attr(scriptElement, \"collect-dnt\") == trueText;\n\n // Some customers want to collect page views manually\n var autoCollect = !(\n attr(scriptElement, \"auto-collect\") == \"false\" ||\n overwriteOptions.autoCollect === falseVar\n );\n\n // Event function name\n var eventFunctionName =\n overwriteOptions.saGlobal ||\n attr(scriptElement, \"sa-global\") ||\n namespace + \"_\" + eventText;\n\n // Customers can ignore certain pages\n var ignorePages = convertCommaSeparatedToArray(\n overwriteOptions.ignorePages || attr(scriptElement, \"ignore-pages\")\n );\n\n // Customers can allow params\n var allowParams = convertCommaSeparatedToArray(\n overwriteOptions.allowParams || attr(scriptElement, \"allow-params\")\n );\n\n // Customers can allow params\n var nonUniqueHostnames = convertCommaSeparatedToArray(\n overwriteOptions.nonUniqueHostnames ||\n attr(scriptElement, \"non-unique-hostnames\")\n );\n\n // Customers can overwrite certain values\n var pathOverwriter =\n overwriteOptions.pathOverwriter || attr(scriptElement, \"path-overwriter\");\n\n // Customers can add metadata to events and pageviews via a function\n var metadataCollector =\n overwriteOptions.metadataCollector ||\n attr(scriptElement, \"metadata-collector\");\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n var phantom = window.phantom;\n var bot =\n nav.webdriver ||\n window.__nightmare ||\n window.callPhantom ||\n window._phantom ||\n (phantom && !phantom.solana) ||\n window.__polypane ||\n window._bot ||\n isBotAgent ||\n Math.random() == Math.random();\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = trueVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n // Warn when no document.doctype is defined (this breaks some documentElement dimensions)\n if (!doc.doctype) warn(\"Add DOCTYPE html for accurate dimensions\");\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (!collectDnt && doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n // Customers can overwrite their referrer, here we check for that\n var overwrittenReferrer =\n overwriteOptions.referrer || attr(scriptElement, \"referrer\");\n\n return (\n (overwrittenReferrer || doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n // t = timeonpage\n if (collectMetricByString(\"t\")) {\n append.duration = Math.round((now() - start - msHidden) / thousand);\n }\n msHidden = 0;\n start = now();\n\n // scro = scrolled\n if (collectMetricByString(\"scro\")) {\n append.scrolled = Math.max(0, scrolled, position());\n }\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n try {\n nav.sendBeacon.bind(nav)(fullApiUrl + \"/append\", stringify(append));\n } catch (e) {\n // Fallback for browsers throwing \"Illegal invocation\" when the URL is invalid\n sendData(append, undefinedVar, trueVar);\n }\n }\n };\n\n var hiddenStart;\n addEventListenerFunc(\n \"visibilitychange\",\n function () {\n if (doc.hidden) {\n if (!(\"on\" + pagehide in window)) sendOnLeave();\n hiddenStart = now();\n } else msHidden += now() - hiddenStart;\n },\n falseVar\n );\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n var body = doc.body || {};\n var position = function () {\n try {\n var documentClientHeight = documentElement[clientHeight] || 0;\n var height = Math.max(\n body[scrollHeight] || 0,\n body[offsetHeight] || 0,\n documentElement[clientHeight] || 0,\n documentElement[scrollHeight] || 0,\n documentElement[offsetHeight] || 0\n );\n return Math.min(\n 100,\n Math.round(\n (100 * ((documentElement.scrollTop || 0) + documentClientHeight)) /\n height /\n 5\n ) * 5\n );\n } catch (error) {\n warn(error);\n return 0;\n }\n };\n\n addEventListenerFunc(\"load\", function () {\n scrolled = position();\n addEventListenerFunc(\n scroll,\n function () {\n if (scrolled < position()) scrolled = position();\n },\n falseVar\n );\n });\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n var pathOverwriterFunction = window[pathOverwriter];\n if (isFunction(pathOverwriterFunction)) {\n try {\n path = pathOverwriterFunction.call(window, { path: path }) || path;\n } catch (error) {\n warnInFunction(\"path\", error);\n }\n }\n\n // Ignore pages specified in data-ignore-pages\n if (shouldIgnore(path)) {\n warn(notSendingWhen + \"ignoring \" + path);\n return;\n }\n\n // Add hash to path when script is put in to hash mode\n if (mode == \"hash\" && loc.hash) path += loc.hash.split(\"?\")[0];\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n query,\n metadata,\n callback\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData(\n {\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: query || getQueryParams(deleteSourceInfo),\n\n metadata: stringify(metadata),\n },\n callback\n );\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (\n isPushState,\n pathOverwrite,\n metadata,\n callbackRaw\n ) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var querySearch;\n if (isString(pathOverwrite) && pathOverwrite.indexOf(\"?\") > -1) {\n // keep query from manual path\n var parts = pathOverwrite.split(\"?\");\n pathOverwrite = parts.shift();\n querySearch = \"?\" + parts.join(\"?\");\n }\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n // v = viewportsizes\n if (collectMetricByString(\"v\")) {\n page.viewport_width =\n Math.max(documentElement[clientWidth] || 0, window.innerWidth || 0) ||\n null;\n page.viewport_height =\n Math.max(\n documentElement[clientHeight] || 0,\n window.innerHeight || 0\n ) || null;\n }\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n // sc = screensizes\n if (screen && collectMetricByString(\"sc\")) {\n page.screen_width = screen.width;\n page.screen_height = screen.height;\n }\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n var currentReferrerHostname = referrer\n ? referrer.split(slash)[0]\n : undefinedVar;\n sameSite = referrer\n ? nonUniqueHostnames.indexOf(currentReferrerHostname) > -1 ||\n currentReferrerHostname == locationHostname\n : falseVar;\n\n // We set unique variable based on pushstate or back navigation, if no match we check the referrer\n page.unique =\n /__cf_/.test(getReferrer()) || isPushState || userNavigated\n ? falseVar\n : !sameSite;\n\n metadata = appendMetadata(metadata, {\n type: pageviewText,\n path: page.path,\n });\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n var delSrc =\n isPushState || userNavigated || !collectMetricByString(\"r\");\n sendPageView(\n isPushState,\n delSrc, // r = referrers\n sameSite,\n querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar,\n metadata,\n callback\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n /////////////////////\n // AUTOMATED PAGE VIEW COLLECTION\n //\n\n var his = window.history;\n var hisPushState = his ? his.pushState : undefinedVar;\n var dis = window.dispatchEvent;\n var pushStateText = \"pushState\";\n\n // Overwrite history pushState function to\n // allow listening on the pushState event\n if (autoCollect && hisPushState && Event && dis) {\n var stateListener = function (type) {\n var orig = his[type];\n return function () {\n var arg = arguments;\n var rv = orig.apply(this, arg);\n var event;\n if (isFunction(Event)) {\n event = new Event(type);\n } else {\n // Fix for IE\n // https://github.com/simpleanalytics/scripts/issues/8\n event = doc.createEvent(\"Event\");\n event.initEvent(type, trueVar, trueVar);\n }\n event.arguments = arg;\n dis(event);\n return rv;\n };\n };\n\n his.pushState = stateListener(pushStateText);\n\n addEventListenerFunc(\n pushStateText,\n function () {\n pageview(1);\n },\n falseVar\n );\n\n addEventListenerFunc(\n \"popstate\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n // When in hash mode, we record a pageview based on the onhashchange function\n if (autoCollect && mode == \"hash\" && \"onhashchange\" in window) {\n addEventListenerFunc(\n \"hashchange\",\n function () {\n pageview(1);\n },\n falseVar\n );\n }\n\n if (autoCollect) pageview();\n\n window.sa_pageview = function (path, metadata, callback) {\n pageview(0, path, metadata, callback);\n };\n\n\n /////////////////////\n // EVENTS\n //\n\n var validTypes = [\"string\", \"number\"];\n\n var sendEvent = function (event, metadata, callbackRaw) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n\n var eventIsFunction = isFunction(event);\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var eventType = typeof event;\n\n if (validTypes.indexOf(eventType) < 0 && !eventIsFunction) {\n warnInFunction(eventFunctionName, eventText + \" can't be \" + eventType);\n return callback();\n }\n\n try {\n if (eventIsFunction) {\n var eventOutput = event();\n if (validTypes.indexOf(typeof eventOutput) < 0) {\n warnInFunction(\n eventFunctionName,\n event + \" returns no string: \" + eventOutput\n );\n return callback();\n }\n event = eventOutput;\n }\n } catch (error) {\n warnInFunction(eventFunctionName, error);\n return callback();\n }\n\n event = (\"\" + event).replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_|_$)/g, \"\");\n\n var eventParams = { type: eventText, event: event };\n var firstPage = !userNavigated && pages < 2;\n\n metadata = appendMetadata(metadata, eventParams);\n\n if (event) {\n sendData(\n assign(eventParams, {\n id: uuid(),\n query: getQueryParams(!firstPage),\n referrer:\n (firstPage || sameSite) && collectMetricByString(\"r\")\n ? previousReferrer\n : null,\n\n metadata: stringify(metadata),\n }),\n callback\n );\n }\n };\n\n var defaultEventFunc = function (event, metadata, callback) {\n sendEvent(event, metadata, callback);\n };\n\n // Set default function if user didn't define a function\n if (!window[eventFunctionName])\n window[eventFunctionName] = defaultEventFunc;\n\n var eventFunc = window[eventFunctionName];\n\n // Read queue of the user defined function\n var queue = eventFunc && eventFunc.q ? eventFunc.q : [];\n\n // Overwrite user defined function\n window[eventFunctionName] = defaultEventFunc;\n\n // Post events from the queue of the user defined function\n for (var event in queue) {\n if (hasProp(queue, event)) {\n Array.isArray(queue[event])\n ? sendEvent.apply(null, queue[event])\n : sendEvent(queue[event]);\n }\n }\n } catch (e) {\n sendError(e);\n }\n})(\n window,\n {},\n \"\",\n \"\",\n \"custom_proxy_12\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","sendError","warn","undefinedVar","undefined","trueVar","falseVar","trueText","https","pageviewText","eventText","errorText","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","notSendingWhen","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","documentElement","language","Height","scroll","uaData","userAgentData","scrollHeight","offsetHeight","clientHeight","pagehide","platformText","platformVersionText","docsUrl","pages","isBotAgent","test","screen","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","warnInFunction","name","error","hasProp","obj","prop","Object","hasOwnProperty","isString","string","filterRegex","item","replace","attr","attribute","getAttribute","convertCommaSeparatedToArray","csv","Array","isArray","length","split","isObject","object","constructor","assign","to","arg","index","nextSource","nextKey","settings","sa_settings","logSettings","keys","ignoreMetrics","collectMetricByString","metricAbbreviation","filter","RegExp","now","Date","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","c","getRandomValues","Uint8Array","toString","r","Math","random","isFunction","func","namespaceText","namespace","appendMetadata","metadata","data","metadataObject","metadataCollectorFunction","metadataCollector","strictUtm","getQueryParams","ignoreSource","overwriteSearch","search","keyValue","ignore","paramsRegexList","allowParams","map","join","regex","loadedVariable","sa_event_loaded","sendData","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","image","Image","onerror","onload","src","key","overwrittenHostname","hostname","definedHostname","basePayload","version","errorOrMessage","stack","type","path","pathname","event","filename","indexOf","message","timezone","start","scrolled","mode","collectDnt","value","autoCollect","eventFunctionName","saGlobal","ignorePages","nonUniqueHostnames","pathOverwriter","Intl","DateTimeFormat","resolvedOptions","timeZone","phantom","bot","webdriver","__nightmare","callPhantom","_phantom","solana","__polypane","_bot","collectDataOnLeave","ua","protocol","page_id","session_id","sri","mobile","brands","doctype","hostname_original","lastSendPath","hiddenStart","getReferrer","referrer","msHidden","sendOnLeave","id","push","append","original_id","duration","round","max","position","sendBeacon","bind","e","hidden","body","documentClientHeight","height","min","scrollTop","previousReferrer","sameSite","userNavigated","getPath","overwrite","pathOverwriterFunction","i","ignorePageRaw","ignorePage","shouldIgnore","hash","pageview","isPushState","pathOverwrite","callbackRaw","querySearch","parts","shift","viewport_width","innerWidth","viewport_height","innerHeight","screen_width","width","screen_height","performaceEntryType","perf","performance","navigationText","getEntriesByType","currentReferrerHostname","unique","triggerSendPageView","delSrc","deleteSourceInfo","query","currentPage","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","his","history","hisPushState","pushState","dis","dispatchEvent","pushStateText","Event","orig","rv","this","createEvent","initEvent","sa_pageview","validTypes","sendEvent","eventIsFunction","eventType","eventOutput","eventParams","firstPage","defaultEventFunc","eventFunc","queue","q"],"mappings":"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"} \ No newline at end of file diff --git a/dist/v12/light.js b/dist/v12/light.js new file mode 100644 index 00000000..d8233766 --- /dev/null +++ b/dist/v12/light.js @@ -0,0 +1,4 @@ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2025-06-24; 95f8; SRI-version; v12) */ + +!function(l,e,t,f){try{var m=undefined,n="https:",r=l.console,a="doNotTrack",g=l.navigator,i=l.location,h=i.host,o=l.document,c=g.userAgent,s="Not sending request ",v=!1,u=encodeURIComponent,p=decodeURIComponent,d=JSON.stringify,y=l.addEventListener,_="https://queue."+t,b=(o.documentElement,"language"),w=g.userAgentData,O="platform",S="platformVersion",j="https://docs.simpleanalytics.com",k=/(bot|spider|crawl)/i.test(c)&&!/(cubot)/i.test(c),E=o.currentScript||o.querySelector('script[src*="'+t+'"]');f=function(){var e=[].slice.call(arguments);return e.unshift("Simple Analytics:"),Function.prototype.apply.call(r.warn,r,e)};var q=function(e){return"string"==typeof e},x=function(e,t){return e&&e.getAttribute("data-"+t)},A=function(){for(var e,t,n,r={},a=arguments,i=0;i>e/4).toString(16)})}catch(r){return e.replace(n,function(e){var t=16*Math.random()|0;return(e<2?t:3&t|8).toString(16)})}},N=function(e){return"function"==typeof e},R="namespace",U=e[R]||x(E,R)||"sa",V=e.strictUtm||"true"==x(E,"strict-utm"),B=function(t,e){return(e||i.search).slice(1).split("&").filter(function(e){return!t&&new RegExp("^((utm_)"+(V?"":"?")+"(source|medium|content|term|campaign)"+(V?"":"|ref")+")=").test(e)}).join("&")||m},C=U+"_loaded";if(1==l[C])return f(s+"twice");l.sa_event_loaded=!0,l[C]=!0;var T,F=function(t,e,n){t=n?t:A(L,P,t),g.brave&&!n&&(t.brave=!0),g._duckduckgoloader_&&!n&&(t.duck=!0),(new Image).src=_+"/simple.gif?"+Object.keys(t).filter(function(e){return t[e]!=m}).map(function(e){return u(e)+"="+u(t[e])}).join("&")+"&time="+Date.now()},H=e.hostname||x(E,"hostname"),z=H||h,J={version:"cdn_light_12",hostname:z};e.mode||x(E,"mode");try{T=Intl.DateTimeFormat().resolvedOptions().timeZone}catch(X){f(X)}k&&(J.bot=!0);var L=A(J,{ua:c,https:i.protocol==n,timezone:T,page_id:I(),session_id:I()});if(L.sri=!0,w&&(L.mobile=w.mobile,L.brands=d(w.brands)),z!==h&&(L.hostname_original=h),a in g&&"1"==g[a])return f("Not sending request when "+a+" is enabled. See "+j+"/dnt");-1!=h.indexOf(".")&&!/^[0-9.:]+$/.test(h)||H||f("Set hostname on "+h+". See "+j+"/overwrite-domain-name");var M,P={},Z=(e.referrer||x(E,"referrer")||o.referrer||"").replace(h,z).replace(/^https?:\/\/((m|l|w{2,3}([0-9]+)?)\.)?([^?#]+)(.*)$/,"$4").replace(/^([^/]+)$/,"$1")||m,G=function(e,t){var n=A(J,{type:"append",original_id:t?e:L.page_id});if(t||!g.sendBeacon)F(n,0,!0);else try{g.sendBeacon.bind(g)(_+"/append",d(n))}catch(r){F(n,0,!0)}};y("pagehide",G,!1);var K,Q,W=function(e){var t="";try{t=e||p(i.pathname)}catch(X){f(X)}return t};!function(t,e,n,r){!r&&N(n)&&(r=n);var a,i;N(r);q(e)&&-1> (c / 4)))\n ).toString(16);\n });\n } catch (error) {\n return emptyUUID.replace(uuidRegex, function (c) {\n var r = (Math.random() * 16) | 0,\n v = c < 2 ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n };\n\n var isFunction = function (func) {\n return typeof func == \"function\";\n };\n\n // Define namespace for the library\n var namespaceText = \"namespace\";\n var namespace =\n overwriteOptions[namespaceText] ||\n attr(scriptElement, namespaceText) ||\n defaultNamespace;\n\n\n var isBoolean = function (value) {\n return !!value === value;\n };\n\n // By default we allow source, medium in the URLs. With strictUtm enabled\n // we only allow it with the utm_ prefix: utm_source, utm_medium, ...\n var strictUtm =\n overwriteOptions.strictUtm ||\n attr(scriptElement, \"strict-utm\") == trueText;\n\n var getQueryParams = function (ignoreSource, overwriteSearch) {\n return (\n (overwriteSearch || loc.search)\n .slice(1)\n .split(\"&\")\n .filter(function (keyValue) {\n var ignore = ignoreSource || !collectMetricByString(\"ut\");\n\n if (ignore) return falseVar;\n // eslint-disable-next-line no-redeclare\n var regex =\n \"^((utm_)\" +\n (strictUtm ? \"\" : \"?\") +\n \"(source|medium|content|term|campaign)\" +\n (strictUtm ? \"\" : \"|ref\") +\n \")=\";\n\n // The prefix \"utm_\" is optional with \"strictUtm\" disabled\n // \"ref\" is only collected when \"strictUtm\" is disabled\n return new RegExp(regex).test(keyValue);\n })\n .join(\"&\") || undefinedVar\n );\n };\n\n\n /////////////////////\n // Warn when using script twice\n //\n\n // Only load our script once, customers can still send multiple page views\n // with the sa_pageview function if they turn off auto collect.\n var loadedVariable = namespace + \"_loaded\";\n if (window[loadedVariable] == trueVar) return warn(notSending + \"twice\");\n window.sa_event_loaded = trueVar;\n window[loadedVariable] = trueVar;\n\n /////////////////////\n // SEND DATA VIA OUR PIXEL\n //\n\n // Send data via image\n var sendData = function (data, callback, onlyThisData) {\n data = onlyThisData ? data : assign(payload, page, data);\n\n if (nav.brave && !onlyThisData) data.brave = trueVar;\n if (nav._duckduckgoloader_ && !onlyThisData) data.duck = trueVar;\n\n\n var image = new Image();\n image.src =\n fullApiUrl +\n \"/simple.gif?\" +\n Object.keys(data)\n .filter(function (key) {\n return data[key] != undefinedVar;\n })\n .map(function (key) {\n return (\n encodeURIComponentFunc(key) +\n \"=\" +\n encodeURIComponentFunc(data[key])\n );\n })\n .join(\"&\") +\n \"&time=\" +\n Date.now();\n };\n\n // Customers can overwrite their hostname, here we check for that\n var overwrittenHostname =\n overwriteOptions.hostname || attr(scriptElement, \"hostname\");\n var definedHostname = overwrittenHostname || locationHostname;\n\n var basePayload = {\n version: version,\n hostname: definedHostname,\n };\n\n\n /////////////////////\n // INITIALIZE VALUES\n //\n\n\n\n /////////////////////\n // GET SETTINGS\n //\n\n // Script mode, this can be hash mode for example\n var mode = overwriteOptions.mode || attr(scriptElement, \"mode\");\n\n\n\n\n\n\n\n\n\n // This code could error on (incomplete) implementations, that's why we use try...catch\n var timezone;\n try {\n // c = countries\n timezone = collectMetricByString(\"c\")\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : undefinedVar;\n } catch (error) {\n warn(error);\n }\n\n /////////////////////\n // PAYLOAD FOR BOTH PAGE VIEWS AND EVENTS\n //\n\n // eslint-disable-next-line no-redeclare\n var bot = isBotAgent;\n\n // t = timeonpage, scro = scrolled\n var collectDataOnLeave =\n collectMetricByString(\"t\") || collectMetricByString(\"scro\");\n\n if (bot) basePayload.bot = trueVar;\n\n var payload = assign(basePayload, {\n // us = useragent\n ua: collectMetricByString(\"us\") ? userAgent : undefinedVar,\n\n https: loc.protocol == https,\n timezone: timezone,\n page_id: collectDataOnLeave ? uuid() : undefinedVar,\n\n // se = sessions\n session_id: collectMetricByString(\"se\") ? uuid() : undefinedVar,\n });\n\n payload.sri = trueVar;\n\n // Use User-Agent Client Hints for better privacy\n // https://web.dev/user-agent-client-hints/\n if (uaData) {\n payload.mobile = uaData.mobile;\n payload.brands = stringify(uaData.brands);\n }\n\n /////////////////////\n // ADD WARNINGS\n //\n\n\n\n // When a customer overwrites the hostname, we need to know what the original\n // hostname was to hide that domain from referrer traffic\n if (definedHostname !== locationHostname)\n payload.hostname_original = locationHostname;\n\n // Don't track when Do Not Track is set to true\n if (doNotTrack in nav && nav[doNotTrack] == \"1\")\n return warn(\n notSendingWhen + doNotTrack + \" is enabled. See \" + docsUrl + \"/dnt\"\n );\n\n // Warn when sending from localhost and not having a hostname set\n if (\n (locationHostname.indexOf(\".\") == -1 ||\n /^[0-9.:]+$/.test(locationHostname)) &&\n !overwrittenHostname\n )\n warn(\n \"Set hostname on \" +\n locationHostname +\n \". See \" +\n docsUrl +\n \"/overwrite-domain-name\"\n );\n\n /////////////////////\n // SETUP INITIAL VARIABLES\n //\n\n var page = {};\n var lastSendPath;\n\n var getReferrer = function () {\n // Customers can overwrite their referrer, here we check for that\n var overwrittenReferrer =\n overwriteOptions.referrer || attr(scriptElement, \"referrer\");\n\n return (\n (overwrittenReferrer || doc.referrer || \"\")\n .replace(locationHostname, definedHostname)\n .replace(/^https?:\\/\\/((m|l|w{2,3}([0-9]+)?)\\.)?([^?#]+)(.*)$/, \"$4\")\n .replace(/^([^/]+)$/, \"$1\") || undefinedVar\n );\n };\n\n // We don't want to end up with sensitive data so we clean the referrer URL\n var referrer = getReferrer();\n\n /////////////////////\n // TIME ON PAGE AND SCROLLED LOGIC\n //\n\n // We don't put msHidden in if duration block, because it's used outside of that functionality\n var msHidden = 0;\n\n var sendOnLeave = function (id, push) {\n if (!collectDataOnLeave) return;\n\n var append = assign(basePayload, {\n type: \"append\",\n original_id: push ? id : payload.page_id,\n });\n\n\n\n if (push || !nav.sendBeacon) {\n // sendData will assign payload to request\n sendData(append, undefinedVar, trueVar);\n } else {\n try {\n nav.sendBeacon.bind(nav)(fullApiUrl + \"/append\", stringify(append));\n } catch (e) {\n // Fallback for browsers throwing \"Illegal invocation\" when the URL is invalid\n sendData(append, undefinedVar, trueVar);\n }\n }\n };\n\n\n addEventListenerFunc(pagehide, sendOnLeave, falseVar);\n\n\n /////////////////////\n // ACTUAL PAGE VIEW LOGIC\n //\n\n var getPath = function (overwrite) {\n var path = \"\";\n\n // decodeURIComponent can fail when having invalid characters\n // https://github.com/simpleanalytics/roadmap/issues/462\n try {\n path = overwrite || decodeURIComponentFunc(loc.pathname);\n } catch (error) {\n warn(error);\n }\n\n\n\n\n return path;\n };\n\n var previousReferrer;\n\n // Send page view and append data to it\n var sendPageView = function (\n isPushState,\n deleteSourceInfo,\n sameSite,\n query,\n metadata,\n callback\n ) {\n if (isPushState) sendOnLeave(\"\" + payload.page_id, trueVar);\n if (collectDataOnLeave) payload.page_id = uuid();\n\n var currentPage = definedHostname + getPath();\n\n sendData(\n {\n id: payload.page_id,\n type: pageviewText,\n referrer: !deleteSourceInfo || sameSite ? referrer : null,\n query: query || getQueryParams(deleteSourceInfo),\n\n },\n callback\n );\n\n previousReferrer = referrer;\n referrer = currentPage;\n\n pages++;\n };\n\n var sameSite, userNavigated;\n\n var pageview = function (\n isPushState,\n pathOverwrite,\n metadata,\n callbackRaw\n ) {\n if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata;\n var callback = isFunction(callbackRaw) ? callbackRaw : function () {};\n var querySearch;\n if (isString(pathOverwrite) && pathOverwrite.indexOf(\"?\") > -1) {\n // keep query from manual path\n var parts = pathOverwrite.split(\"?\");\n pathOverwrite = parts.shift();\n querySearch = \"?\" + parts.join(\"?\");\n }\n // Obfuscate personal data in URL by dropping the search and hash\n var path = getPath(pathOverwrite);\n\n // Don't send the last path again (this could happen when pushState is used to change the path hash or search)\n if (!path || lastSendPath == path) return;\n\n lastSendPath = path;\n page.path = path;\n\n\n // l = language\n if (collectMetricByString(\"l\")) {\n if (nav[language]) page[language] = nav[language];\n }\n\n\n // If a user does refresh we need to delete the referrer because otherwise it count double\n var perf = window.performance;\n var navigationText = \"navigation\";\n\n // Check if back, forward or reload buttons are being used in modern browsers\n var performaceEntryType;\n try {\n performaceEntryType = perf.getEntriesByType(navigationText)[0].type;\n } catch (error) {\n warn(error);\n }\n\n userNavigated = performaceEntryType\n ? [\"reload\", \"back_forward\"].indexOf(performaceEntryType) > -1\n : // Check if back, forward or reload buttons are being use in older browsers\n // 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD\n perf &&\n perf[navigationText] &&\n [1, 2].indexOf(perf[navigationText].type) > -1;\n\n // Check if referrer is the same as current real hostname (not the defined hostname!)\n sameSite = referrer\n ? referrer.split(slash)[0] == locationHostname\n : falseVar;\n\n\n\n var triggerSendPageView = function () {\n fetchedHighEntropyValues = trueVar;\n var delSrc =\n isPushState || userNavigated || !collectMetricByString(\"r\");\n sendPageView(\n isPushState,\n delSrc, // r = referrers\n sameSite,\n querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar,\n metadata,\n callback\n );\n };\n\n if (!fetchedHighEntropyValues) {\n // Request platform information if this is available\n try {\n if (uaData && isFunction(uaData.getHighEntropyValues)) {\n uaData\n .getHighEntropyValues([platformText, platformVersionText])\n .then(function (highEntropyValues) {\n payload.os_name = highEntropyValues[platformText];\n payload.os_version = highEntropyValues[platformVersionText];\n triggerSendPageView();\n })\n .catch(triggerSendPageView);\n } else {\n triggerSendPageView();\n }\n } catch (e) {\n triggerSendPageView();\n }\n } else {\n triggerSendPageView();\n }\n };\n\n\n\n pageview();\n\n } catch (e) {\n warn(e);\n }\n})(\n window,\n {},\n \"simpleanalyticscdn.com\",\n \"queue.\",\n \"cdn_light_12\",\n \"sa\"\n);\n"],"names":["window","overwriteOptions","baseUrl","warn","undefinedVar","undefined","https","con","console","doNotTrack","nav","navigator","loc","location","locationHostname","host","doc","document","userAgent","notSending","fetchedHighEntropyValues","encodeURIComponentFunc","encodeURIComponent","decodeURIComponentFunc","decodeURIComponent","stringify","JSON","addEventListenerFunc","addEventListener","fullApiUrl","protocol","language","documentElement","uaData","userAgentData","platformText","platformVersionText","docsUrl","isBotAgent","test","scriptElement","currentScript","querySelector","args","slice","call","arguments","unshift","Function","prototype","apply","isString","string","attr","attribute","getAttribute","assign","obj","prop","object","to","arg","index","length","nextSource","constructor","Object","nextKey","hasOwnProperty","settings","sa_settings","logSettings","keys","Date","now","uuid","cryptoObject","crypto","msCrypto","emptyUUID","uuidRegex","replace","c","getRandomValues","Uint8Array","toString","error","r","Math","random","isFunction","func","namespaceText","namespace","strictUtm","getQueryParams","ignoreSource","overwriteSearch","search","split","filter","keyValue","RegExp","join","loadedVariable","sa_event_loaded","timezone","sendData","data","callback","onlyThisData","payload","page","brave","_duckduckgoloader_","duck","Image","src","key","map","overwrittenHostname","hostname","definedHostname","basePayload","version","mode","Intl","DateTimeFormat","resolvedOptions","timeZone","bot","ua","page_id","session_id","sri","mobile","brands","hostname_original","indexOf","lastSendPath","referrer","sendOnLeave","id","push","append","type","original_id","sendBeacon","bind","e","sameSite","userNavigated","getPath","overwrite","path","pathname","isPushState","pathOverwrite","metadata","callbackRaw","querySearch","parts","shift","performaceEntryType","perf","performance","navigationText","getEntriesByType","triggerSendPageView","delSrc","deleteSourceInfo","query","currentPage","pages","sendPageView","getHighEntropyValues","then","highEntropyValues","os_name","os_version","catch","pageview"],"mappings":"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"} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 7748693a..7c2d2440 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,18 +9,24 @@ "version": "9.0.0", "license": "ISC", "devDependencies": { + "acorn": "^8.11.3", "browserstack-local": "^1.5.1", "chai": "^4.2.0", "dotenv": "^8.2.0", "eslint": "^6.7.2", "esprima": "^4.0.1", "handlebars": "^4.7.6", + "jsdom": "^21.1.0", "mocha": "^6.2.3", "nodemon": "^1.19.4", + "prettier": "3.2.5", "request": "^2.88.0", "selenium-webdriver": "^4.3.1", "uglify-js": "^3.9.4", "uuid-validate": "0.0.3" + }, + "engines": { + "node": "22.16" } }, "node_modules/@babel/code-frame": { @@ -43,6 +49,22 @@ "js-tokens": "^4.0.0" } }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", + "dev": true + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -50,9 +72,9 @@ "dev": true }, "node_modules/acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -61,12 +83,34 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "dev": true, + "dependencies": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, "node_modules/acorn-jsx": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", "dev": true }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -518,6 +562,19 @@ "node": ">=0.10.0" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -853,6 +910,18 @@ "node": ">=4" } }, + "node_modules/cssstyle": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", + "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", + "dev": true, + "dependencies": { + "rrweb-cssom": "^0.6.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -865,6 +934,20 @@ "node": ">=0.10" } }, + "node_modules/data-urls": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", + "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^12.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -889,6 +972,12 @@ "node": ">=0.10.0" } }, + "node_modules/decimal.js": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", + "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==", + "dev": true + }, "node_modules/decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", @@ -1018,6 +1107,19 @@ "node": ">=6.0.0" } }, + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "deprecated": "Use your platform's native DOMException instead", + "dev": true, + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", @@ -1039,6 +1141,20 @@ "node": ">=8" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -1067,6 +1183,18 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/entities": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz", + "integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/es-abstract": { "version": "1.17.6", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", @@ -1089,6 +1217,51 @@ "node": ">= 0.4" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -1112,6 +1285,36 @@ "node": ">=0.8.0" } }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/eslint": { "version": "6.7.2", "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.7.2.tgz", @@ -1302,6 +1505,18 @@ "node": ">=6.0.0" } }, + "node_modules/espree/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -1780,10 +1995,13 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/functional-red-black-tree": { "version": "1.0.1", @@ -1809,6 +2027,43 @@ "node": "*" } }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", @@ -1899,6 +2154,18 @@ "node": ">=8" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/got": { "version": "6.7.1", "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", @@ -1999,12 +2266,30 @@ } }, "node_modules/has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-value": { @@ -2046,6 +2331,18 @@ "node": ">=0.10.0" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -2055,6 +2352,55 @@ "he": "bin/he" } }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-agent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -2521,6 +2867,12 @@ "node": ">=0.10.0" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, "node_modules/is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", @@ -2651,6 +3003,81 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, + "node_modules/jsdom": { + "version": "21.1.2", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.1.2.tgz", + "integrity": "sha512-sCpFmK2jv+1sjff4u7fzft+pUh2KSUbUrEHYHyfSIbGTIcmnjyp83qg6qLwdJ/I3LpTXx33ACxeRL7Lsyc6lGQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.8.2", + "acorn-globals": "^7.0.0", + "cssstyle": "^3.0.0", + "data-urls": "^4.0.0", + "decimal.js": "^10.4.3", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.4", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^12.0.1", + "ws": "^8.13.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/form-data": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jsdom/node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -2834,6 +3261,15 @@ "node": ">=0.10.0" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -3164,6 +3600,12 @@ "node": ">=4" } }, + "node_modules/nwsapi": { + "version": "2.2.20", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.20.tgz", + "integrity": "sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==", + "dev": true + }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -3400,6 +3842,18 @@ "node": ">=6" } }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -3508,6 +3962,21 @@ "node": ">=0.10.0" } }, + "node_modules/prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -3557,9 +4026,9 @@ "dev": true }, "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" @@ -3574,6 +4043,12 @@ "node": ">=0.6" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -3732,6 +4207,12 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -3781,6 +4262,12 @@ "rimraf": "bin.js" } }, + "node_modules/rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true + }, "node_modules/run-async": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", @@ -3826,6 +4313,18 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/selenium-webdriver": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.3.1.tgz", @@ -4313,6 +4812,12 @@ "node": ">=4" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, "node_modules/table": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", @@ -4521,6 +5026,18 @@ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true }, + "node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dev": true, + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", @@ -4635,6 +5152,15 @@ "node": ">=4" } }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", @@ -4738,6 +5264,16 @@ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/url-parse-lax": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", @@ -4774,30 +5310,97 @@ "uuid": "bin/uuid" } }, - "node_modules/uuid-validate": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/uuid-validate/-/uuid-validate-0.0.3.tgz", - "integrity": "sha512-Fykw5U4eZESbq739BeLvEBFRuJODfrlmjx5eJux7W817LjRaq4b7/i4t2zxQmhcX+fAj4nMfRdTzO4tmwLKn0w==", - "dev": true + "node_modules/uuid-validate": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/uuid-validate/-/uuid-validate-0.0.3.tgz", + "integrity": "sha512-Fykw5U4eZESbq739BeLvEBFRuJODfrlmjx5eJux7W817LjRaq4b7/i4t2zxQmhcX+fAj4nMfRdTzO4tmwLKn0w==", + "dev": true + }, + "node_modules/v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "dev": true, + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/v8-compile-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", - "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", - "dev": true + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true, + "engines": { + "node": ">=12" + } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "node_modules/whatwg-url": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", + "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", "dev": true, - "engines": [ - "node >=0.6.0" - ], "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=14" } }, "node_modules/which": { @@ -4939,16 +5542,16 @@ } }, "node_modules/ws": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", - "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", + "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", "dev": true, "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -4968,6 +5571,21 @@ "node": ">=4" } }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "node_modules/y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", @@ -5094,6 +5712,18 @@ "js-tokens": "^4.0.0" } }, + "@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true + }, + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -5101,17 +5731,36 @@ "dev": true }, "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, + "acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "dev": true, + "requires": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, "acorn-jsx": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", "dev": true }, + "acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "requires": { + "acorn": "^8.11.0" + } + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -5482,6 +6131,16 @@ "unset-value": "^1.0.0" } }, + "call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -5762,6 +6421,15 @@ "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", "dev": true }, + "cssstyle": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", + "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", + "dev": true, + "requires": { + "rrweb-cssom": "^0.6.0" + } + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -5771,6 +6439,17 @@ "assert-plus": "^1.0.0" } }, + "data-urls": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", + "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^12.0.0" + } + }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -5794,6 +6473,12 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "decimal.js": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", + "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==", + "dev": true + }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", @@ -5892,6 +6577,15 @@ "esutils": "^2.0.2" } }, + "domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "dev": true, + "requires": { + "webidl-conversions": "^7.0.0" + } + }, "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", @@ -5907,6 +6601,17 @@ "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", "dev": true }, + "dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "requires": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + } + }, "duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -5935,6 +6640,12 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "entities": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz", + "integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==", + "dev": true + }, "es-abstract": { "version": "1.17.6", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", @@ -5954,6 +6665,39 @@ "string.prototype.trimstart": "^1.0.1" } }, + "es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true + }, + "es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "requires": { + "es-errors": "^1.3.0" + } + }, + "es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + } + }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -5971,6 +6715,26 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "source-map": "~0.6.1" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, "eslint": { "version": "6.7.2", "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.7.2.tgz", @@ -6124,6 +6888,14 @@ "acorn": "^7.1.0", "acorn-jsx": "^5.1.0", "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + } } }, "esprima": { @@ -6510,9 +7282,9 @@ } }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true }, "functional-red-black-tree": { @@ -6533,6 +7305,34 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, + "get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "requires": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + } + }, + "get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "requires": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + } + }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", @@ -6607,6 +7407,12 @@ "type-fest": "^0.8.1" } }, + "gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true + }, "got": { "version": "6.7.1", "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", @@ -6683,11 +7489,20 @@ "dev": true }, "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true }, + "has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.3" + } + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -6720,12 +7535,58 @@ } } }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "requires": { + "whatwg-encoding": "^2.0.0" + } + }, + "http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "requires": { + "ms": "^2.1.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -7091,6 +7952,12 @@ "isobject": "^3.0.1" } }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", @@ -7197,6 +8064,66 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, + "jsdom": { + "version": "21.1.2", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.1.2.tgz", + "integrity": "sha512-sCpFmK2jv+1sjff4u7fzft+pUh2KSUbUrEHYHyfSIbGTIcmnjyp83qg6qLwdJ/I3LpTXx33ACxeRL7Lsyc6lGQ==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "acorn": "^8.8.2", + "acorn-globals": "^7.0.0", + "cssstyle": "^3.0.0", + "data-urls": "^4.0.0", + "decimal.js": "^10.4.3", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.4", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^12.0.1", + "ws": "^8.13.0", + "xml-name-validator": "^4.0.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.12" + } + }, + "tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + } + } + } + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -7350,6 +8277,12 @@ "object-visit": "^1.0.0" } }, + "math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -7624,6 +8557,12 @@ "path-key": "^2.0.0" } }, + "nwsapi": { + "version": "2.2.20", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.20.tgz", + "integrity": "sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==", + "dev": true + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -7808,6 +8747,15 @@ "callsites": "^3.0.0" } }, + "parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "requires": { + "entities": "^6.0.0" + } + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -7889,6 +8837,12 @@ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", "dev": true }, + "prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "dev": true + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -7929,9 +8883,9 @@ "dev": true }, "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, "qs": { @@ -7940,6 +8894,12 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -8071,6 +9031,12 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -8108,6 +9074,12 @@ "glob": "^7.1.3" } }, + "rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true + }, "run-async": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", @@ -8147,6 +9119,15 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, "selenium-webdriver": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.3.1.tgz", @@ -8547,6 +9528,12 @@ "has-flag": "^3.0.0" } }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, "table": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", @@ -8718,6 +9705,15 @@ } } }, + "tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dev": true, + "requires": { + "punycode": "^2.3.0" + } + }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", @@ -8810,6 +9806,12 @@ "crypto-random-string": "^1.0.0" } }, + "universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true + }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", @@ -8895,6 +9897,16 @@ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "url-parse-lax": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", @@ -8945,6 +9957,57 @@ "extsprintf": "^1.2.0" } }, + "w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "dev": true, + "requires": { + "xml-name-validator": "^4.0.0" + } + }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true + }, + "whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "requires": { + "iconv-lite": "0.6.3" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, + "whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true + }, + "whatwg-url": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", + "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", + "dev": true, + "requires": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -9062,9 +10125,9 @@ } }, "ws": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz", - "integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==", + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", + "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", "dev": true, "requires": {} }, @@ -9074,6 +10137,18 @@ "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", "dev": true }, + "xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", diff --git a/package.json b/package.json index e8fe1bba..fab35be4 100644 --- a/package.json +++ b/package.json @@ -3,13 +3,19 @@ "version": "9.0.0", "description": "Simple Analytics visitor facing scripts", "main": "compile.js", + "engines": { + "node": "22.16" + }, "scripts": { "playground": "./playground.sh", "watch": "node_modules/.bin/nodemon compile.js --ignore dist", "build": "node compile.js", + "lint": "./node_modules/.bin/eslint --ext .js .", "pretest": "npm run build -- testing", "test": "node -r dotenv/config ./test/index.js", - "posttest": "npm run build" + "posttest": "npm run build", + "prettier": "prettier --check .", + "test:unit": "npm run build -- testing && mocha ./test/unit && git checkout dist" }, "repository": { "type": "git", @@ -23,6 +29,7 @@ }, "homepage": "https://github.com/simpleanalytics/scripts#readme", "devDependencies": { + "acorn": "^8.11.3", "browserstack-local": "^1.5.1", "chai": "^4.2.0", "dotenv": "^8.2.0", @@ -31,9 +38,11 @@ "handlebars": "^4.7.6", "mocha": "^6.2.3", "nodemon": "^1.19.4", + "prettier": "3.2.5", "request": "^2.88.0", "selenium-webdriver": "^4.3.1", "uglify-js": "^3.9.4", - "uuid-validate": "0.0.3" + "uuid-validate": "0.0.3", + "jsdom": "^21.1.0" } } diff --git a/playground/callback.html b/playground/callback.html index fd6069af..9f1bdfdb 100644 --- a/playground/callback.html +++ b/playground/callback.html @@ -1,4 +1,4 @@ - + @@ -46,7 +46,8 @@ @font-face { font-family: "Space Grotesk"; font-weight: 500; - src: url("https://assets.simpleanalytics.com/fonts/SpaceGrotesk-Medium.woff2") + src: + url("https://assets.simpleanalytics.com/fonts/SpaceGrotesk-Medium.woff2") format("woff2"), url("https://assets.simpleanalytics.com/fonts/SpaceGrotesk-Medium.woff") format("woff"); @@ -54,7 +55,8 @@ @font-face { font-family: "Space Grotesk"; font-weight: 400; - src: url("https://assets.simpleanalytics.com/fonts/SpaceGrotesk-Regular.woff2") + src: + url("https://assets.simpleanalytics.com/fonts/SpaceGrotesk-Regular.woff2") format("woff2"), url("https://assets.simpleanalytics.com/fonts/SpaceGrotesk-Regular.woff") format("woff"); @@ -179,9 +181,8 @@

Automated events

return param; }) .join(" "); - document.querySelector( - "textarea" - ).value += `${type.toUpperCase()}: ${line}\n`; + document.querySelector("textarea").value += + `${type.toUpperCase()}: ${line}\n`; } console.log = function () { diff --git a/playground/events.html b/playground/events.html index 05f871a2..2e8fe67c 100644 --- a/playground/events.html +++ b/playground/events.html @@ -1,4 +1,4 @@ - + @@ -67,7 +67,8 @@ @font-face { font-family: "Space Grotesk"; font-weight: 500; - src: url("https://assets.simpleanalytics.com/fonts/SpaceGrotesk-Medium.woff2") + src: + url("https://assets.simpleanalytics.com/fonts/SpaceGrotesk-Medium.woff2") format("woff2"), url("https://assets.simpleanalytics.com/fonts/SpaceGrotesk-Medium.woff") format("woff"); @@ -75,7 +76,8 @@ @font-face { font-family: "Space Grotesk"; font-weight: 400; - src: url("https://assets.simpleanalytics.com/fonts/SpaceGrotesk-Regular.woff2") + src: + url("https://assets.simpleanalytics.com/fonts/SpaceGrotesk-Regular.woff2") format("woff2"), url("https://assets.simpleanalytics.com/fonts/SpaceGrotesk-Regular.woff") format("woff"); @@ -206,9 +208,8 @@

Automated events

return param; }) .join(" "); - document.querySelector( - "textarea" - ).value += `${type.toUpperCase()}: ${line}\n`; + document.querySelector("textarea").value += + `${type.toUpperCase()}: ${line}\n`; } console.log = function () { diff --git a/src/auto-events.js b/src/auto-events.js index 0df03611..3f08e13f 100644 --- a/src/auto-events.js +++ b/src/auto-events.js @@ -73,7 +73,7 @@ if (typeof optionsLink === "undefined") log("options object not found, please specify", "warn"); - window.saAutomatedLink = function saAutomatedLink(element, type) { + var saAutomatedLink = function saAutomatedLink(element, type) { try { if (!element) return log("no element found"); var sent = false; @@ -146,7 +146,10 @@ } }; + window.saAutomatedLink = saAutomatedLink; + function collectLink(link, onclick) { + if (link.hasAttribute("data-simple-event")) return; var collect = false; // Collect download clicks @@ -186,8 +189,8 @@ link.setAttribute("onclick", onClickAttribute); } else { - link.addEventListener("click", function (element) { - saAutomatedLink(element.target, collect); + link.addEventListener("click", function () { + saAutomatedLink(link, collect); }); } } diff --git a/src/default.js b/src/default.js index dfeccbd9..2b4e925e 100644 --- a/src/default.js +++ b/src/default.js @@ -117,8 +117,8 @@ return Array.isArray(csv) ? csv : isString(csv) && csv.length - ? csv.split(/, ?/) - : []; + ? csv.split(/, ?/) + : []; }; var isObject = function (object) { @@ -165,6 +165,7 @@ }).length === 0 ); /** else **/ + // eslint-disable-next-line no-unreachable return true; /** endif **/ }; @@ -205,11 +206,17 @@ defaultNamespace; /** if metadata **/ - var metadataObject = window[namespace + "_metadata"]; var appendMetadata = function (metadata, data) { + var metadataObject = window[namespace + "_metadata"]; if (isObject(metadataObject)) metadata = assign(metadata, metadataObject); var metadataCollectorFunction = window[metadataCollector]; - if (!isFunction(metadataCollectorFunction)) return metadata; + if (!isFunction(metadataCollectorFunction)) { + if (metadataCollector) + warn( + metadataCollector + " not found, set window." + metadataCollector + ); + return metadata; + } try { return assign( metadata, @@ -231,9 +238,9 @@ overwriteOptions.strictUtm || attr(scriptElement, "strict-utm") == trueText; - var getQueryParams = function (ignoreSource) { + var getQueryParams = function (ignoreSource, overwriteSearch) { return ( - loc.search + (overwriteSearch || loc.search) .slice(1) .split("&") .filter(function (keyValue) { @@ -253,6 +260,7 @@ if (ignore && !allowParams.length) return falseVar; /** else **/ if (ignore) return falseVar; + // eslint-disable-next-line no-redeclare var regex = "^((utm_)" + (strictUtm ? "" : "?") + @@ -486,17 +494,19 @@ // /** if botdetection **/ + var phantom = window.phantom; var bot = nav.webdriver || window.__nightmare || window.callPhantom || window._phantom || - window.phantom || + (phantom && !phantom.solana) || window.__polypane || window._bot || isBotAgent || Math.random() == Math.random(); /** else **/ + // eslint-disable-next-line no-redeclare var bot = isBotAgent; /** endif **/ @@ -584,8 +594,12 @@ var lastSendPath; var getReferrer = function () { + // Customers can overwrite their referrer, here we check for that + var overwrittenReferrer = + overwriteOptions.referrer || attr(scriptElement, "referrer"); + return ( - (doc.referrer || "") + (overwrittenReferrer || doc.referrer || "") .replace(locationHostname, definedHostname) .replace(/^https?:\/\/((m|l|w{2,3}([0-9]+)?)\.)?([^?#]+)(.*)$/, "$4") .replace(/^([^/]+)$/, "$1") || undefinedVar @@ -630,7 +644,12 @@ // sendData will assign payload to request sendData(append, undefinedVar, trueVar); } else { - nav.sendBeacon(fullApiUrl + "/append", stringify(append)); + try { + nav.sendBeacon.bind(nav)(fullApiUrl + "/append", stringify(append)); + } catch (e) { + // Fallback for browsers throwing "Illegal invocation" when the URL is invalid + sendData(append, undefinedVar, trueVar); + } } }; @@ -737,23 +756,28 @@ isPushState, deleteSourceInfo, sameSite, - metadata + query, + metadata, + callback ) { if (isPushState) sendOnLeave("" + payload.page_id, trueVar); if (collectDataOnLeave) payload.page_id = uuid(); var currentPage = definedHostname + getPath(); - sendData({ - id: payload.page_id, - type: pageviewText, - referrer: !deleteSourceInfo || sameSite ? referrer : null, - query: getQueryParams(deleteSourceInfo), - - /** if metadata **/ - metadata: stringify(metadata), - /** endif **/ - }); + sendData( + { + id: payload.page_id, + type: pageviewText, + referrer: !deleteSourceInfo || sameSite ? referrer : null, + query: query || getQueryParams(deleteSourceInfo), + + /** if metadata **/ + metadata: stringify(metadata), + /** endif **/ + }, + callback + ); previousReferrer = referrer; referrer = currentPage; @@ -763,7 +787,21 @@ var sameSite, userNavigated; - var pageview = function (isPushState, pathOverwrite, metadata) { + var pageview = function ( + isPushState, + pathOverwrite, + metadata, + callbackRaw + ) { + if (!callbackRaw && isFunction(metadata)) callbackRaw = metadata; + var callback = isFunction(callbackRaw) ? callbackRaw : function () {}; + var querySearch; + if (isString(pathOverwrite) && pathOverwrite.indexOf("?") > -1) { + // keep query from manual path + var parts = pathOverwrite.split("?"); + pathOverwrite = parts.shift(); + querySearch = "?" + parts.join("?"); + } // Obfuscate personal data in URL by dropping the search and hash var path = getPath(pathOverwrite); @@ -837,7 +875,10 @@ /** if uniques **/ // We set unique variable based on pushstate or back navigation, if no match we check the referrer - page.unique = isPushState || userNavigated ? falseVar : !sameSite; + page.unique = + /__cf_/.test(getReferrer()) || isPushState || userNavigated + ? falseVar + : !sameSite; /** endif **/ /** if metadata **/ @@ -849,11 +890,15 @@ var triggerSendPageView = function () { fetchedHighEntropyValues = trueVar; + var delSrc = + isPushState || userNavigated || !collectMetricByString("r"); sendPageView( isPushState, - isPushState || userNavigated || !collectMetricByString("r"), // r = referrers + delSrc, // r = referrers sameSite, - metadata + querySearch ? getQueryParams(delSrc, querySearch) : undefinedVar, + metadata, + callback ); }; @@ -948,17 +993,17 @@ /** if (or spa hash) **/ if (autoCollect) pageview(); - else { - /** if metadata **/ - window.sa_pageview = function (path, metadata) { - pageview(0, path, metadata); - }; - /** else **/ - window.sa_pageview = function (path) { - pageview(0, path); - }; - /** endif **/ - } + + /** if metadata **/ + window.sa_pageview = function (path, metadata, callback) { + pageview(0, path, metadata, callback); + }; + /** else **/ + window.sa_pageview = function (path, callback) { + pageview(0, path, undefinedVar, callback); + }; + /** endif **/ + /** else **/ pageview(); /** endif **/ diff --git a/test/helpers/index.js b/test/helpers/index.js index 25544d7c..0d3c1768 100644 --- a/test/helpers/index.js +++ b/test/helpers/index.js @@ -1,5 +1,4 @@ const crypto = require("crypto"); -const { networkInterfaces: getNetworkInterfaces } = require("os"); const { DEBUG, SERVER_PORT } = require("../constants"); const { promisify } = require("util"); const { By, Key } = require("selenium-webdriver"); diff --git a/test/helpers/server.js b/test/helpers/server.js index 18ef4dfe..2c2d0122 100644 --- a/test/helpers/server.js +++ b/test/helpers/server.js @@ -1,7 +1,7 @@ const url = require("url"); const http = require("http"); const { readFileSync } = require("fs"); -const { SERVER_PORT, DEBUG, CI } = require("../constants"); +const { SERVER_PORT, DEBUG } = require("../constants"); const { getJSONBody } = require("./request"); const log = (...messages) => diff --git a/test/index.js b/test/index.js index 8bafc945..de55a7ec 100644 --- a/test/index.js +++ b/test/index.js @@ -231,7 +231,7 @@ const getDeviceName = ({ suiteInstance.addTest( new Mocha.Test(`Test Node.js environment`, async function () { - expect(process.version, "Should use Node.js 16.16").to.match(/^v16\.16/); + expect(process.version, "Should use Node.js 22.16").to.match(/^v22\.16/); }) ); @@ -267,12 +267,14 @@ const getDeviceName = ({ if (nextDriver) { log(`Reusing next driver...`); driver = await nextDriver; + // eslint-disable-next-line require-atomic-updates nextDriver = null; } else { log(`Waiting to get ${browser.name}...`); driver = await getDriverWithTimeout(browser); } + // eslint-disable-next-line require-atomic-updates nextDriver = backgroundDriver; // Try again with new device when driver is not available @@ -328,8 +330,6 @@ const getDeviceName = ({ // Empty global REQUESTS global.REQUESTS = []; - let errorMessage = null; - try { await navigate({ ...browser, @@ -383,9 +383,6 @@ const getDeviceName = ({ }); await require("./test-events")(browser); - } catch (error) { - errorMessage = error.message; - throw error; } finally { // if (!driver) return; // try { diff --git a/test/unit/auto-events.test.js b/test/unit/auto-events.test.js new file mode 100644 index 00000000..48beb50e --- /dev/null +++ b/test/unit/auto-events.test.js @@ -0,0 +1,67 @@ +const { expect } = require("chai"); +const { createDOM } = require("./helpers/dom-auto-events"); + +function setupDOM() { + const events = []; + const dom = createDOM({ + beforeRun(vm) { + vm.sa_event = function (name, metadata, cb) { + events.push({ name, metadata }); + if (typeof cb === "function") cb(); + }; + vm.sa_event_loaded = true; + }, + }); + dom.events = events; + return dom; +} + +describe("auto-events", function () { + it("tracks outbound link clicks", function (done) { + const dom = setupDOM(); + const link = dom.window.document.createElement("a"); + link.href = "https://example.org/path"; + link.target = "_blank"; + dom.window.document.body.appendChild(link); + + dom.window.saAutomatedLink(link, "outbound"); + + setTimeout(() => { + expect(dom.events[0]).to.deep.include({ name: "outbound_example_org" }); + expect(dom.events[0].metadata).to.include({ url: link.href }); + done(); + }, 0); + }); + + it("tracks download link clicks", function (done) { + const dom = setupDOM(); + const link = dom.window.document.createElement("a"); + link.href = "https://example.com/file.pdf"; + link.target = "_blank"; + dom.window.document.body.appendChild(link); + + dom.window.saAutomatedLink(link, "download"); + + setTimeout(() => { + expect(dom.events[0]).to.deep.include({ name: "download_file_pdf" }); + expect(dom.events[0].metadata).to.include({ url: link.href }); + done(); + }, 0); + }); + + it("tracks email link clicks", function (done) { + const dom = setupDOM(); + const link = dom.window.document.createElement("a"); + link.href = "mailto:test@example.com"; + link.target = "_blank"; + dom.window.document.body.appendChild(link); + + dom.window.saAutomatedLink(link, "email"); + + setTimeout(() => { + expect(dom.events[0]).to.deep.include({ name: "email_test_example_com" }); + expect(dom.events[0].metadata).to.include({ email: "test@example.com" }); + done(); + }, 0); + }); +}); diff --git a/test/unit/helpers/dom-auto-events.js b/test/unit/helpers/dom-auto-events.js new file mode 100644 index 00000000..eaf7ccc7 --- /dev/null +++ b/test/unit/helpers/dom-auto-events.js @@ -0,0 +1,78 @@ +const { JSDOM } = require("jsdom"); +const { readFileSync } = require("fs"); +const vm = require("vm"); + +const SCRIPT_PATH = "dist/latest/auto-events.js"; + +/** + * @typedef {"navigate" | "reload" | "back_forward" | "prerender"} NavigationType + */ + +/** @type {Record} */ +const NAVIGATION_TYPES = { + navigate: { name: "navigate", code: 0 }, + reload: { name: "reload", code: 1 }, + back_forward: { name: "back_forward", code: 2 }, + prerender: { name: "prerender", code: 255 }, +}; + +function createDOM(options = {}) { + const { + url = "https://example.com/", + navigationType = "navigate", + settings, + beforeRun, + } = options; + const dom = new JSDOM("", { + url, + runScripts: "outside-only", + pretendToBeVisual: true, + }); + + if (settings) { + vm.runInContext( + `window.sa_settings = ${JSON.stringify(settings)}`, + dom.getInternalVMContext() + ); + } + + if (typeof beforeRun === "function") beforeRun(dom.getInternalVMContext()); + + const sent = []; + dom.window.Image = function () { + return { + set src(value) { + sent.push({ type: "image", url: value }); + }, + }; + }; + dom.window.navigator.sendBeacon = function (url, data) { + sent.push({ type: "beacon", url, data }); + return true; + }; + + Object.defineProperty(dom.window, "performance", { + writable: true, + value: { + getEntriesByType: function (type) { + if (type === "navigation") { + return [{ type: NAVIGATION_TYPES[navigationType].name }]; + } + return []; + }, + navigation: { type: NAVIGATION_TYPES[navigationType].code }, + }, + }); + + const script = readFileSync(SCRIPT_PATH, "utf8"); + vm.runInContext(script, dom.getInternalVMContext()); + + dom.sent = sent; + return dom; +} + +module.exports = { + createDOM, + SCRIPT_PATH, + NAVIGATION_TYPES, +}; diff --git a/test/unit/helpers/dom.js b/test/unit/helpers/dom.js new file mode 100644 index 00000000..b0f2bae3 --- /dev/null +++ b/test/unit/helpers/dom.js @@ -0,0 +1,78 @@ +const { JSDOM } = require("jsdom"); +const { readFileSync } = require("fs"); +const vm = require("vm"); + +const SCRIPT_PATH = "dist/latest/latest.dev.js"; + +/** + * @typedef {"navigate" | "reload" | "back_forward" | "prerender"} NavigationType + */ + +/** @type {Record} */ +const NAVIGATION_TYPES = { + navigate: { name: "navigate", code: 0 }, + reload: { name: "reload", code: 1 }, + back_forward: { name: "back_forward", code: 2 }, + prerender: { name: "prerender", code: 255 }, +}; + +function createDOM(options = {}) { + const { + url = "https://example.com/", + navigationType = "navigate", + settings, + beforeRun, + } = options; + const dom = new JSDOM("", { + url, + runScripts: "outside-only", + pretendToBeVisual: true, + }); + + if (settings) { + vm.runInContext( + `window.sa_settings = ${JSON.stringify(settings)}`, + dom.getInternalVMContext() + ); + } + + if (typeof beforeRun === "function") beforeRun(dom.getInternalVMContext()); + + const sent = []; + dom.window.Image = function () { + return { + set src(value) { + sent.push({ type: "image", url: value }); + }, + }; + }; + dom.window.navigator.sendBeacon = function (url, data) { + sent.push({ type: "beacon", url, data }); + return true; + }; + + Object.defineProperty(dom.window, "performance", { + writable: true, + value: { + getEntriesByType: function (type) { + if (type === "navigation") { + return [{ type: NAVIGATION_TYPES[navigationType].name }]; + } + return []; + }, + navigation: { type: NAVIGATION_TYPES[navigationType].code }, + }, + }); + + const script = readFileSync(SCRIPT_PATH, "utf8"); + vm.runInContext(script, dom.getInternalVMContext()); + + dom.sent = sent; + return dom; +} + +module.exports = { + createDOM, + SCRIPT_PATH, + NAVIGATION_TYPES, +}; diff --git a/test/unit/helpers/index.js b/test/unit/helpers/index.js new file mode 100644 index 00000000..385a0601 --- /dev/null +++ b/test/unit/helpers/index.js @@ -0,0 +1 @@ +module.exports = require("./dom"); diff --git a/test/unit/ignore-pages.test.js b/test/unit/ignore-pages.test.js new file mode 100644 index 00000000..df7b5387 --- /dev/null +++ b/test/unit/ignore-pages.test.js @@ -0,0 +1,26 @@ +const { expect } = require("chai"); +const { createDOM } = require("./helpers/dom"); + +describe("ignore pages", function () { + it("does not send a request for ignored paths", function (done) { + const dom = createDOM({ + settings: { autoCollect: false, ignorePages: "/ignore" }, + }); + + dom.window.sa_pageview("/ignore"); + dom.window.sa_pageview("/allowed"); + + setTimeout(() => { + const ignoreReq = dom.sent.find( + (r) => r.type === "image" && /path=%2Fignore/.test(r.url) + ); + const allowedReq = dom.sent.find( + (r) => r.type === "image" && /path=%2Fallowed/.test(r.url) + ); + + expect(ignoreReq, "request for ignored path").to.not.exist; + expect(allowedReq, "request for allowed path").to.exist; + done(); + }, 10); + }); +}); diff --git a/test/unit/metadata-attr.test.js b/test/unit/metadata-attr.test.js new file mode 100644 index 00000000..5b473bdb --- /dev/null +++ b/test/unit/metadata-attr.test.js @@ -0,0 +1,33 @@ +const { expect } = require("chai"); +const { createDOM } = require("./helpers/dom"); + +describe("metadata via data attribute", function () { + it("uses data-metadata-collector attribute", function (done) { + const dom = createDOM({ + settings: { autoCollect: false }, + beforeRun(vmContext) { + const { runInContext } = require("vm"); + runInContext( + "window.collector = function(data){ return { fromAttr: true, path: data.path }; };" + + "Object.defineProperty(document, 'currentScript', {get: function(){ return { getAttribute: function(name){ return name === 'data-metadata-collector' ? 'collector' : null; } }; }});", + vmContext + ); + }, + }); + + dom.window.sa_pageview("/attr"); + + setTimeout(() => { + const req = dom.sent.find( + (r) => r.type === "image" && /path=%2Fattr/.test(r.url) + ); + expect(req, "pageview request").to.exist; + const url = new URL(req.url); + const meta = JSON.parse( + decodeURIComponent(url.searchParams.get("metadata")) + ); + expect(meta).to.include({ fromAttr: true }); + done(); + }, 10); + }); +}); diff --git a/test/unit/metadata.test.js b/test/unit/metadata.test.js new file mode 100644 index 00000000..b5270b62 --- /dev/null +++ b/test/unit/metadata.test.js @@ -0,0 +1,85 @@ +const { expect } = require("chai"); +const { createDOM } = require("./helpers/dom"); + +describe("metadata", function () { + it("collects metadata from global object and collector", function (done) { + const dom = createDOM({ + settings: { autoCollect: false, metadataCollector: "collector" }, + beforeRun(vmContext) { + const { runInContext } = require("vm"); + runInContext( + "window.sa_metadata = { fromGlobal: true };" + + "window.collector = function(data){ return { fromCollector: true, path: data.path }; };", + vmContext + ); + }, + }); + + const { runInContext } = require("vm"); + runInContext( + "window.manualMeta = { manual: true };", + dom.getInternalVMContext() + ); + dom.window.sa_pageview("/meta", dom.window.manualMeta); + + setTimeout(() => { + const req = dom.sent.find( + (r) => r.type === "image" && /path=%2Fmeta/.test(r.url) + ); + expect(req, "pageview request").to.exist; + const url = new URL(req.url); + const meta = JSON.parse( + decodeURIComponent(url.searchParams.get("metadata")) + ); + expect(meta).to.include({ + manual: true, + fromGlobal: true, + fromCollector: true, + }); + done(); + }, 10); + }); + + it("reloads global metadata on each call", function (done) { + const dom = createDOM({ settings: { autoCollect: false } }); + const { runInContext } = require("vm"); + + runInContext( + "window.sa_metadata = { first: true };", + dom.getInternalVMContext() + ); + + dom.window.sa_pageview("/first"); + + setTimeout(() => { + let req = dom.sent.find( + (r) => r.type === "image" && /path=%2Ffirst/.test(r.url) + ); + expect(req, "first pageview request").to.exist; + let url = new URL(req.url); + let meta = JSON.parse( + decodeURIComponent(url.searchParams.get("metadata")) + ); + expect(meta).to.include({ first: true }); + + runInContext( + "window.sa_metadata = { second: true };", + dom.getInternalVMContext() + ); + + dom.window.sa_pageview("/second"); + + setTimeout(() => { + req = dom.sent.find( + (r) => r.type === "image" && /path=%2Fsecond/.test(r.url) + ); + expect(req, "second pageview request").to.exist; + url = new URL(req.url); + meta = JSON.parse(decodeURIComponent(url.searchParams.get("metadata"))); + expect(meta).to.include({ second: true }); + expect(meta).to.not.have.property("first"); + done(); + }, 10); + }, 10); + }); +}); diff --git a/test/unit/pageview-callback.test.js b/test/unit/pageview-callback.test.js new file mode 100644 index 00000000..6929b316 --- /dev/null +++ b/test/unit/pageview-callback.test.js @@ -0,0 +1,34 @@ +const { expect } = require("chai"); +const { createDOM } = require("./helpers/dom"); + +describe("pageview callback", function () { + it("executes callback after sending a pageview", function (done) { + const dom = createDOM({ settings: { autoCollect: false } }); + + const sent = dom.sent; + dom.window.Image = function () { + return { + onload: null, + onerror: null, + set src(value) { + sent.push({ type: "image", url: value }); + if (this.onload) this.onload(); + }, + }; + }; + + let called = false; + dom.window.sa_pageview("/callback", function () { + called = true; + }); + + setTimeout(() => { + const req = dom.sent.find( + (r) => r.type === "image" && /path=%2Fcallback/.test(r.url) + ); + expect(req, "pageview request").to.exist; + expect(called, "callback called").to.be.true; + done(); + }, 10); + }); +}); diff --git a/test/unit/pageview-query.test.js b/test/unit/pageview-query.test.js new file mode 100644 index 00000000..0f4478d3 --- /dev/null +++ b/test/unit/pageview-query.test.js @@ -0,0 +1,22 @@ +const { expect } = require("chai"); +const { createDOM } = require("./helpers/dom"); + +describe("pageview query", function () { + it("sends query params from manual path", function (done) { + const dom = createDOM({ + settings: { autoCollect: false, allowParams: "foo" }, + }); + + dom.window.sa_pageview("/manual?foo=bar"); + + setTimeout(() => { + const req = dom.sent.find( + (r) => r.type === "image" && /path=%2Fmanual/.test(r.url) + ); + expect(req, "pageview request").to.exist; + const url = new URL(req.url); + expect(url.searchParams.get("query")).to.equal("foo=bar"); + done(); + }, 10); + }); +}); diff --git a/test/unit/pageview.test.js b/test/unit/pageview.test.js new file mode 100644 index 00000000..0459f479 --- /dev/null +++ b/test/unit/pageview.test.js @@ -0,0 +1,67 @@ +const { expect } = require("chai"); +const { createDOM } = require("./helpers/dom"); + +describe("pageview", function () { + it("sends pageview, event and beacon requests", function (done) { + const dom = createDOM({ navigationType: "reload" }); + + dom.window.sa_event("unit_test"); + + if (!("onpagehide" in dom.window)) { + dom.window.document.hidden = true; + dom.window.document.dispatchEvent( + new dom.window.Event("visibilitychange") + ); + } else { + dom.window.dispatchEvent(new dom.window.Event("pagehide")); + } + + setTimeout(() => { + const gif = dom.sent.find( + (r) => r.type === "image" && /simple\.gif/.test(r.url) + ); + const eventReq = dom.sent.find( + (r) => r.type === "image" && /event=unit_test/.test(r.url) + ); + const beacon = dom.sent.find((r) => r.type === "beacon"); + + expect(gif, "pageview gif request").to.exist; + expect(eventReq, "event gif request").to.exist; + expect(beacon, "append beacon request").to.exist; + expect(beacon.url).to.match(/\/append$/); + expect(beacon.data).to.include('"type":"append"'); + + done(); + }, 10); + }); + + it("falls back to pixel when sendBeacon fails", function (done) { + const dom = createDOM({ navigationType: "reload" }); + + dom.window.navigator.sendBeacon = function () { + throw new TypeError("Illegal invocation"); + }; + + dom.window.sa_event("unit_test"); + + if (!("onpagehide" in dom.window)) { + dom.window.document.hidden = true; + dom.window.document.dispatchEvent( + new dom.window.Event("visibilitychange") + ); + } else { + dom.window.dispatchEvent(new dom.window.Event("pagehide")); + } + + setTimeout(() => { + const beacon = dom.sent.find((r) => r.type === "beacon"); + const appendGif = dom.sent.find( + (r) => r.type === "image" && /type=append/.test(r.url) + ); + + expect(beacon, "append beacon request").to.not.exist; + expect(appendGif, "append gif request").to.exist; + done(); + }, 10); + }); +});