Create repository
120
.gitignore
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
.DS_Store
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
openwc-epaper/
|
||||
40
dashboard.sh
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/bin/sh
|
||||
SERVICE_NAME=dashboard
|
||||
PATH_TO_INDEX=index.js
|
||||
PID_PATH_NAME=/tmp/dashboard.pid
|
||||
|
||||
case $1 in
|
||||
start)
|
||||
echo "Starting $SERVICE_NAME ..."
|
||||
if [ ! -f $PID_PATH_NAME ]; then
|
||||
/usr/local/bin/node $PATH_TO_INDEX
|
||||
echo "$SERVICE_NAME started ..."
|
||||
else
|
||||
echo "$SERVICE_NAME is already running ..."
|
||||
fi
|
||||
;;
|
||||
stop)
|
||||
if [ -f $PID_PATH_NAME ]; then
|
||||
PID=$(cat $PID_PATH_NAME);
|
||||
echo "$SERVICE_NAME stopping ..."
|
||||
kill $PID;
|
||||
echo "$SERVICE_NAME stopped ..."
|
||||
rm $PID_PATH_NAME
|
||||
else
|
||||
echo "$SERVICE_NAME is not running ..."
|
||||
fi
|
||||
;;
|
||||
restart)
|
||||
if [ -f $PID_PATH_NAME ]; then
|
||||
PID=$(cat $PID_PATH_NAME);
|
||||
echo "$SERVICE_NAME stopping ...";
|
||||
kill $PID;
|
||||
echo "$SERVICE_NAME stopped ...";
|
||||
rm $PID_PATH_NAME
|
||||
echo "$SERVICE_NAME starting ..."
|
||||
/usr/local/bin/node $PATH_TO_INDEX
|
||||
echo "$SERVICE_NAME started ..."
|
||||
else
|
||||
echo "$SERVICE_NAME is not running ..."
|
||||
fi ;;
|
||||
esac
|
||||
29
epaper-ui/.editorconfig
Normal file
@@ -0,0 +1,29 @@
|
||||
# EditorConfig helps developers define and maintain consistent
|
||||
# coding styles between different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
|
||||
[*]
|
||||
|
||||
# Change these settings to your own preference
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
# We recommend you to keep these unchanged
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.json]
|
||||
indent_size = 2
|
||||
|
||||
[*.{html,js,md}]
|
||||
block_comment_start = /**
|
||||
block_comment = *
|
||||
block_comment_end = */
|
||||
23
epaper-ui/.gitignore
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
## editors
|
||||
/.idea
|
||||
/.vscode
|
||||
|
||||
## system files
|
||||
.DS_Store
|
||||
|
||||
## npm
|
||||
/node_modules/
|
||||
/npm-debug.log
|
||||
|
||||
## testing
|
||||
/coverage/
|
||||
|
||||
## temp folders
|
||||
/.tmp/
|
||||
|
||||
# build
|
||||
/_site/
|
||||
/dist/
|
||||
/out-tsc/
|
||||
|
||||
storybook-static
|
||||
21
epaper-ui/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 paper-dashboard
|
||||
|
||||
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, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
30
epaper-ui/README.OW.md
Normal file
@@ -0,0 +1,30 @@
|
||||
<p align="center">
|
||||
<img width="200" src="https://open-wc.org/hero.png"></img>
|
||||
</p>
|
||||
|
||||
## Open-wc Starter App
|
||||
|
||||
[](https://github.com/open-wc)
|
||||
|
||||
## Quickstart
|
||||
|
||||
To get started:
|
||||
|
||||
```sh
|
||||
npm init @open-wc
|
||||
# requires node 10 & npm 6 or higher
|
||||
```
|
||||
|
||||
## Scripts
|
||||
|
||||
- `start` runs your app for development, reloading on file changes
|
||||
- `start:build` runs your app after it has been built using the build command
|
||||
- `build` builds your app and outputs it in your `dist` directory
|
||||
- `test` runs your test suite with Web Test Runner
|
||||
- `lint` runs the linter for your project
|
||||
|
||||
## Tooling configs
|
||||
|
||||
For most of the tools, the configuration is in the `package.json` to reduce the amount of files in your project.
|
||||
|
||||
If you customize the configuration a lot, you can consider moving them to individual files.
|
||||
BIN
epaper-ui/assets/JetBrainsMono-Regular.ttf
Normal file
BIN
epaper-ui/assets/PFAdamantPro.ttf
Normal file
BIN
epaper-ui/assets/Palatino.ttf
Normal file
BIN
epaper-ui/assets/Sabon_Roman.ttf
Normal file
BIN
epaper-ui/assets/SourceCodePro-Regular.ttf
Normal file
1
epaper-ui/assets/bolt-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="bolt" class="svg-inline--fa fa-bolt fa-w-10" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path fill="currentColor" d="M296 160H180.6l42.6-129.8C227.2 15 215.7 0 200 0H56C44 0 33.8 8.9 32.2 20.8l-32 240C-1.7 275.2 9.5 288 24 288h118.7L96.6 482.5c-3.6 15.2 8 29.5 23.3 29.5 8.4 0 16.4-4.4 20.8-12l176-304c9.3-15.9-2.2-36-20.7-36z"></path></svg>
|
||||
|
After Width: | Height: | Size: 437 B |
BIN
epaper-ui/assets/favicon.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
1
epaper-ui/assets/fire-alt-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="fire-alt" class="svg-inline--fa fa-fire-alt fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M323.56 51.2c-20.8 19.3-39.58 39.59-56.22 59.97C240.08 73.62 206.28 35.53 168 0 69.74 91.17 0 209.96 0 281.6 0 408.85 100.29 512 224 512s224-103.15 224-230.4c0-53.27-51.98-163.14-124.44-230.4zm-19.47 340.65C282.43 407.01 255.72 416 226.86 416 154.71 416 96 368.26 96 290.75c0-38.61 24.31-72.63 72.79-130.75 6.93 7.98 98.83 125.34 98.83 125.34l58.63-66.88c4.14 6.85 7.91 13.55 11.27 19.97 27.35 52.19 15.81 118.97-33.43 153.42z"></path></svg>
|
||||
|
After Width: | Height: | Size: 662 B |
183931
epaper-ui/assets/tailwind-final.css
Normal file
1
epaper-ui/assets/tint-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="tint" class="svg-inline--fa fa-tint fa-w-11" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 352 512"><path fill="currentColor" d="M205.22 22.09c-7.94-28.78-49.44-30.12-58.44 0C100.01 179.85 0 222.72 0 333.91 0 432.35 78.72 512 176 512s176-79.65 176-178.09c0-111.75-99.79-153.34-146.78-311.82zM176 448c-61.75 0-112-50.25-112-112 0-8.84 7.16-16 16-16s16 7.16 16 16c0 44.11 35.89 80 80 80 8.84 0 16 7.16 16 16s-7.16 16-16 16z"></path></svg>
|
||||
|
After Width: | Height: | Size: 520 B |
1
epaper-ui/assets/weight-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="weight" class="svg-inline--fa fa-weight fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M448 64h-25.98C438.44 92.28 448 125.01 448 160c0 105.87-86.13 192-192 192S64 265.87 64 160c0-34.99 9.56-67.72 25.98-96H64C28.71 64 0 92.71 0 128v320c0 35.29 28.71 64 64 64h384c35.29 0 64-28.71 64-64V128c0-35.29-28.71-64-64-64zM256 320c88.37 0 160-71.63 160-160S344.37 0 256 0 96 71.63 96 160s71.63 160 160 160zm-.3-151.94l33.58-78.36c3.5-8.17 12.94-11.92 21.03-8.41 8.12 3.48 11.88 12.89 8.41 21l-33.67 78.55C291.73 188 296 197.45 296 208c0 22.09-17.91 40-40 40s-40-17.91-40-40c0-21.98 17.76-39.77 39.7-39.94z"></path></svg>
|
||||
|
After Width: | Height: | Size: 741 B |
26
epaper-ui/custom-elements.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"version": 2,
|
||||
"tags": [
|
||||
{
|
||||
"name": "paper-dashboard",
|
||||
"description": "An application with a title and an action counter",
|
||||
"properties": [
|
||||
{
|
||||
"name": "title",
|
||||
"type": "String",
|
||||
"description": "The title of your application",
|
||||
"default": "Hey there"
|
||||
},
|
||||
{
|
||||
"name": "page",
|
||||
"type": "String",
|
||||
"description": "Which page to show",
|
||||
"default": "main"
|
||||
}
|
||||
],
|
||||
"events": [],
|
||||
"slots": [],
|
||||
"cssProperties": []
|
||||
}
|
||||
]
|
||||
}
|
||||
29
epaper-ui/index.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="refresh" content="60"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||
<meta name="Description" content="A simple paper dashboard">
|
||||
<link rel="shortcut icon" href="assets/favicon.ico" />
|
||||
<link href="assets/tailwind-final.css" rel="stylesheet">
|
||||
<base href="/">
|
||||
|
||||
<title>paper-dashboard</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<paper-dashboard></paper-dashboard>
|
||||
|
||||
<script type="module" src="./out-tsc/src/PaperDashboard.js"></script>
|
||||
<script>
|
||||
const ws = new WebSocket('ws://localhost:8080');
|
||||
ws.addEventListener('open', () => {
|
||||
setTimeout(() => ws.send('render'), 10000);
|
||||
setInterval( () => {ws.send('render')}, 300000);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
21358
epaper-ui/package-lock.json
generated
Normal file
87
epaper-ui/package.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"@open-wc/building-rollup": "^1.0.0",
|
||||
"@open-wc/eslint-config": "^4.2.0",
|
||||
"@open-wc/testing": "^2.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^2.20.0",
|
||||
"@typescript-eslint/parser": "^2.20.0",
|
||||
"@web/dev-server": "^0.1.1",
|
||||
"@web/test-runner": "^0.11.5",
|
||||
"autoprefixer": "^10.2.1",
|
||||
"concurrently": "^5.3.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"eslint": "^6.1.0",
|
||||
"eslint-config-prettier": "^6.11.0",
|
||||
"husky": "^1.0.0",
|
||||
"lint-staged": "^10.0.0",
|
||||
"postcss": "^8.2.4",
|
||||
"prettier": "^2.0.4",
|
||||
"rimraf": "^2.6.3",
|
||||
"rollup": "^2.3.4",
|
||||
"rollup-plugin-copy": "^3.3.0",
|
||||
"tailwindcss": "^2.0.2",
|
||||
"tailwindcss-cli": "^0.1.2",
|
||||
"tslib": "^2.0.3",
|
||||
"typescript": "^4.1.3"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint --ext .ts,.html . --ignore-path .gitignore && prettier \"**/*.ts\" --check --ignore-path .gitignore",
|
||||
"format": "eslint --ext .ts,.html . --fix --ignore-path .gitignore && prettier \"**/*.ts\" --write --ignore-path .gitignore",
|
||||
"test": "tsc && wtr --coverage",
|
||||
"test:watch": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wtr --watch\"",
|
||||
"build": "rimraf dist && tsc && rollup -c rollup.config.js",
|
||||
"start:build": "npm run build && web-dev-server --root-dir dist --app-index index.html --open --compatibility none",
|
||||
"start": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wds\"",
|
||||
"css": "npx tailwindcss-cli@latest build ./tailwind.css -o assets/tailwind-final.css",
|
||||
"dist": "rm -rf ../static/*; cp -rf dist/* ../static/"
|
||||
},
|
||||
"name": "paper-dashboard",
|
||||
"version": "0.0.0",
|
||||
"description": "Webcomponent paper-dashboard following open-wc recommendations",
|
||||
"author": "paper-dashboard",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lit-element": "^2.0.1",
|
||||
"lit-html": "^1.0.0"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"extends": [
|
||||
"@open-wc/eslint-config",
|
||||
"eslint-config-prettier"
|
||||
],
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"rules": {
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error"
|
||||
],
|
||||
"import/no-unresolved": "off",
|
||||
"import/extensions": [
|
||||
"error",
|
||||
"always",
|
||||
{
|
||||
"ignorePackages": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"prettier": {
|
||||
"singleQuote": true,
|
||||
"arrowParens": "avoid"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.ts": [
|
||||
"eslint --fix",
|
||||
"prettier --write",
|
||||
"git add"
|
||||
]
|
||||
}
|
||||
}
|
||||
39
epaper-ui/rollup.config.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import merge from 'deepmerge';
|
||||
// use createSpaConfig for bundling a Single Page App
|
||||
import { createSpaConfig } from '@open-wc/building-rollup';
|
||||
import copy from 'rollup-plugin-copy';
|
||||
|
||||
// use createBasicConfig to do regular JS to JS bundling
|
||||
// import { createBasicConfig } from '@open-wc/building-rollup';
|
||||
|
||||
const baseConfig = createSpaConfig({
|
||||
// use the outputdir option to modify where files are output
|
||||
// outputDir: 'dist',
|
||||
|
||||
// if you need to support older browsers, such as IE11, set the legacyBuild
|
||||
// option to generate an additional build just for this browser
|
||||
// legacyBuild: true,
|
||||
|
||||
// development mode creates a non-minified build for debugging or development
|
||||
developmentMode: process.env.ROLLUP_WATCH === 'true',
|
||||
|
||||
// set to true to inject the service worker registration into your index.html
|
||||
injectServiceWorker: false,
|
||||
});
|
||||
|
||||
export default merge(baseConfig, {
|
||||
// if you use createSpaConfig, you can use your index.html as entrypoint,
|
||||
// any <script type="module"> inside will be bundled by rollup
|
||||
input: './index.html',
|
||||
|
||||
// alternatively, you can use your JS as entrypoint for rollup and
|
||||
// optionally set a HTML template manually
|
||||
// input: './app.js',
|
||||
plugins: [
|
||||
copy({
|
||||
targets: [{ src: 'assets/**/*', dest: 'dist/assets' }],
|
||||
// set flatten to false to preserve folder structure
|
||||
flatten: false,
|
||||
}),
|
||||
],
|
||||
});
|
||||
51
epaper-ui/src/CalendarData.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import {until} from 'lit-html/directives/until';
|
||||
|
||||
import { html } from 'lit-element';
|
||||
|
||||
import { YoloLitElement } from './YoloLitElement.js';
|
||||
|
||||
import { NetworkMixin } from './NetworkMixin.js';
|
||||
|
||||
const calendar = "https://docs.google.com/spreadsheets/d/e/2PACX-1vTPX3UqKW4tMPhj6M18f-6cR73IkIpMblbK3i2sodtFCoRNkDwAbhvFaU4PgBPBE1krJmy11dw1EzyT/pub?gid=0&single=true&output=csv"
|
||||
|
||||
const monthNames = ["January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"];
|
||||
|
||||
interface CalendarEvent{
|
||||
when: string;
|
||||
what: string;
|
||||
where: string;
|
||||
}
|
||||
|
||||
export class CalendarData extends NetworkMixin(YoloLitElement) {
|
||||
|
||||
async getEvents() {
|
||||
const result = await this.httpText(calendar);
|
||||
|
||||
const eventsAsArray = result.split(/\r?\n/).map(l => l.split(','));
|
||||
const events = eventsAsArray.map(e => { return {when: e[0], what: e[1], where: e[2]}});
|
||||
|
||||
return events.slice(0, 7);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
${until(this.getEvents().then( events => html`
|
||||
<div class="ml-4 h-full flex flex-col justify-around">
|
||||
${events.map( (event : CalendarEvent) =>
|
||||
html`
|
||||
<div class="flex">
|
||||
<div class="w-1/3 text-base font-extrabold">
|
||||
${(new Date(event.when)).getDate()} ${monthNames[(new Date(event.when)).getMonth()].slice(0,1)}. ${(new Date(event.when)).getHours()}:${(new Date(event.when)).getMinutes()<10?'0':''}${(new Date(event.when)).getMinutes()}
|
||||
</div>
|
||||
<div class="w-2/3 text-base font-bold">${event.what}</div>
|
||||
</div>`
|
||||
)}
|
||||
</div>
|
||||
`
|
||||
))}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('calendar-events', CalendarData);
|
||||
25
epaper-ui/src/DateInfo.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { html } from 'lit-element';
|
||||
|
||||
import { YoloLitElement } from './YoloLitElement.js';
|
||||
|
||||
const monthNames = ["January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"];
|
||||
|
||||
export class DateInfo extends YoloLitElement {
|
||||
|
||||
render() {
|
||||
const now = new Date();
|
||||
return html`
|
||||
<div class="h-full flex flex-col">
|
||||
<div class="h-3/5 font-bold text-4xl text-center flex items-center justify-center">
|
||||
${now.getHours()}:${now.getMinutes()<10?'0':''}${now.getMinutes()}
|
||||
</div>
|
||||
<div class="h-2/5 flex font-bold justify-center">
|
||||
${now.getDate()} ${monthNames[now.getMonth()]}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('date-info', DateInfo);
|
||||
61
epaper-ui/src/EnergyInfo.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import {until} from 'lit-html/directives/until';
|
||||
import { html } from 'lit-element';
|
||||
|
||||
import { YoloLitElement } from './YoloLitElement.js';
|
||||
|
||||
import { NetworkMixin } from './NetworkMixin.js';
|
||||
|
||||
const energySheet = "https://docs.google.com/spreadsheets/d/e/2PACX-1vTo1q9NO4daxpvY77c1UGTgAai9LIEsf5QmCPU13IatzIzx5a68Jr5EL8MUzKpDob55Qo1vy5CkQpYE/pub?gid=1686054259&single=true&output=csv";
|
||||
|
||||
interface EnergyInfoData{
|
||||
lastMeasurement: number;
|
||||
previsionkWh: string;
|
||||
previsionGJ: string;
|
||||
previsionm3: string;
|
||||
trendkWh: string;
|
||||
trendGJ: string;
|
||||
trendm3: string;
|
||||
}
|
||||
|
||||
|
||||
export class EnergyInfo extends NetworkMixin(YoloLitElement) {
|
||||
|
||||
async getEnergy() {
|
||||
const energyRaw = (await this.httpText(energySheet)).split(',');
|
||||
|
||||
const energyInfo = {
|
||||
lastMeasurement: energyRaw[0],
|
||||
previsionkWh: parseInt(energyRaw[1], 10),
|
||||
previsionGJ: parseInt(energyRaw[2], 10),
|
||||
previsionm3: parseInt(energyRaw[3], 10),
|
||||
trendkWh: parseInt(energyRaw[4], 10),
|
||||
trendGJ: parseInt(energyRaw[5], 10),
|
||||
trendm3: parseInt(energyRaw[6 ], 10),
|
||||
}
|
||||
return energyInfo;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="h-full flex flex justify-around">
|
||||
${until(this.getEnergy().then( energyInfo => html`
|
||||
<div class="font-bold text-xl text-center flex items-center justify-center">
|
||||
<img class="h-8 mr-2" alt="a drop of water" src="assets/bolt-solid.svg">
|
||||
<p class="" >${energyInfo.trendkWh > 0 ? html`+` : html``} ${energyInfo.trendkWh}%</p>
|
||||
</div>
|
||||
<div class="font-bold text-xl text-center flex items-center justify-center">
|
||||
<img class="h-8 mr-2" alt="a drop of water" src="assets/fire-alt-solid.svg">
|
||||
<p>${energyInfo.trendGJ > 0 ? html`+` : html``} ${energyInfo.trendGJ}%</p>
|
||||
</div>
|
||||
<div class="font-bold text-xl text-center flex items-center justify-center">
|
||||
<img class="h-8 mr-2" alt="a drop of water" src="assets/tint-solid.svg">
|
||||
<p>${energyInfo.trendm3 > 0 ? html`+` : html``} ${energyInfo.trendm3}%</p>
|
||||
</div>
|
||||
`
|
||||
))}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('energy-info', EnergyInfo);
|
||||
22
epaper-ui/src/NetworkMixin.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
declare type Constructor<T> = {
|
||||
new (...args: any[]): T
|
||||
}
|
||||
|
||||
export function NetworkMixin<B extends Constructor<HTMLElement>>(baseClass: B) {
|
||||
return class extends baseClass {
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
async httpJson<T>(request: RequestInfo): Promise<T> {
|
||||
const response = await fetch(request);
|
||||
const body = await response.json();
|
||||
return body;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
async httpText<T>(request: RequestInfo): Promise<String> {
|
||||
const response = await fetch(request);
|
||||
const body = await response.text();
|
||||
return body;
|
||||
}
|
||||
}
|
||||
}
|
||||
40
epaper-ui/src/PaperDashboard.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { html, css, property } from 'lit-element';
|
||||
|
||||
import { YoloLitElement } from './YoloLitElement.js';
|
||||
|
||||
import './DateInfo.js'
|
||||
import './WeatherData.js';
|
||||
import './WeeklyMenus.js';
|
||||
import './EnergyInfo.js';
|
||||
import './CalendarData.js';
|
||||
import './WeightInfo.js';
|
||||
|
||||
export class PaperDashboard extends YoloLitElement {
|
||||
|
||||
@property({ type: String }) title = 'My app';
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<main class="h-full">
|
||||
<div class="flex h-1/6">
|
||||
<date-info class="flex-auto h-full"></date-info>
|
||||
<weather-data class="flex-auto h-full flex justify-around"></weather-data>
|
||||
</div>
|
||||
<div class="flex h-4/6 mt-2 mb-2">
|
||||
<weekly-menus class="w-1/2 h-full"></weekly-menus>
|
||||
<div class="h-full flex-grow-0 flex items-center justify-center">
|
||||
<div class=" h-1/2 border-2 border-black"></div>
|
||||
</div>
|
||||
|
||||
<calendar-events class="w-1/2 h-full flex-auto"></calendar-events>
|
||||
</div>
|
||||
<div class="h-1/6 flex items-center justify-center">
|
||||
<weight-info class="w-1/5"></weight-info>
|
||||
<energy-info class="w-4/5"></energy-info>
|
||||
</div>
|
||||
</main>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('paper-dashboard', PaperDashboard);
|
||||
55
epaper-ui/src/WeatherData.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { html } from 'lit-element';
|
||||
import {until} from 'lit-html/directives/until';
|
||||
|
||||
import { YoloLitElement } from './YoloLitElement.js';
|
||||
import './WeatherDay.js';
|
||||
import {NetworkMixin} from './NetworkMixin.js';
|
||||
|
||||
const weatherApi = "https://api.openweathermap.org/data/2.5/onecall?exclude=hourly,minutely&lat=52.046680&lon=5.079170&APPID=ee80728351da55e61e612558832978e4"
|
||||
|
||||
interface IWeatherResponse {
|
||||
current: IWeatherPoint;
|
||||
daily: Array<IWeatherPointDaily>;
|
||||
}
|
||||
|
||||
interface IWeatherPointDaily {
|
||||
feels_like: IWeatherFeelsLikeDaily;
|
||||
weather: Array<IWeather>;
|
||||
}
|
||||
|
||||
interface IWeatherFeelsLikeDaily {
|
||||
day: number
|
||||
}
|
||||
|
||||
interface IWeatherPoint {
|
||||
feels_like: number;
|
||||
weather: Array<IWeather>;
|
||||
}
|
||||
|
||||
interface IWeather {
|
||||
icon : string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export class WeatherData extends NetworkMixin(YoloLitElement) {
|
||||
|
||||
async getWeather() {
|
||||
const result = await this.httpJson<IWeatherResponse>(weatherApi);
|
||||
return result;
|
||||
}
|
||||
|
||||
render() {
|
||||
const currentDay = (current: IWeatherPoint) => html`<weather-day .temperature=${current.feels_like} .icon=${current.weather[0].icon}></weather-day>`;
|
||||
const allDays = (days: Array<IWeatherPointDaily>) => html`${days.map((day: IWeatherPointDaily) => html`<weather-day .temperature=${day.feels_like.day} .icon=${day.weather[0].icon}></weather-day>`)}`;
|
||||
|
||||
return html`
|
||||
${until(this.getWeather().then( res => html`
|
||||
${currentDay(res.current)}
|
||||
${allDays(res.daily)}
|
||||
`
|
||||
))}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('weather-data', WeatherData);
|
||||
25
epaper-ui/src/WeatherDay.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { html, css, property } from 'lit-element';
|
||||
|
||||
import { YoloLitElement } from './YoloLitElement.js';
|
||||
|
||||
const toKelvin = 273.15;
|
||||
|
||||
export class WeatherDay extends YoloLitElement {
|
||||
|
||||
@property({ type: Number }) temperature = 0.0 ;
|
||||
|
||||
@property({ type: String }) icon = "";
|
||||
|
||||
static styles = css``;
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="flex flex-col h-full justify-around">
|
||||
<p class="font-bold text-center mt-2">${Math.round(this.temperature - toKelvin)}°C</p>
|
||||
<img style="filter:brightness(0);" src="https://openweathermap.org/img/wn/${this.icon}.png" alt=${this.icon}>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('weather-day', WeatherDay);
|
||||
48
epaper-ui/src/WeeklyMenus.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import {until} from 'lit-html/directives/until';
|
||||
import { html } from 'lit-element';
|
||||
|
||||
import { YoloLitElement } from './YoloLitElement.js';
|
||||
|
||||
import { NetworkMixin } from './NetworkMixin.js';
|
||||
|
||||
const menusSheet = "https://docs.google.com/spreadsheets/d/e/2PACX-1vTQFqToleR71JZahgIYAcIsieLFd4sugFLsDMUoVHUMLV8UoqUv4QctkO1lzUU_2Eh0ZzaLAbtEUZUH/pub?gid=0&single=true&output=csv";
|
||||
|
||||
interface MenuData{
|
||||
day: string;
|
||||
lunch: string;
|
||||
dinner: string;
|
||||
}
|
||||
|
||||
export class WeeklyMenus extends NetworkMixin(YoloLitElement) {
|
||||
|
||||
async getMenus() {
|
||||
const result = await this.httpText(menusSheet);
|
||||
|
||||
const menusAsArray = result.split(/\r?\n/).map(l => l.split(','));
|
||||
const menus = menusAsArray.map(m => { return {day:m[0], lunch: m[1], dinner: m[2]}});
|
||||
|
||||
return menus;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="h-full flex flex-col justify-evenly">
|
||||
${until(this.getMenus().then( menus => html`
|
||||
${menus.map( (menu : MenuData) =>
|
||||
html`<div class="flex">
|
||||
<div class="ml-4 w-1/3 text-base font-extrabold">${menu.day}</div>
|
||||
<div class="ml-5 w-2/3">
|
||||
<div class="text-base font-bold">${menu.lunch}</div>
|
||||
<div class="text-base font-bold">${menu.dinner}</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
`
|
||||
))}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('weekly-menus', WeeklyMenus);
|
||||
32
epaper-ui/src/WeightInfo.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import {until} from 'lit-html/directives/until';
|
||||
import { html } from 'lit-element';
|
||||
|
||||
import { YoloLitElement } from './YoloLitElement.js';
|
||||
|
||||
import { NetworkMixin } from './NetworkMixin.js';
|
||||
|
||||
const weightSheet = "https://docs.google.com/spreadsheets/d/e/2PACX-1vSdO0GF46JK4LZhxXyuH6HPFtHSHaMmE91yD3WJj1zDHW99K_cL__e9Hnbh_ATvEIQ_D1daxYXXttyC/pub?gid=0&single=true&output=csv";
|
||||
|
||||
export class WeightInfo extends NetworkMixin(YoloLitElement) {
|
||||
|
||||
async getWeight() {
|
||||
const weight = await this.httpText(weightSheet);
|
||||
return weight;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="h-full flex flex-col justify-around">
|
||||
${until(this.getWeight().then( weight => html`
|
||||
<div class="font-bold text-xl text-center flex items-center justify-center">
|
||||
<img class="h-8 mr-2" alt="a scale" src="assets/weight-solid.svg">
|
||||
<p>${weight}kg</p>
|
||||
</div>
|
||||
`
|
||||
))}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('weight-info', WeightInfo);
|
||||
7
epaper-ui/src/YoloLitElement.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { LitElement } from 'lit-element';
|
||||
|
||||
export class YoloLitElement extends LitElement {
|
||||
createRenderRoot(){
|
||||
return this;
|
||||
}
|
||||
}
|
||||
3
epaper-ui/src/paper-dashboard.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { PaperDashboard } from './PaperDashboard.js';
|
||||
|
||||
customElements.define('paper-dashboard', PaperDashboard);
|
||||
42
epaper-ui/tailwind.css
Normal file
@@ -0,0 +1,42 @@
|
||||
/* ./tailwind.css */
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
|
||||
@font-face {
|
||||
font-family: "PFAdamantPro";
|
||||
src: url("assets/PFAdamantPro.ttf") format("ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Sabon";
|
||||
src: url("assets/Sabon_Roman.ttf") format("ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "SourceCodePro";
|
||||
src: url("assets/SourceCodePro-Regular.ttf") format("ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "JetBrainsMono";
|
||||
src: url("assets/JetBrainsMono-Regular.ttf") format("ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Palatino";
|
||||
src: url("assets/Palatino.ttf") format("ttf");
|
||||
}
|
||||
|
||||
html,body,p,input,textarea,h1,h2, div {
|
||||
font-family: 'PFAdamantPro';
|
||||
}
|
||||
|
||||
body {
|
||||
width:800px;
|
||||
max-width: 800px;
|
||||
|
||||
height: 480px;
|
||||
max-height: 480px;
|
||||
}
|
||||
|
||||
@tailwind utilities;
|
||||
21
epaper-ui/test/paper-dashboard.test.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { html, fixture, expect } from '@open-wc/testing';
|
||||
|
||||
import { PaperDashboard } from '../src/PaperDashboard.js';
|
||||
import '../src/paper-dashboard.js';
|
||||
|
||||
describe('PaperDashboard', () => {
|
||||
let element: PaperDashboard;
|
||||
beforeEach(async () => {
|
||||
element = await fixture(html`<paper-dashboard></paper-dashboard>`);
|
||||
});
|
||||
|
||||
it('renders a h1', () => {
|
||||
const h1 = element.shadowRoot!.querySelector('h1')!;
|
||||
expect(h1).to.exist;
|
||||
expect(h1.textContent).to.equal('My app');
|
||||
});
|
||||
|
||||
it('passes the a11y audit', async () => {
|
||||
await expect(element).shadowDom.to.be.accessible();
|
||||
});
|
||||
});
|
||||
19
epaper-ui/tsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2018",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"noEmitOnError": true,
|
||||
"lib": ["es2017", "dom"],
|
||||
"strict": true,
|
||||
"esModuleInterop": false,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"experimentalDecorators": true,
|
||||
"importHelpers": true,
|
||||
"outDir": "out-tsc",
|
||||
"sourceMap": true,
|
||||
"inlineSources": true,
|
||||
"rootDir": "./"
|
||||
},
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
29
epaper-ui/web-dev-server.config.mjs
Normal file
@@ -0,0 +1,29 @@
|
||||
// import { hmrPlugin, presets } from '@open-wc/dev-server-hmr';
|
||||
|
||||
/** Use Hot Module replacement by adding --hmr to the start command */
|
||||
const hmr = process.argv.includes('--hmr');
|
||||
|
||||
export default /** @type {import('@web/dev-server').DevServerConfig} */ ({
|
||||
nodeResolve: true,
|
||||
open: '/',
|
||||
watch: !hmr,
|
||||
port: 8082,
|
||||
|
||||
/** Compile JS for older browsers. Requires @web/dev-server-esbuild plugin */
|
||||
// esbuildTarget: 'auto'
|
||||
|
||||
/** Set appIndex to enable SPA routing */
|
||||
// appIndex: 'demo/index.html',
|
||||
|
||||
/** Confgure bare import resolve plugin */
|
||||
// nodeResolve: {
|
||||
// exportConditions: ['browser', 'development']
|
||||
// },
|
||||
|
||||
plugins: [
|
||||
/** Use Hot Module Replacement by uncommenting. Requires @open-wc/dev-server-hmr plugin */
|
||||
// hmr && hmrPlugin({ exclude: ['**/*/node_modules/**/*'], presets: [presets.litElement] }),
|
||||
],
|
||||
|
||||
// See documentation for all available options
|
||||
});
|
||||
30
epaper-ui/web-test-runner.config.mjs
Normal file
@@ -0,0 +1,30 @@
|
||||
// import { playwrightLauncher } from '@web/test-runner-playwright';
|
||||
|
||||
export default /** @type {import("@web/test-runner").TestRunnerConfig} */ ({
|
||||
files: 'out-tsc/test/**/*.test.js',
|
||||
nodeResolve: true,
|
||||
port: 8082,
|
||||
|
||||
/** Compile JS for older browsers. Requires @web/dev-server-esbuild plugin */
|
||||
// esbuildTarget: 'auto',
|
||||
|
||||
/** Confgure bare import resolve plugin */
|
||||
// nodeResolve: {
|
||||
// exportConditions: ['browser', 'development']
|
||||
// },
|
||||
|
||||
/** Amount of browsers to run concurrently */
|
||||
// concurrentBrowsers: 2,
|
||||
|
||||
/** Amount of test files per browser to test concurrently */
|
||||
// concurrency: 1,
|
||||
|
||||
/** Browsers to run tests on */
|
||||
// browsers: [
|
||||
// playwrightLauncher({ product: 'chromium' }),
|
||||
// playwrightLauncher({ product: 'firefox' }),
|
||||
// playwrightLauncher({ product: 'webkit' }),
|
||||
// ],
|
||||
|
||||
// See documentation for all available options
|
||||
});
|
||||
4
index.js
Normal file
@@ -0,0 +1,4 @@
|
||||
const { init, devices } = require('epaperjs');
|
||||
|
||||
init(devices.waveshare7in5v2Horizontal);
|
||||
|
||||
3
netlify.toml
Normal file
@@ -0,0 +1,3 @@
|
||||
[build]
|
||||
publish = "static/"
|
||||
command = "npm run build"
|
||||
2625
package-lock.json
generated
Normal file
27
package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "epaper-dashboard",
|
||||
"version": "1.0.0",
|
||||
"description": "Runner for my epaper dashboard",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"node-engine": "node -v",
|
||||
"build": "cd epaper-ui; npm run css; npm run build; npm run dist",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jlengrand/epaper-dashboard.git"
|
||||
},
|
||||
"author": "Julien Lengrand-Lambert",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/jlengrand/epaper-dashboard/issues"
|
||||
},
|
||||
"homepage": "https://github.com/jlengrand/epaper-dashboard#readme",
|
||||
"dependencies": {
|
||||
"epaperjs": "^1.3.3"
|
||||
}
|
||||
}
|
||||
15
service/dashboard.service
Normal file
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=Epaper dashboard
|
||||
[Service]
|
||||
User=pi
|
||||
WorkingDirectory=/home/pi/epaper-dashboard
|
||||
ExecStart=/home/pi/epaper-dashboard/dashboard.sh start
|
||||
ExecStop=/home/pi/epaper-dashboard/dashboard.sh stop
|
||||
ExecReload=/home/pi/epaper-dashboard/dashboard.sh restart
|
||||
|
||||
SuccessExitStatus=143
|
||||
TimeoutStopSec=10
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
BIN
static/assets/JetBrainsMono-Regular.ttf
Normal file
BIN
static/assets/PFAdamantPro.ttf
Normal file
BIN
static/assets/Palatino.ttf
Normal file
BIN
static/assets/Sabon_Roman.ttf
Normal file
BIN
static/assets/SourceCodePro-Regular.ttf
Normal file
1
static/assets/bolt-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="bolt" class="svg-inline--fa fa-bolt fa-w-10" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path fill="currentColor" d="M296 160H180.6l42.6-129.8C227.2 15 215.7 0 200 0H56C44 0 33.8 8.9 32.2 20.8l-32 240C-1.7 275.2 9.5 288 24 288h118.7L96.6 482.5c-3.6 15.2 8 29.5 23.3 29.5 8.4 0 16.4-4.4 20.8-12l176-304c9.3-15.9-2.2-36-20.7-36z"></path></svg>
|
||||
|
After Width: | Height: | Size: 437 B |
BIN
static/assets/favicon.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
1
static/assets/fire-alt-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="fire-alt" class="svg-inline--fa fa-fire-alt fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M323.56 51.2c-20.8 19.3-39.58 39.59-56.22 59.97C240.08 73.62 206.28 35.53 168 0 69.74 91.17 0 209.96 0 281.6 0 408.85 100.29 512 224 512s224-103.15 224-230.4c0-53.27-51.98-163.14-124.44-230.4zm-19.47 340.65C282.43 407.01 255.72 416 226.86 416 154.71 416 96 368.26 96 290.75c0-38.61 24.31-72.63 72.79-130.75 6.93 7.98 98.83 125.34 98.83 125.34l58.63-66.88c4.14 6.85 7.91 13.55 11.27 19.97 27.35 52.19 15.81 118.97-33.43 153.42z"></path></svg>
|
||||
|
After Width: | Height: | Size: 662 B |
183931
static/assets/tailwind-final.css
Normal file
1
static/assets/tint-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="tint" class="svg-inline--fa fa-tint fa-w-11" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 352 512"><path fill="currentColor" d="M205.22 22.09c-7.94-28.78-49.44-30.12-58.44 0C100.01 179.85 0 222.72 0 333.91 0 432.35 78.72 512 176 512s176-79.65 176-178.09c0-111.75-99.79-153.34-146.78-311.82zM176 448c-61.75 0-112-50.25-112-112 0-8.84 7.16-16 16-16s16 7.16 16 16c0 44.11 35.89 80 80 80 8.84 0 16 7.16 16 16s-7.16 16-16 16z"></path></svg>
|
||||
|
After Width: | Height: | Size: 520 B |
1
static/assets/weight-solid.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="weight" class="svg-inline--fa fa-weight fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M448 64h-25.98C438.44 92.28 448 125.01 448 160c0 105.87-86.13 192-192 192S64 265.87 64 160c0-34.99 9.56-67.72 25.98-96H64C28.71 64 0 92.71 0 128v320c0 35.29 28.71 64 64 64h384c35.29 0 64-28.71 64-64V128c0-35.29-28.71-64-64-64zM256 320c88.37 0 160-71.63 160-160S344.37 0 256 0 96 71.63 96 160s71.63 160 160 160zm-.3-151.94l33.58-78.36c3.5-8.17 12.94-11.92 21.03-8.41 8.12 3.48 11.88 12.89 8.41 21l-33.67 78.55C291.73 188 296 197.45 296 208c0 22.09-17.91 40-40 40s-40-17.91-40-40c0-21.98 17.76-39.77 39.7-39.94z"></path></svg>
|
||||
|
After Width: | Height: | Size: 741 B |
1
static/c0737020.js
Normal file
1
static/index.html
Normal file
@@ -0,0 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="refresh" content="60"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><meta name="Description" content="A simple paper dashboard"><link rel="shortcut icon" href="assets/favicon.ico"><link href="assets/tailwind-final.css" rel="stylesheet"><base href="/"><title>paper-dashboard</title><link rel="preload" href="./c0737020.js" as="script" crossorigin="anonymous"></head><body><paper-dashboard></paper-dashboard><script>const ws=new WebSocket("ws://localhost:8080");ws.addEventListener("open",()=>{setTimeout(()=>ws.send("render"),1e4),setInterval(()=>{ws.send("render")},3e5)})</script><script type="module" src="./c0737020.js"></script></body></html>
|
||||
2
static/sw.js
Normal file
@@ -0,0 +1,2 @@
|
||||
if(!self.define){const e=e=>{"require"!==e&&(e+=".js");let r=Promise.resolve();return s[e]||(r=new Promise(async r=>{if("document"in self){const s=document.createElement("script");s.src=e,document.head.appendChild(s),s.onload=r}else importScripts(e),r()})),r.then(()=>{if(!s[e])throw new Error(`Module ${e} didn’t register its module`);return s[e]})},r=(r,s)=>{Promise.all(r.map(e)).then(e=>s(1===e.length?e[0]:e))},s={require:Promise.resolve(r)};self.define=(r,t,i)=>{s[r]||(s[r]=Promise.resolve().then(()=>{let s={};const n={uri:location.origin+r.slice(1)};return Promise.all(t.map(r=>{switch(r){case"exports":return s;case"module":return n;default:return e(r)}})).then(e=>{const r=i(...e);return s.default||(s.default=r),s})}))}}define("./sw.js",["./workbox-80efdfd1"],(function(e){"use strict";e.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"c0737020.js",revision:"ba034c33bc1e655c7a3db57ccc558a24"},{url:"index.html",revision:"a63454ad38c319cf08eda926873da204"}],{}),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"))),e.registerRoute("polyfills/*.js",new e.CacheFirst,"GET")}));
|
||||
//# sourceMappingURL=sw.js.map
|
||||
1
static/sw.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"sw.js","sources":["../../../../../private/var/folders/0x/xhvbsmgn36z1t2jltptz27yc0000gn/T/9095901c8719ae9cf98d3833b954be97/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/Users/jlengrand/Developer/epaper-dashboard-blog/epaper-ui/node_modules/workbox-routing/registerRoute.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from '/Users/jlengrand/Developer/epaper-dashboard-blog/epaper-ui/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {skipWaiting as workbox_core_skipWaiting} from '/Users/jlengrand/Developer/epaper-dashboard-blog/epaper-ui/node_modules/workbox-core/skipWaiting.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/Users/jlengrand/Developer/epaper-dashboard-blog/epaper-ui/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/Users/jlengrand/Developer/epaper-dashboard-blog/epaper-ui/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/Users/jlengrand/Developer/epaper-dashboard-blog/epaper-ui/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/Users/jlengrand/Developer/epaper-dashboard-blog/epaper-ui/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nworkbox_core_skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"c0737020.js\",\n \"revision\": \"ba034c33bc1e655c7a3db57ccc558a24\"\n },\n {\n \"url\": \"index.html\",\n \"revision\": \"a63454ad38c319cf08eda926873da204\"\n }\n], {});\n\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"/index.html\")));\n\n\nworkbox_routing_registerRoute(\"polyfills/*.js\", new workbox_strategies_CacheFirst(), 'GET');\n\n\n\n\n"],"names":["workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","workbox_strategies_CacheFirst"],"mappings":"k1BAmCoC,CAClC,KACS,uBACK,oCAEd,KACS,sBACK,qCAEb,oBAE2B,IAAIA,kBAAgCC,0BAA2C,iCAG/E,iBAAkB,IAAIC,aAAiC"}
|
||||