diff --git a/package-lock.json b/package-lock.json
index f664dc3..753020c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "src",
- "version": "2024.12.1",
+ "version": "2024.12.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "src",
- "version": "2024.12.1",
+ "version": "2024.12.2",
"hasInstallScript": true,
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^2.4.1",
diff --git a/package.json b/package.json
index 8604fd8..d382738 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "src",
"private": true,
- "version": "2024.12.1",
+ "version": "2024.12.2",
"type": "module",
"scripts": {
"dev": "vite",
diff --git a/public/404.html b/public/404.html
new file mode 100644
index 0000000..6dc48f9
--- /dev/null
+++ b/public/404.html
@@ -0,0 +1,92 @@
+
+
+
+
+
+ 404
+
+
+
+
+
+
+
+
+
+
+ 404
+ Page Not Found
+
+
+
+
+
diff --git a/public/assets/404.js b/public/assets/404.js
new file mode 100644
index 0000000..825f00a
--- /dev/null
+++ b/public/assets/404.js
@@ -0,0 +1,20 @@
+window.onload = () => {
+ // https://www.syfy.com/sites/syfy/files/2024/07/screenshot_2024-07-14_at_10.45.27_am.jpg
+ fetch('https://hooks.slack.com/services/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', {
+ method: 'POST',
+ headers: {
+ // CORS blocked when this is set
+ // https://stackoverflow.com/questions/45752537/slack-incoming-webhook-request-header-field-content-type-is-not-allowed-by-acce/45752919#45752919
+ // 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ text: window.location.href + '\n' +
+ 'Referrer: ' + (document.referrer || 'N/A')
+ })
+ })
+ .catch(err => console.error(err))
+}
+
+const backBtn = document.querySelector('#back-btn')
+const goBack = () => history.back();
+backBtn.addEventListener('click', goBack)
\ No newline at end of file
diff --git a/public/assets/localStorage.js b/public/assets/localStorage.js
new file mode 100644
index 0000000..12197ac
--- /dev/null
+++ b/public/assets/localStorage.js
@@ -0,0 +1,106 @@
+const $ = (el) => document.getElementById(el)
+const sites = [
+ "https://www.greenfielddemo.com/localStorage.html",
+ "https://www.hello.dev/localStorage.html",
+ "https://www.hello.coop/localStorage.html",
+ "https://console.hello.coop/localStorage.html",
+ "https://playground.hello.dev/localStorage.html",
+ "https://wallet.hello.coop/localStorage.html",
+ "https://quickstart.hello.coop/localStorage.html",
+ "https://blog.hello.coop/localstorage/",
+ "https://www.b2bsaasdemo.com/localStorage.html"
+]
+const hydrate = () => {
+ $("hostname").textContent = window.location.hostname
+ processParams()
+ addList()
+ plausibleIgnoreState()
+}
+
+const processParams = () => {
+ const params = new URLSearchParams(window.location.search)
+ if (!params.get("action") || !params.get("sites")) {
+ cleanURL()
+ return
+ }
+ if (params.get("action") === "ignoreAll") {
+ console.info("Setting plausible_ignore at " + window.location.hostname)
+ localStorage.setItem("plausible_ignore", true)
+ } else if (params.get("action") === "clearAll") {
+ console.info("Clearing localStorage at " + window.location.hostname)
+ localStorage.clear()
+ }
+ let _sites = params.get("sites")
+ _sites = _sites.split(",")
+ _sites.pop()
+ if (!_sites.length) {
+ cleanURL()
+ return
+ }
+ params.set("sites", _sites.toString())
+ const url = new URL(_sites[_sites.length - 1])
+ url.search = params
+ window.location.href = url
+}
+
+const ignoreAll = () => {
+ const url = makeParams("ignoreAll")
+ window.location.href = url
+}
+
+const clearAll = () => {
+ const url = makeParams("clearAll")
+ window.location.href = url
+}
+
+const cleanURL = () => {
+ window.history.pushState(
+ {},
+ document.title,
+ window.location.href.substring(0, window.location.href.indexOf("?"))
+ )
+}
+
+const makeParams = (type) => {
+ let params = new URLSearchParams()
+ if (type === "clearAll") {
+ params.append("action", "clearAll")
+ } else if (type === "ignoreAll") {
+ params.append("action", "ignoreAll")
+ }
+ params.append("sites", sites.toString())
+ const url = new URL(sites[sites.length - 1])
+ url.search = params
+ return url
+}
+
+const plausibleIgnoreState = () => {
+ const checkboxRef = $("plausible_ignore")
+ if (localStorage.getItem("plausible_ignore")) {
+ checkboxRef.checked = true
+ }
+ checkboxRef.addEventListener("change", () => {
+ if (checkboxRef.checked) {
+ console.info("plausible_ignore added to localStorage")
+ localStorage.setItem("plausible_ignore", true)
+ } else {
+ console.info("plausible_ignore removed from localStorage")
+ localStorage.removeItem("plausible_ignore")
+ }
+ })
+}
+
+const addList = () => {
+ const linksRef = $("links")
+ for (const site of sites) {
+ if (site === window.location.href) continue
+ const link = new URL(site)
+ const liEl = document.createElement("li")
+ const aEl = document.createElement("a")
+ aEl.textContent = link.hostname
+ aEl.href = link
+ aEl.classList.add("underline")
+ liEl.appendChild(aEl)
+ linksRef.appendChild(liEl)
+ }
+}
diff --git a/public/localStorage.html b/public/localStorage.html
new file mode 100644
index 0000000..b87b3a1
--- /dev/null
+++ b/public/localStorage.html
@@ -0,0 +1,33 @@
+
+
+
+
+
+ Manage localStorage
+
+
+
+
+
+
+ Manage localStorage
+
+
...
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file