diff --git a/.dir-locals.el b/.dir-locals.el
new file mode 100644
index 0000000..459c7ad
--- /dev/null
+++ b/.dir-locals.el
@@ -0,0 +1,2 @@
+((nil . ((geiser-mode-auto-p . nil)
+ (geiser-mode-start-repl-p . nil))))
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b25c15b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*~
diff --git a/app.scm b/app.scm
new file mode 100644
index 0000000..096294a
--- /dev/null
+++ b/app.scm
@@ -0,0 +1,15 @@
+(define root document.body)
+
+(define click-count 0)
+
+(m.mount
+ root
+ `&(:view
+ ,(lambda ()
+ (m "main"
+ (vector
+ (m "h1" "LIPS! PWA!")
+ (m "button"
+ `&(:onclick
+ ,(lambda () (set! click-count (+ click-count 1))))
+ (format "~a clicks" click-count)))))))
diff --git a/icon-192.png b/icon-192.png
new file mode 100644
index 0000000..adb3a05
Binary files /dev/null and b/icon-192.png differ
diff --git a/icon-512.png b/icon-512.png
new file mode 100644
index 0000000..3efa80a
Binary files /dev/null and b/icon-512.png differ
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..f589935
--- /dev/null
+++ b/index.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+ LIPS PWA
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 0000000..3d3336c
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1,21 @@
+{
+ "short_name": "PWA",
+ "name": "LIPS PWA Experiment",
+ "description": "A PWA built with LIPS Scheme.",
+ "start_url": "/",
+ "display": "standalone",
+ "theme_color": "black",
+ "background_color": "white",
+ "icons": [
+ {
+ "src": "icon-192.png",
+ "sizes": "192x192",
+ "type": "image/png"
+ },
+ {
+ "src": "icon-512.png",
+ "sizes": "512x512",
+ "type": "image/png"
+ }
+ ]
+}
diff --git a/sw.js b/sw.js
new file mode 100644
index 0000000..a83178b
--- /dev/null
+++ b/sw.js
@@ -0,0 +1,33 @@
+const CACHE_NAME = 'lips-pwa';
+const urlsToCache = ['/',
+ '/index.html',
+ '/app.scm',
+ '/manifest.json',
+ 'https://cdn.jsdelivr.net/npm/lips@beta/dist/lips.min.js',
+ 'https://cdnjs.cloudflare.com/ajax/libs/mithril/2.2.2/mithril.min.js'];
+
+// Install event: cache the assets
+self.addEventListener('install', event => {
+ event.waitUntil(
+ caches.open(CACHE_NAME)
+ .then(cache => {
+ console.log('Opened cache');
+ return cache.addAll(urlsToCache);
+ })
+ );
+});
+
+// Fetch event: serve cached assets when offline
+self.addEventListener('fetch', event => {
+ event.respondWith(
+ caches.match(event.request)
+ .then(response => {
+ // Cache hit - return the response
+ if (response) {
+ return response;
+ }
+ // Otherwise, fetch from network
+ return fetch(event.request);
+ })
+ );
+});