diff --git a/SimLoop/docs/assets/javascripts/pageviews.js b/SimLoop/docs/assets/javascripts/pageviews.js new file mode 100644 index 0000000..9ada600 --- /dev/null +++ b/SimLoop/docs/assets/javascripts/pageviews.js @@ -0,0 +1,33 @@ +// Page-view counter for this docs site. Horizon (FTC 36596). +// +// It counts with GoatCounter, but runs no GoatCounter code: this file sends one image request to +// GoatCounter's documented /count endpoint (goatcounter.com/help/pixel). No third-party script is +// loaded on purpose: these pages share an origin with the other sites under +// libraries.horizon36596.org, the Zenith web editor (/zenith/app/) among them, so a third-party +// script here could read their browser storage. +// +// No cookies, no local storage. Sent: the page path and title, the referring page, and the screen +// size. GoatCounter also sees the IP address and browser, as any web request does; it uses them to +// work out the country and to count a reload once, keeps them in memory for at most 8 hours and does +// not store them. The privacy page (privacy.md) says the same; change both together. +// +// Both docs sites (libraries.horizon36596.org/zenith/ and /simloop/) report to ONE GoatCounter site, +// told apart by path. Until the owner creates that site, GOATCOUNTER_CODE is a placeholder and this +// file does nothing. +(function () { + var GOATCOUNTER_CODE = "REPLACE_WITH_GOATCOUNTER_CODE"; + if (GOATCOUNTER_CODE.indexOf("REPLACE_") === 0) return; + // Local previews (mkdocs serve) are not counted. + if (location.hostname !== "libraries.horizon36596.org") return; + if (document.visibilityState === "prerender") return; + var q = [ + "p=" + encodeURIComponent(location.pathname), + "t=" + encodeURIComponent(document.title), + "r=" + encodeURIComponent(document.referrer), + "s=" + [screen.width, screen.height, window.devicePixelRatio || 1].join(","), + "rnd=" + Math.random().toString(36).slice(2), + ]; + // 153 is GoatCounter's "WebDriver-based headless browser" bot flag. + if (navigator.webdriver) q.push("b=153"); + new Image().src = "https://" + GOATCOUNTER_CODE + ".goatcounter.com/count?" + q.join("&"); +})(); diff --git a/SimLoop/docs/privacy.md b/SimLoop/docs/privacy.md new file mode 100644 index 0000000..8af2818 --- /dev/null +++ b/SimLoop/docs/privacy.md @@ -0,0 +1,21 @@ +# Privacy + +SimLoop is a library. It has no analytics and collects nothing about you. + +This documentation site counts page views with [GoatCounter](https://www.goatcounter.com), so we can +see which pages teams read. + +- It sets no cookies and stores nothing in your browser. +- For each page view it records the page and its title, the site that linked you here, your + browser, operating system and screen size, and your country. +- GoatCounter uses your IP address and browser to work out your country and to count a reload only + once. It keeps them in memory for at most 8 hours and never stores them. +- No outside script runs on these pages. Our own page sends one request to GoatCounter; no + GoatCounter code is loaded. +- It cannot tell who you are or follow you to other sites. + +The site is hosted on GitHub Pages, which keeps the routine request logs any website has, such as +your IP address. Its fonts load from Google Fonts, which sees your IP address and browser the same +way. + +Questions: open an issue on [GitHub](https://github.com/Horizon-36596/simloop/issues). diff --git a/SimLoop/mkdocs.yml b/SimLoop/mkdocs.yml index 2eb07b4..308c289 100644 --- a/SimLoop/mkdocs.yml +++ b/SimLoop/mkdocs.yml @@ -83,8 +83,10 @@ extra_css: - stylesheets/horizon.css # The one-time alpha notice; its styles are at the end of horizon.css. +# The cookieless page-view counter; see the file's header and privacy.md. extra_javascript: - javascripts/alpha-notice.js + - assets/javascripts/pageviews.js markdown_extensions: - admonition @@ -133,3 +135,4 @@ nav: - Troubleshooting: troubleshooting.md - Reporting a bug: support.md - Index for AI agents: llms.md + - Privacy: privacy.md