From 2986f020c87a69224233292969d817de6155e658 Mon Sep 17 00:00:00 2001
From: Feuerfuchs <git@feuerfuchs.dev>
Date: Wed, 26 Jun 2019 21:51:25 +0200
Subject: Code cleanup

---
 .drone.yml            | 22 ----------------------
 .gitignore            |  2 ++
 .goreleaser.yml       |  9 ---------
 .vscode/settings.json |  3 ---
 LICENSE               |  3 +--
 Makefile              |  6 +++---
 README.md             | 51 +++++++++++++++++++++++++++++----------------------
 _config.yml           |  1 -
 assets/main.js        |  2 +-
 fonts/glyphs.txt      |  1 +
 glyphs.txt            |  1 -
 js/main.ts            | 20 ++++++++++++++++----
 12 files changed, 53 insertions(+), 68 deletions(-)
 delete mode 100644 .drone.yml
 delete mode 100644 .goreleaser.yml
 delete mode 100644 .vscode/settings.json
 delete mode 100644 _config.yml
 create mode 100644 fonts/glyphs.txt
 delete mode 100644 glyphs.txt

diff --git a/.drone.yml b/.drone.yml
deleted file mode 100644
index 0065a03..0000000
--- a/.drone.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-kind: pipeline
-name: default
-
-steps:
-  - name: build
-    image: golang:latest
-    commands:
-      - make test
-
-  - name: coverage
-    image: plugins/codecov
-    settings:
-      token:
-        from_secret: codecov-token
-
-  - name: notify
-    image: plugins/webhook
-    urls: https://msgbus.mills.io/ci.mills.io
-    when:
-      status:
-        - success
-        - failure
diff --git a/.gitignore b/.gitignore
index 32c3689..e036b02 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,5 @@ dist
 coverage.txt
 
 gopherproxy
+
+.vscode
diff --git a/.goreleaser.yml b/.goreleaser.yml
deleted file mode 100644
index 8376981..0000000
--- a/.goreleaser.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-build:
-  main: cmd/gopherproxy/main.go
-  binary: gopherproxy
-  goos:
-    - windows
-    - darwin
-    - linux
-  goarch:
-    - amd64
diff --git a/.vscode/settings.json b/.vscode/settings.json
deleted file mode 100644
index 8c45cda..0000000
--- a/.vscode/settings.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-    "go.formatTool": "goimports"
-}
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index 72873e6..3595902 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,6 @@
+Copyright (C) 2019 Feuerfuchs <me@feuerfuchs.dev>
 Copyright (C) 2016 James Mills
 
-go-gopher is covered by the MIT license::
-
 Permission is hereby granted, free of charge, to any person
 obtaining a copy of this software and associated documentation
 files (the "Software"), to deal in the Software without restriction,
diff --git a/Makefile b/Makefile
index fa3998e..652aee5 100644
--- a/Makefile
+++ b/Makefile
@@ -7,9 +7,9 @@ dev: build
 
 build: clean
 	sassc -t compressed css/main.scss assets/style.css
-	tsc --strict --module none --outFile /dev/stdout js/KeyValueStore.ts js/main.ts | uglifyjs -c -m -o assets/main.js --
-	pyftsubset fonts/iosevka-term-ss03-regular.ttf --name-IDs+=0,4,6 --text-file=glyphs.txt --flavor='woff' --output-file='assets/iosevka-term-ss03-regular.woff'
-	pyftsubset fonts/iosevka-term-ss03-regular.ttf --name-IDs+=0,4,6 --text-file=glyphs.txt --flavor='woff2' --output-file='assets/iosevka-term-ss03-regular.woff2'
+	tsc --strict --module none --outFile /dev/stdout js/* | uglifyjs -c -m -o assets/main.js --
+	pyftsubset fonts/iosevka-term-ss03-regular.ttf --name-IDs+=0,4,6 --text-file=fonts/glyphs.txt --flavor='woff' --output-file='assets/iosevka-term-ss03-regular.woff'
+	pyftsubset fonts/iosevka-term-ss03-regular.ttf --name-IDs+=0,4,6 --text-file=fonts/glyphs.txt --flavor='woff2' --output-file='assets/iosevka-term-ss03-regular.woff2'
 	go build -o ./gopherproxy ./cmd/gopherproxy/main.go
 
 profile:
diff --git a/README.md b/README.md
index 4b89136..49ed7c5 100644
--- a/README.md
+++ b/README.md
@@ -1,45 +1,51 @@
 # Gopher (RFC 1436) Web Proxy
 
-[![Build Status](https://cloud.drone.io/api/badges/prologic/gopherproxy/status.svg)](https://cloud.drone.io/prologic/gopherproxy)
-[![CodeCov](https://codecov.io/gh/prologic/gopherproxy/branch/master/graph/badge.svg)](https://codecov.io/gh/prologic/gopherproxy)
-[![Go Report Card](https://goreportcard.com/badge/prologic/gopherproxy)](https://goreportcard.com/report/prologic/gopherproxy)
-[![GoDoc](https://godoc.org/git.feuerfuchs.dev/Feuerfuchs/gopherproxy?status.svg)](https://godoc.org/git.feuerfuchs.dev/Feuerfuchs/gopherproxy) 
-[![Sourcegraph](https://sourcegraph.com/git.feuerfuchs.dev/Feuerfuchs/gopherproxy/-/badge.svg)](https://sourcegraph.com/git.feuerfuchs.dev/Feuerfuchs/gopherproxy?badge)
-
 gopherproxy is a Gopher (RFC 1436) Web Proxy that acts as a gateway into Gopherspace
 by proxying standard Web HTTP requests to Gopher requests of the target server.
 
-gopherproxy is written in Go (#golang) using the
-[go-gopher](https://github.com/prologic/go-gopher) library.
+gopherproxy is a fork of https://github.com/prologic/gopherproxy.
+
+Demo: https://gopher.feuerfuchs.dev/
+
+
+## Requirements
+
+gopherproxy requires the following programs and libraries:
+
+- libvips: Fast on-demand thumbnail generation
 
-Demo: https://gopher.mills.io/
 
 ## Installation
   
   $ go install git.feuerfuchs.dev/Feuerfuchs/gopherproxy/...
 
-### Docker
 
-Run directly from a prebuild image from the [Docker Hub](https://hub.docker.com):
+## Usage
 
 ```#!bash
-$ docker run -p 8000:8000 prologic/gopherproxy
+$ gopherproxy
 ```
 
-Or build your own custom image from a source checkout:
+Then simply visit: http://localhost:8000/
 
-```#!bash
-$ docker build -t gopherproxy .
-$ docker run -p 80:80 gopherproxy -uri floodgap.com
-```
 
-## Usage
+## Development
 
-```#!bash
-$ gopherproxy
-```
+For development, the following libraries and programs are required in addition
+to the previously listed ones:
+
+- **SASS (sassc):** Compiling SCSS to CSS
+- **TypeScript (tsc):** Compiling TypeScript to JavaScript
+- **UglifyJS (uglifyjs):** Minifying JavaScript
+- **fonttools (pyftsubset):** Minifying fonts
+
+Folder structure:
+
+- **assets:** Compiled assets that will be embedded into the executable using packr
+- **css:** SCSS source files
+- **fonts:** Fonts that will be minified
+- **js:** TypeScript source files
 
-Then simply visit: http://localhost/gopher.floodgap.com
 
 ## Related
 
@@ -52,6 +58,7 @@ Related projects:
   gopherclient is a cross-platform QT/QML GUI Gopher Client
   using the gopherproxy library as its backend.
 
+
 ## License
 
 MIT
diff --git a/_config.yml b/_config.yml
deleted file mode 100644
index 3397c9a..0000000
--- a/_config.yml
+++ /dev/null
@@ -1 +0,0 @@
-theme: jekyll-theme-architect
\ No newline at end of file
diff --git a/assets/main.js b/assets/main.js
index ab1a9d0..33aa76d 100644
--- a/assets/main.js
+++ b/assets/main.js
@@ -1 +1 @@
-"use strict";var KeyValueStore=function(){function e(e){this.data=e;for(var t=0,n=Object.keys(e);t<n.length;t++){var a=n[t],l=e[a];if(l.valueRange&&-1===l.valueRange.indexOf(l.value))throw new Error('Invalid value "'+l.value+'" for ID "'+a+'"')}}return e.prototype.getValue=function(e){return this.data[e].value},e.prototype.setValue=function(e,t){var n=this.data[e];if(n.valueRange&&-1===n.valueRange.indexOf(t))throw new Error('Invalid value "'+t+'" for ID "'+e+'"');n.value=t,n.callbacks&&n.callbacks.forEach(function(e){e(t)})},e.prototype.cycleValue=function(e,t){void 0===t&&(t=1);var n=this.data[e];if(!n)throw new Error('Invalid ID "'+e+'"');var a=n.value;if(n.valueRange){var l=n.valueRange.indexOf(a)+t;l>=n.valueRange.length?l=0:l<0&&(l=n.valueRange.length-1),a=n.value=n.valueRange[l]}else{if("number"!=typeof a)throw new Error("Can't cycle \""+e+'"');a+=t,n.value=a}return n.callbacks&&n.callbacks.forEach(function(e){e(a)}),a},e.prototype.addCallback=function(e,t){var n=this.data[e];n.callbacks||(n.callbacks=[]),n.callbacks.push(t)},e}();function ensureSetting(e,t){var n=localStorage.getItem(e);return null===n&&(n=t,localStorage.setItem(e,n)),n}var settings=new KeyValueStore({wordWrap:{value:"1"===ensureSetting("word-wrap","1"),valueRange:[!1,!0]},imagePreviews:{value:"1"===ensureSetting("image-previews","1"),valueRange:[!1,!0]},clickablePlainLinks:{value:"1"===ensureSetting("clickable-plain-links","1"),valueRange:[!1,!0]}});function generateImageThumbnails(){for(var r=document.querySelectorAll(".link--IMG, .link--GIF"),s=r.length,e=function(){var e=r[s],t=e.href.replace(/^(.*?)\/I/,"$1/T"),n=document.createTextNode("\n"),a=document.createElement("span");a.classList.add("type-annotation"),a.textContent=" ->  ";var l=document.createElement("img");l.src=t,l.addEventListener("load",function(e){l.classList.remove("faded")});var i=document.createElement("a");i.classList.add("img-preview"),i.href=e.href,i.addEventListener("click",function(e){return e.preventDefault(),l.classList.add("faded"),l.classList.contains("expanded")?(l.classList.remove("expanded"),l.src=t):(l.classList.add("expanded"),l.src=i.href),!1}),i.append(l),e.parentNode.insertBefore(i,e.nextSibling),e.parentNode.insertBefore(a,i),e.parentNode.insertBefore(n,a)};s--;)e()}function removeImageThumbnails(){for(var e=document.querySelectorAll(".link--IMG, .link--GIF"),t=e.length;t--;)for(var n=e[t],a=3;a--&&n.nextSibling;)n.nextSibling.remove()}function generateMarkupForPlainLinks(){if(document.body.classList.contains("is-plain")){var e=document.getElementsByClassName("content")[0];e.innerHTML=e.innerHTML.replace(/\b([a-z]*:\/\/[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,}\b[-a-zA-Z0-9@:%_\+.~#?&//=]*)/g,function(e){var t=e;return 0===t.indexOf("gopher://")&&(t=t.replace(/^gopher:\/\/(.*)$/,location.origin+"/$1")),'<a href="'+t+'">'+e+"</a>"}),e.innerHTML=e.innerHTML.replace(/\bmailto:[-a-zA-Z0-9@:%._\+~#=]+@(?:[-a-zA-Z0-9@:%._\+~#=]+\.)+[a-z]{2,}\b/g,function(e){return'<a href="'+e+'">'+e+"</a>"})}}function removeMarkupForPlainLinks(){if(document.body.classList.contains("is-plain"))for(var e=document.getElementsByClassName("content")[0],t=e.getElementsByTagName("a"),n=t.length;n--;){var a=t[n],l=document.createTextNode(a.textContent);e.replaceChild(l,a)}}!function(){for(var e=document.getElementsByClassName("link--QRY"),t=e.length;t--;)e[t].addEventListener("click",function(e){e.preventDefault();var t=prompt("Please enter required input: ","");return null!==t&&""!==t&&(window.location.href=e.target.href+"?"+t),!1})}(),function(){for(var e=document.getElementsByClassName("location__prefix"),t=e.length;t--;)e[t].addEventListener("click",function(e){e.preventDefault();var t=prompt("Please enter new location: ","");return null!==t&&""!==t.trim()&&(0===(t=t.trim()).indexOf("gopher://")&&(t=t.substring(9)),window.location.href=window.location.origin+"/"+t),!1})}(),function(){function e(e,t){void 0===t&&(t=!1),e?generateImageThumbnails():t||removeImageThumbnails(),localStorage.setItem("image-previews",e?"1":"0"),n.textContent=e?"[yes]":"[no]"}var t=document.getElementsByClassName("content")[0],n=document.getElementsByClassName("setting--image-previews")[0].getElementsByClassName("setting__value")[0];n.addEventListener("click",function(e){return e.preventDefault(),settings.cycleValue("imagePreviews"),!1}),e(settings.getValue("imagePreviews"),!0),settings.addCallback("imagePreviews",e);function a(e){e?t.classList.add("content--wrap"):t.classList.remove("content--wrap"),localStorage.setItem("word-wrap",e?"1":"0"),l.textContent=e?"[yes]":"[no]"}var l=document.getElementsByClassName("setting--word-wrap")[0].getElementsByClassName("setting__value")[0];l.addEventListener("click",function(e){return e.preventDefault(),settings.cycleValue("wordWrap"),!1}),a(settings.getValue("wordWrap")),settings.addCallback("wordWrap",a);function i(e){e?generateMarkupForPlainLinks():removeMarkupForPlainLinks(),localStorage.setItem("clickable-plain-links",e?"1":"0"),r.textContent=e?"[yes]":"[no]"}var r=document.getElementsByClassName("setting--clickable-plain-links")[0].getElementsByClassName("setting__value")[0];r.addEventListener("click",function(e){return e.preventDefault(),settings.cycleValue("clickablePlainLinks"),!1}),i(settings.getValue("clickablePlainLinks")),settings.addCallback("clickablePlainLinks",i)}(),function(){for(var a=document.getElementsByClassName("modal"),l=a.length,e=function(){var t=a[l],n=t.getElementsByClassName("modal__content")[0],e=t.getElementsByClassName("modal__close-btn")[0];document.addEventListener("click",function(e){t.classList.contains("modal--visible")&&(e.target===n||n.contains(e.target)||(t.classList.remove("modal--visible"),e.preventDefault(),e.stopPropagation()))},!0),document.addEventListener("keydown",function(e){t.classList.contains("modal--visible")&&27===e.keyCode&&t.classList.remove("modal--visible")}),e.addEventListener("click",function(e){return e.preventDefault(),t.classList.remove("modal--visible"),!1})};l--;)e();var t=document.getElementsByClassName("settings-btn")[0],n=document.getElementsByClassName("modal--settings")[0];t.addEventListener("click",function(e){return e.preventDefault(),n.classList.add("modal--visible"),!1})}();
\ No newline at end of file
+"use strict";var KeyValueStore=function(){function e(e){this.data=e;for(var t=0,n=Object.keys(e);t<n.length;t++){var a=n[t],l=e[a];if(l.valueRange&&-1===l.valueRange.indexOf(l.value))throw new Error('Invalid value "'+l.value+'" for ID "'+a+'"')}}return e.prototype.getValue=function(e){return this.data[e].value},e.prototype.setValue=function(e,t){var n=this.data[e];if(n.valueRange&&-1===n.valueRange.indexOf(t))throw new Error('Invalid value "'+t+'" for ID "'+e+'"');n.value=t,n.callbacks&&n.callbacks.forEach(function(e){e(t)})},e.prototype.cycleValue=function(e,t){void 0===t&&(t=1);var n=this.data[e];if(!n)throw new Error('Invalid ID "'+e+'"');var a=n.value;if(n.valueRange){var l=n.valueRange.indexOf(a)+t;l>=n.valueRange.length?l=0:l<0&&(l=n.valueRange.length-1),a=n.value=n.valueRange[l]}else{if("number"!=typeof a)throw new Error("Can't cycle \""+e+'"');a+=t,n.value=a}return n.callbacks&&n.callbacks.forEach(function(e){e(a)}),a},e.prototype.addCallback=function(e,t){var n=this.data[e];n.callbacks||(n.callbacks=[]),n.callbacks.push(t)},e}();function ensureSetting(e,t){var n=localStorage.getItem(e);return null===n&&(n=t,localStorage.setItem(e,n)),n}var settings=new KeyValueStore({wordWrap:{value:"1"===ensureSetting("word-wrap","1"),callbacks:[function(e){localStorage.setItem("word-wrap",e?"1":"0")}],valueRange:[!1,!0]},imagePreviews:{value:"1"===ensureSetting("image-previews","1"),callbacks:[function(e){localStorage.setItem("image-previews",e?"1":"0")}],valueRange:[!1,!0]},clickablePlainLinks:{value:"1"===ensureSetting("clickable-plain-links","1"),callbacks:[function(e){localStorage.setItem("clickable-plain-links",e?"1":"0")}],valueRange:[!1,!0]}});function generateImageThumbnails(){for(var r=document.querySelectorAll(".link--IMG, .link--GIF"),s=r.length,e=function(){var e=r[s],t=e.href.replace(/^(.*?)\/I/,"$1/T"),n=document.createTextNode("\n"),a=document.createElement("span");a.classList.add("type-annotation"),a.textContent=" ->  ";var l=document.createElement("img");l.src=t,l.addEventListener("load",function(e){l.classList.remove("faded")});var i=document.createElement("a");i.classList.add("img-preview"),i.href=e.href,i.addEventListener("click",function(e){return e.preventDefault(),l.classList.add("faded"),l.classList.contains("expanded")?(l.classList.remove("expanded"),l.src=t):(l.classList.add("expanded"),l.src=i.href),!1}),i.append(l),e.parentNode.insertBefore(i,e.nextSibling),e.parentNode.insertBefore(a,i),e.parentNode.insertBefore(n,a)};s--;)e()}function removeImageThumbnails(){for(var e=document.querySelectorAll(".link--IMG, .link--GIF"),t=e.length;t--;)for(var n=e[t],a=3;a--&&n.nextSibling;)n.nextSibling.remove()}function generateMarkupForPlainLinks(){if(document.body.classList.contains("is-plain")){var e=document.getElementsByClassName("content")[0];e.innerHTML=e.innerHTML.replace(/\b[a-z]*:\/\/[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,}\b[-a-zA-Z0-9@:%_\+.~#?&//=]*/g,function(e){var t=e;return 0===t.indexOf("gopher://")&&(t=t.replace(/^gopher:\/\/(.*)$/,location.origin+"/$1")),'<a href="'+t+'">'+e+"</a>"}),e.innerHTML=e.innerHTML.replace(/\bmailto:[-a-zA-Z0-9@:%._\+~#=]+@(?:[-a-zA-Z0-9@:%._\+~#=]+\.)+[a-z]{2,}\b/g,function(e){return'<a href="'+e+'">'+e+"</a>"})}}function removeMarkupForPlainLinks(){if(document.body.classList.contains("is-plain"))for(var e=document.getElementsByClassName("content")[0],t=e.getElementsByTagName("a"),n=t.length;n--;){var a=t[n],l=document.createTextNode(a.textContent);e.replaceChild(l,a)}}!function(){for(var e=document.getElementsByClassName("link--QRY"),t=e.length;t--;)e[t].addEventListener("click",function(e){e.preventDefault();var t=prompt("Please enter required input: ","");return null!==t&&""!==t&&(window.location.href=e.target.href+"?"+t),!1})}(),function(){for(var e=document.getElementsByClassName("location__prefix"),t=e.length;t--;)e[t].addEventListener("click",function(e){e.preventDefault();var t=prompt("Please enter new location: ","");return null!==t&&""!==t.trim()&&(0===(t=t.trim()).indexOf("gopher://")&&(t=t.substring(9)),window.location.href=window.location.origin+"/"+t),!1})}(),function(){function e(e,t){void 0===t&&(t=!1),e?generateImageThumbnails():t||removeImageThumbnails(),n.textContent=e?"[yes]":"[no]"}var t=document.getElementsByClassName("content")[0],n=document.getElementsByClassName("setting--image-previews")[0].getElementsByClassName("setting__value")[0];n.addEventListener("click",function(e){return e.preventDefault(),settings.cycleValue("imagePreviews"),!1}),e(settings.getValue("imagePreviews"),!0),settings.addCallback("imagePreviews",e);function a(e){e?t.classList.add("content--wrap"):t.classList.remove("content--wrap"),l.textContent=e?"[yes]":"[no]"}var l=document.getElementsByClassName("setting--word-wrap")[0].getElementsByClassName("setting__value")[0];l.addEventListener("click",function(e){return e.preventDefault(),settings.cycleValue("wordWrap"),!1}),a(settings.getValue("wordWrap")),settings.addCallback("wordWrap",a);function i(e){e?generateMarkupForPlainLinks():removeMarkupForPlainLinks(),r.textContent=e?"[yes]":"[no]"}var r=document.getElementsByClassName("setting--clickable-plain-links")[0].getElementsByClassName("setting__value")[0];r.addEventListener("click",function(e){return e.preventDefault(),settings.cycleValue("clickablePlainLinks"),!1}),i(settings.getValue("clickablePlainLinks")),settings.addCallback("clickablePlainLinks",i)}(),function(){for(var a=document.getElementsByClassName("modal"),l=a.length,e=function(){var t=a[l],n=t.getElementsByClassName("modal__content")[0],e=t.getElementsByClassName("modal__close-btn")[0];document.addEventListener("click",function(e){t.classList.contains("modal--visible")&&(e.target===n||n.contains(e.target)||(t.classList.remove("modal--visible"),e.preventDefault(),e.stopPropagation()))},!0),document.addEventListener("keydown",function(e){t.classList.contains("modal--visible")&&27===e.keyCode&&t.classList.remove("modal--visible")}),e.addEventListener("click",function(e){return e.preventDefault(),t.classList.remove("modal--visible"),!1})};l--;)e();var t=document.getElementsByClassName("settings-btn")[0],n=document.getElementsByClassName("modal--settings")[0];t.addEventListener("click",function(e){return e.preventDefault(),n.classList.add("modal--visible"),!1})}();
\ No newline at end of file
diff --git a/fonts/glyphs.txt b/fonts/glyphs.txt
new file mode 100644
index 0000000..1f4af23
--- /dev/null
+++ b/fonts/glyphs.txt
@@ -0,0 +1 @@
+ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~äöüÄÖÜßẞ↓↙←↖↑↗→↘
diff --git a/glyphs.txt b/glyphs.txt
deleted file mode 100644
index 1f4af23..0000000
--- a/glyphs.txt
+++ /dev/null
@@ -1 +0,0 @@
- !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~äöüÄÖÜßẞ↓↙←↖↑↗→↘
diff --git a/js/main.ts b/js/main.ts
index b099496..32c5a5b 100644
--- a/js/main.ts
+++ b/js/main.ts
@@ -14,14 +14,29 @@ function ensureSetting(key: string, defaultValue: string): string {
 const settings = new KeyValueStore({
     wordWrap: {
         value: ensureSetting('word-wrap', '1') === '1',
+        callbacks: [
+            value => {
+                localStorage.setItem('word-wrap', value ? '1' : '0');
+            }
+        ],
         valueRange: [false, true]
     },
     imagePreviews: {
         value: ensureSetting('image-previews', '1') === '1',
+        callbacks: [
+            value => {
+                localStorage.setItem('image-previews', value ? '1' : '0');
+            }
+        ],
         valueRange: [false, true]
     },
     clickablePlainLinks: {
         value: ensureSetting('clickable-plain-links', '1') === '1',
+        callbacks: [
+            value => {
+                localStorage.setItem('clickable-plain-links', value ? '1' : '0');
+            }
+        ],
         valueRange: [false, true]
     },
 });
@@ -81,7 +96,6 @@ const settings = new KeyValueStore({
             removeImageThumbnails();
         }
 
-        localStorage.setItem('image-previews', value ? '1' : '0');
         settingImagePreviewValueEl.textContent = value ? '[yes]' : '[no]';
     }
 
@@ -105,7 +119,6 @@ const settings = new KeyValueStore({
             contentEl.classList.remove("content--wrap");
         }
 
-        localStorage.setItem('word-wrap', value ? '1' : '0');
         settingWordWrapValueEl.textContent = value ? '[yes]' : '[no]';
     }
 
@@ -129,7 +142,6 @@ const settings = new KeyValueStore({
             removeMarkupForPlainLinks();
         }
 
-        localStorage.setItem('clickable-plain-links', value ? '1' : '0');
         clickablePlainLinksValueEl.textContent = value ? '[yes]' : '[no]';
     }
 
@@ -254,7 +266,7 @@ function generateMarkupForPlainLinks() {
     }
 
     const contentEl = document.getElementsByClassName('content')[0];
-    const urlRegex  = /\b([a-z]*:\/\/[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,}\b[-a-zA-Z0-9@:%_\+.~#?&//=]*)/g;
+    const urlRegex  = /\b[a-z]*:\/\/[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,}\b[-a-zA-Z0-9@:%_\+.~#?&//=]*/g;
     const mailRegex = /\bmailto:[-a-zA-Z0-9@:%._\+~#=]+@(?:[-a-zA-Z0-9@:%._\+~#=]+\.)+[a-z]{2,}\b/g;
 
     contentEl.innerHTML = contentEl.innerHTML.replace(urlRegex, match => {
-- 
cgit v1.2.3-70-g09d2