diff --git a/README.md b/README.md index f3f1d13..b7b1382 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,5 @@ # \ - - - - Way back at the dawn of the Internet, I started writing (and sometimes still write) a long-running adult space opera serial called [The Journal Entries](https://pendorwright.com/journals). One of the conceits of the series in that the distant world of Pendor was built and terraformed to have a @@ -13,9 +9,9 @@ applets](https://en.wikipedia.org/wiki/Java_applet) (remember those?) I wrote wa showed the time of day on Pendor. This is the Pendorclock, but modernized into a custom Web Component, capable of running in any -browser without your needing to do anything at all to make it work correctly. It will load its own -font (Google Audiowide) and run anywhere you want. The font is not currently customizable without a -rebuild, but the following CSS Custom Attributes are exposed and you're free to change any of them: +browser without your needing to do anything at all to make it work correctly. + +The following CSS Custom Attributes are exposed and you're free to change any of them: ``` JavaScript background-color: var(--pendorclock-background-color, #000030); @@ -28,6 +24,35 @@ font-weight: var(--pendorclock-font-weight, 700); This is mostly my set-up these days, complete with the hard-core `lint:hard`, Codespell, and automatic Prettier. +## Options + +The clock has a single configurable attribute, `with-internal-font`. Setting that will cause the +component to use the Google Font [Audiowide](https://fonts.google.com/specimen/Audiowide), which, +while stylish, is not the original font from 1993, which was Bitwise. Using it is just like using +any boolean attribute in HTML: + +``` html + +``` + +Along with the CSS Custom Attributes, there is only CSS target within the clock: +''. Using that target it is possible to use any font at all for the +clock by providing some additional CSS to the host page. This can be seen in the demo-with-font.html +file in the demo. + +``` css +@font-face { + font-family: "Bitwise"; + font-style: normal; + font-weight: 400; + src: url("./Bitwise.woff2") format("woff2"), url("./Bitwise.ttf") format("truetype"); +} +pendor-clock::clock { + font-family: Bitwise; +} +``` + + ## LICENSE The Pendorwright Clock is Copyright [Elf M. Sternberg](https://elfsternberg.com) (c) 2023, and diff --git a/build-modern/pendor-clock.js b/build-modern/pendor-clock.js index acb2504..28c3015 100644 --- a/build-modern/pendor-clock.js +++ b/build-modern/pendor-clock.js @@ -1,3 +1,4 @@ +"function"==typeof SuppressedError&&SuppressedError; /** * @license * Copyright 2019 Google LLC @@ -8,15 +9,21 @@ const t=window,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow)&&" * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause - */;var l;const h=window,a=h.trustedTypes,c=a?a.emptyScript:"",d=h.reactiveElementPolyfillSupport,u={toAttribute(t,e){switch(e){case Boolean:t=t?c:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},p=(t,e)=>e!==t&&(e==e||t==t),v={attribute:!0,type:String,converter:u,reflect:!1,hasChanged:p},$="finalized";class _ extends HTMLElement{constructor(){super(),this._$Ei=new Map,this.isUpdatePending=!1,this.hasUpdated=!1,this._$El=null,this._$Eu()}static addInitializer(t){var e;this.finalize(),(null!==(e=this.h)&&void 0!==e?e:this.h=[]).push(t)}static get observedAttributes(){this.finalize();const t=[];return this.elementProperties.forEach(((e,i)=>{const s=this._$Ep(i,e);void 0!==s&&(this._$Ev.set(s,i),t.push(s))})),t}static createProperty(t,e=v){if(e.state&&(e.attribute=!1),this.finalize(),this.elementProperties.set(t,e),!e.noAccessor&&!this.prototype.hasOwnProperty(t)){const i="symbol"==typeof t?Symbol():"__"+t,s=this.getPropertyDescriptor(t,i,e);void 0!==s&&Object.defineProperty(this.prototype,t,s)}}static getPropertyDescriptor(t,e,i){return{get(){return this[e]},set(s){const n=this[t];this[e]=s,this.requestUpdate(t,n,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)||v}static finalize(){if(this.hasOwnProperty($))return!1;this[$]=!0;const t=Object.getPrototypeOf(this);if(t.finalize(),void 0!==t.h&&(this.h=[...t.h]),this.elementProperties=new Map(t.elementProperties),this._$Ev=new Map,this.hasOwnProperty("properties")){const t=this.properties,e=[...Object.getOwnPropertyNames(t),...Object.getOwnPropertySymbols(t)];for(const i of e)this.createProperty(i,t[i])}return this.elementStyles=this.finalizeStyles(this.styles),!0}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const t of i)e.unshift(r(t))}else void 0!==t&&e.push(r(t));return e}static _$Ep(t,e){const i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}_$Eu(){var t;this._$E_=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$Eg(),this.requestUpdate(),null===(t=this.constructor.h)||void 0===t||t.forEach((t=>t(this)))}addController(t){var e,i;(null!==(e=this._$ES)&&void 0!==e?e:this._$ES=[]).push(t),void 0!==this.renderRoot&&this.isConnected&&(null===(i=t.hostConnected)||void 0===i||i.call(t))}removeController(t){var e;null===(e=this._$ES)||void 0===e||e.splice(this._$ES.indexOf(t)>>>0,1)}_$Eg(){this.constructor.elementProperties.forEach(((t,e)=>{this.hasOwnProperty(e)&&(this._$Ei.set(e,this[e]),delete this[e])}))}createRenderRoot(){var i;const s=null!==(i=this.shadowRoot)&&void 0!==i?i:this.attachShadow(this.constructor.shadowRootOptions);return((i,s)=>{e?i.adoptedStyleSheets=s.map((t=>t instanceof CSSStyleSheet?t:t.styleSheet)):s.forEach((e=>{const s=document.createElement("style"),n=t.litNonce;void 0!==n&&s.setAttribute("nonce",n),s.textContent=e.cssText,i.appendChild(s)}))})(s,this.constructor.elementStyles),s}connectedCallback(){var t;void 0===this.renderRoot&&(this.renderRoot=this.createRenderRoot()),this.enableUpdating(!0),null===(t=this._$ES)||void 0===t||t.forEach((t=>{var e;return null===(e=t.hostConnected)||void 0===e?void 0:e.call(t)}))}enableUpdating(t){}disconnectedCallback(){var t;null===(t=this._$ES)||void 0===t||t.forEach((t=>{var e;return null===(e=t.hostDisconnected)||void 0===e?void 0:e.call(t)}))}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$EO(t,e,i=v){var s;const n=this.constructor._$Ep(t,i);if(void 0!==n&&!0===i.reflect){const o=(void 0!==(null===(s=i.converter)||void 0===s?void 0:s.toAttribute)?i.converter:u).toAttribute(e,i.type);this._$El=t,null==o?this.removeAttribute(n):this.setAttribute(n,o),this._$El=null}}_$AK(t,e){var i;const s=this.constructor,n=s._$Ev.get(t);if(void 0!==n&&this._$El!==n){const t=s.getPropertyOptions(n),o="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==(null===(i=t.converter)||void 0===i?void 0:i.fromAttribute)?t.converter:u;this._$El=n,this[n]=o.fromAttribute(e,t.type),this._$El=null}}requestUpdate(t,e,i){let s=!0;void 0!==t&&(((i=i||this.constructor.getPropertyOptions(t)).hasChanged||p)(this[t],e)?(this._$AL.has(t)||this._$AL.set(t,e),!0===i.reflect&&this._$El!==t&&(void 0===this._$EC&&(this._$EC=new Map),this._$EC.set(t,i))):s=!1),!this.isUpdatePending&&s&&(this._$E_=this._$Ej())}async _$Ej(){this.isUpdatePending=!0;try{await this._$E_}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){var t;if(!this.isUpdatePending)return;this.hasUpdated,this._$Ei&&(this._$Ei.forEach(((t,e)=>this[e]=t)),this._$Ei=void 0);let e=!1;const i=this._$AL;try{e=this.shouldUpdate(i),e?(this.willUpdate(i),null===(t=this._$ES)||void 0===t||t.forEach((t=>{var e;return null===(e=t.hostUpdate)||void 0===e?void 0:e.call(t)})),this.update(i)):this._$Ek()}catch(t){throw e=!1,this._$Ek(),t}e&&this._$AE(i)}willUpdate(t){}_$AE(t){var e;null===(e=this._$ES)||void 0===e||e.forEach((t=>{var e;return null===(e=t.hostUpdated)||void 0===e?void 0:e.call(t)})),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$Ek(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$E_}shouldUpdate(t){return!0}update(t){void 0!==this._$EC&&(this._$EC.forEach(((t,e)=>this._$EO(e,this[e],t))),this._$EC=void 0),this._$Ek()}updated(t){}firstUpdated(t){}} + */;var l;const h=window,a=h.trustedTypes,c=a?a.emptyScript:"",d=h.reactiveElementPolyfillSupport,u={toAttribute(t,e){switch(e){case Boolean:t=t?c:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},p=(t,e)=>e!==t&&(e==e||t==t),v={attribute:!0,type:String,converter:u,reflect:!1,hasChanged:p},$="finalized";class f extends HTMLElement{constructor(){super(),this._$Ei=new Map,this.isUpdatePending=!1,this.hasUpdated=!1,this._$El=null,this._$Eu()}static addInitializer(t){var e;this.finalize(),(null!==(e=this.h)&&void 0!==e?e:this.h=[]).push(t)}static get observedAttributes(){this.finalize();const t=[];return this.elementProperties.forEach(((e,i)=>{const s=this._$Ep(i,e);void 0!==s&&(this._$Ev.set(s,i),t.push(s))})),t}static createProperty(t,e=v){if(e.state&&(e.attribute=!1),this.finalize(),this.elementProperties.set(t,e),!e.noAccessor&&!this.prototype.hasOwnProperty(t)){const i="symbol"==typeof t?Symbol():"__"+t,s=this.getPropertyDescriptor(t,i,e);void 0!==s&&Object.defineProperty(this.prototype,t,s)}}static getPropertyDescriptor(t,e,i){return{get(){return this[e]},set(s){const n=this[t];this[e]=s,this.requestUpdate(t,n,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)||v}static finalize(){if(this.hasOwnProperty($))return!1;this[$]=!0;const t=Object.getPrototypeOf(this);if(t.finalize(),void 0!==t.h&&(this.h=[...t.h]),this.elementProperties=new Map(t.elementProperties),this._$Ev=new Map,this.hasOwnProperty("properties")){const t=this.properties,e=[...Object.getOwnPropertyNames(t),...Object.getOwnPropertySymbols(t)];for(const i of e)this.createProperty(i,t[i])}return this.elementStyles=this.finalizeStyles(this.styles),!0}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const t of i)e.unshift(r(t))}else void 0!==t&&e.push(r(t));return e}static _$Ep(t,e){const i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}_$Eu(){var t;this._$E_=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$Eg(),this.requestUpdate(),null===(t=this.constructor.h)||void 0===t||t.forEach((t=>t(this)))}addController(t){var e,i;(null!==(e=this._$ES)&&void 0!==e?e:this._$ES=[]).push(t),void 0!==this.renderRoot&&this.isConnected&&(null===(i=t.hostConnected)||void 0===i||i.call(t))}removeController(t){var e;null===(e=this._$ES)||void 0===e||e.splice(this._$ES.indexOf(t)>>>0,1)}_$Eg(){this.constructor.elementProperties.forEach(((t,e)=>{this.hasOwnProperty(e)&&(this._$Ei.set(e,this[e]),delete this[e])}))}createRenderRoot(){var i;const s=null!==(i=this.shadowRoot)&&void 0!==i?i:this.attachShadow(this.constructor.shadowRootOptions);return((i,s)=>{e?i.adoptedStyleSheets=s.map((t=>t instanceof CSSStyleSheet?t:t.styleSheet)):s.forEach((e=>{const s=document.createElement("style"),n=t.litNonce;void 0!==n&&s.setAttribute("nonce",n),s.textContent=e.cssText,i.appendChild(s)}))})(s,this.constructor.elementStyles),s}connectedCallback(){var t;void 0===this.renderRoot&&(this.renderRoot=this.createRenderRoot()),this.enableUpdating(!0),null===(t=this._$ES)||void 0===t||t.forEach((t=>{var e;return null===(e=t.hostConnected)||void 0===e?void 0:e.call(t)}))}enableUpdating(t){}disconnectedCallback(){var t;null===(t=this._$ES)||void 0===t||t.forEach((t=>{var e;return null===(e=t.hostDisconnected)||void 0===e?void 0:e.call(t)}))}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$EO(t,e,i=v){var s;const n=this.constructor._$Ep(t,i);if(void 0!==n&&!0===i.reflect){const o=(void 0!==(null===(s=i.converter)||void 0===s?void 0:s.toAttribute)?i.converter:u).toAttribute(e,i.type);this._$El=t,null==o?this.removeAttribute(n):this.setAttribute(n,o),this._$El=null}}_$AK(t,e){var i;const s=this.constructor,n=s._$Ev.get(t);if(void 0!==n&&this._$El!==n){const t=s.getPropertyOptions(n),o="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==(null===(i=t.converter)||void 0===i?void 0:i.fromAttribute)?t.converter:u;this._$El=n,this[n]=o.fromAttribute(e,t.type),this._$El=null}}requestUpdate(t,e,i){let s=!0;void 0!==t&&(((i=i||this.constructor.getPropertyOptions(t)).hasChanged||p)(this[t],e)?(this._$AL.has(t)||this._$AL.set(t,e),!0===i.reflect&&this._$El!==t&&(void 0===this._$EC&&(this._$EC=new Map),this._$EC.set(t,i))):s=!1),!this.isUpdatePending&&s&&(this._$E_=this._$Ej())}async _$Ej(){this.isUpdatePending=!0;try{await this._$E_}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){var t;if(!this.isUpdatePending)return;this.hasUpdated,this._$Ei&&(this._$Ei.forEach(((t,e)=>this[e]=t)),this._$Ei=void 0);let e=!1;const i=this._$AL;try{e=this.shouldUpdate(i),e?(this.willUpdate(i),null===(t=this._$ES)||void 0===t||t.forEach((t=>{var e;return null===(e=t.hostUpdate)||void 0===e?void 0:e.call(t)})),this.update(i)):this._$Ek()}catch(t){throw e=!1,this._$Ek(),t}e&&this._$AE(i)}willUpdate(t){}_$AE(t){var e;null===(e=this._$ES)||void 0===e||e.forEach((t=>{var e;return null===(e=t.hostUpdated)||void 0===e?void 0:e.call(t)})),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$Ek(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$E_}shouldUpdate(t){return!0}update(t){void 0!==this._$EC&&(this._$EC.forEach(((t,e)=>this._$EO(e,this[e],t))),this._$EC=void 0),this._$Ek()}updated(t){}firstUpdated(t){}} /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ -var f;_[$]=!0,_.elementProperties=new Map,_.elementStyles=[],_.shadowRootOptions={mode:"open"},null==d||d({ReactiveElement:_}),(null!==(l=h.reactiveElementVersions)&&void 0!==l?l:h.reactiveElementVersions=[]).push("1.6.3");const A=window,m=A.trustedTypes,g=m?m.createPolicy("lit-html",{createHTML:t=>t}):void 0,y="$lit$",E=`lit$${(Math.random()+"").slice(9)}$`,b="?"+E,S=`<${b}>`,w=document,C=()=>w.createComment(""),U=t=>null===t||"object"!=typeof t&&"function"!=typeof t,x=Array.isArray,k="[ \t\n\f\r]",H=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,P=/-->/g,N=/>/g,T=RegExp(`>|${k}(?:([^\\s"'>=/]+)(${k}*=${k}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),O=/'/g,M=/"/g,R=/^(?:script|style|textarea|title)$/i,D=(t=>(e,...i)=>({_$litType$:t,strings:e,values:i}))(1),B=Symbol.for("lit-noChange"),I=Symbol.for("lit-nothing"),z=new WeakMap,L=w.createTreeWalker(w,129,null,!1);function j(t,e){if(!Array.isArray(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==g?g.createHTML(e):e}const F=(t,e)=>{const i=t.length-1,s=[];let n,o=2===e?"":"",r=H;for(let e=0;e"===h[0]?(r=null!=n?n:H,a=-1):void 0===h[1]?a=-2:(a=r.lastIndex-h[2].length,l=h[1],r=void 0===h[3]?T:'"'===h[3]?M:O):r===M||r===O?r=T:r===P||r===N?r=H:(r=T,n=void 0);const d=r===T&&t[e+1].startsWith("/>")?" ":"";o+=r===H?i+S:a>=0?(s.push(l),i.slice(0,a)+y+i.slice(a)+E+d):i+E+(-2===a?(s.push(void 0),e):d)}return[j(t,o+(t[i]||"")+(2===e?"":"")),s]};class V{constructor({strings:t,_$litType$:e},i){let s;this.parts=[];let n=0,o=0;const r=t.length-1,l=this.parts,[h,a]=F(t,e);if(this.el=V.createElement(h,i),L.currentNode=this.el.content,2===e){const t=this.el.content,e=t.firstChild;e.remove(),t.append(...e.childNodes)}for(;null!==(s=L.nextNode())&&l.length0){s.textContent=m?m.emptyScript:"";for(let i=0;ix(t)||"function"==typeof(null==t?void 0:t[Symbol.iterator]))(t)?this.T(t):this._(t)}k(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}$(t){this._$AH!==t&&(this._$AR(),this._$AH=this.k(t))}_(t){this._$AH!==I&&U(this._$AH)?this._$AA.nextSibling.data=t:this.$(w.createTextNode(t)),this._$AH=t}g(t){var e;const{values:i,_$litType$:s}=t,n="number"==typeof s?this._$AC(t):(void 0===s.el&&(s.el=V.createElement(j(s.h,s.h[0]),this.options)),s);if((null===(e=this._$AH)||void 0===e?void 0:e._$AD)===n)this._$AH.v(i);else{const t=new q(n,this),e=t.u(this.options);t.v(i),this.$(e),this._$AH=t}}_$AC(t){let e=z.get(t.strings);return void 0===e&&z.set(t.strings,e=new V(t)),e}T(t){x(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let i,s=0;for(const n of t)s===e.length?e.push(i=new Y(this.k(C()),this.k(C()),this,this.options)):i=e[s],i._$AI(n),s++;s2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=I}get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}_$AI(t,e=this,i,s){const n=this.strings;let o=!1;if(void 0===n)t=W(this,t,e,0),o=!U(t)||t!==this._$AH&&t!==B,o&&(this._$AH=t);else{const s=t;let r,l;for(t=n[0],r=0;r{var s,n;const o=null!==(s=null==i?void 0:i.renderBefore)&&void 0!==s?s:e;let r=o._$litPart$;if(void 0===r){const t=null!==(n=null==i?void 0:i.renderBefore)&&void 0!==n?n:null;o._$litPart$=r=new Y(e.insertBefore(C(),t),t,void 0,null!=i?i:{})}return r._$AI(t),r +var _;f[$]=!0,f.elementProperties=new Map,f.elementStyles=[],f.shadowRootOptions={mode:"open"},null==d||d({ReactiveElement:f}),(null!==(l=h.reactiveElementVersions)&&void 0!==l?l:h.reactiveElementVersions=[]).push("1.6.3");const g=window,m=g.trustedTypes,A=m?m.createPolicy("lit-html",{createHTML:t=>t}):void 0,y="$lit$",E=`lit$${(Math.random()+"").slice(9)}$`,b="?"+E,S=`<${b}>`,w=document,C=()=>w.createComment(""),U=t=>null===t||"object"!=typeof t&&"function"!=typeof t,x=Array.isArray,k="[ \t\n\f\r]",P=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,H=/-->/g,N=/>/g,O=RegExp(`>|${k}(?:([^\\s"'>=/]+)(${k}*=${k}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),R=/'/g,T=/"/g,M=/^(?:script|style|textarea|title)$/i,D=(t=>(e,...i)=>({_$litType$:t,strings:e,values:i}))(1),I=Symbol.for("lit-noChange"),z=Symbol.for("lit-nothing"),B=new WeakMap,j=w.createTreeWalker(w,129,null,!1);function F(t,e){if(!Array.isArray(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==A?A.createHTML(e):e}const L=(t,e)=>{const i=t.length-1,s=[];let n,o=2===e?"":"",r=P;for(let e=0;e"===h[0]?(r=null!=n?n:P,a=-1):void 0===h[1]?a=-2:(a=r.lastIndex-h[2].length,l=h[1],r=void 0===h[3]?O:'"'===h[3]?T:R):r===T||r===R?r=O:r===H||r===N?r=P:(r=O,n=void 0);const d=r===O&&t[e+1].startsWith("/>")?" ":"";o+=r===P?i+S:a>=0?(s.push(l),i.slice(0,a)+y+i.slice(a)+E+d):i+E+(-2===a?(s.push(void 0),e):d)}return[F(t,o+(t[i]||"")+(2===e?"":"")),s]};class V{constructor({strings:t,_$litType$:e},i){let s;this.parts=[];let n=0,o=0;const r=t.length-1,l=this.parts,[h,a]=L(t,e);if(this.el=V.createElement(h,i),j.currentNode=this.el.content,2===e){const t=this.el.content,e=t.firstChild;e.remove(),t.append(...e.childNodes)}for(;null!==(s=j.nextNode())&&l.length0){s.textContent=m?m.emptyScript:"";for(let i=0;ix(t)||"function"==typeof(null==t?void 0:t[Symbol.iterator]))(t)?this.T(t):this._(t)}k(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}$(t){this._$AH!==t&&(this._$AR(),this._$AH=this.k(t))}_(t){this._$AH!==z&&U(this._$AH)?this._$AA.nextSibling.data=t:this.$(w.createTextNode(t)),this._$AH=t}g(t){var e;const{values:i,_$litType$:s}=t,n="number"==typeof s?this._$AC(t):(void 0===s.el&&(s.el=V.createElement(F(s.h,s.h[0]),this.options)),s);if((null===(e=this._$AH)||void 0===e?void 0:e._$AD)===n)this._$AH.v(i);else{const t=new q(n,this),e=t.u(this.options);t.v(i),this.$(e),this._$AH=t}}_$AC(t){let e=B.get(t.strings);return void 0===e&&B.set(t.strings,e=new V(t)),e}T(t){x(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let i,s=0;for(const n of t)s===e.length?e.push(i=new Y(this.k(C()),this.k(C()),this,this.options)):i=e[s],i._$AI(n),s++;s2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=z}get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}_$AI(t,e=this,i,s){const n=this.strings;let o=!1;if(void 0===n)t=W(this,t,e,0),o=!U(t)||t!==this._$AH&&t!==I,o&&(this._$AH=t);else{const s=t;let r,l;for(t=n[0],r=0;r{var s,n;const o=null!==(s=null==i?void 0:i.renderBefore)&&void 0!==s?s:e;let r=o._$litPart$;if(void 0===r){const t=null!==(n=null==i?void 0:i.renderBefore)&&void 0!==n?n:null;o._$litPart$=r=new Y(e.insertBefore(C(),t),t,void 0,null!=i?i:{})}return r._$AI(t),r /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause - */};var it,st;class nt extends _{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){var t,e;const i=super.createRenderRoot();return null!==(t=(e=this.renderOptions).renderBefore)&&void 0!==t||(e.renderBefore=i.firstChild),i}update(t){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=et(e,this.renderRoot,this.renderOptions)}connectedCallback(){var t;super.connectedCallback(),null===(t=this._$Do)||void 0===t||t.setConnected(!0)}disconnectedCallback(){var t;super.disconnectedCallback(),null===(t=this._$Do)||void 0===t||t.setConnected(!1)}render(){return B}}nt.finalized=!0,nt._$litElement$=!0,null===(it=globalThis.litElementHydrateSupport)||void 0===it||it.call(globalThis,{LitElement:nt});const ot=globalThis.litElementPolyfillSupport;null==ot||ot({LitElement:nt}),(null!==(st=globalThis.litElementVersions)&&void 0!==st?st:globalThis.litElementVersions=[]).push("3.3.3");const rt=[0,31,59,90,120,151,181,212,243,273,304,334],lt=[0,1,25,49,73,97,121,145,146,147,171,195,211,243,267,291,292],ht=["Yestar","Narrin","Nenim","Sulim","Virta","Lothess","Narnya","Attendes","Loende","Cerim","Urim","Yavar","Narquel","Hiss","Ring","Mettare"],at=["Seren","Anar","Noren","Aldea","Erwer","Elenya"],ct=t=>`${t<10?"0":""}${t.toFixed(0)}`;class dt{constructor(t,e=1e3){this.value=new Date,(this.host=t).addController(this),this.timeout=e}hostConnected(){this._timerID=setInterval((()=>{this.value=new Date,this.host.requestUpdate()}),this.timeout)}hostDisconnected(){clearInterval(this._timerID),this._timerID=void 0}}const ut=o`*,::after,::before{all:unset;display:revert;box-sizing:border-box}:host{padding-top:0;letter-spacing:1px;--default-font-size:calc(clamp(0.63rem, calc(0.5rem + 0.63vw), 0.9rem));font-family:Bitwise,Audiowide,Tahoma,Arial,Helvetica,sans-serif;flex:0 1 auto;text-align:left}div#clock{padding:.175rem .375rem .175rem .375rem;background-color:var(--pendorclock-background-color,#000030);color:var(--pendorclock-color,#fff);font-size:var(--pendorclock-font-size,--default-font-size);line-height:var(--pendorclock-line-height,1.35);font-weight:var(--pendorclock-font-weight,700);min-width:20ch;max-width:35ch;text-align:center}`,pt=o`@font-face{font-family:Audiowide;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/audiowide/v20/l7gdbjpo0cum0ckerWCdlg_O.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}`;class vt extends nt{static get styles(){return ut}constructor(){super(),this.clock=new dt(this,250)}connectedCallback(){if(super.connectedCallback(),document.getElementById("pendor-font-block"))return;const t=document.head||document.getElementsByTagName("head")[0],e=D``;et(e,t)}tick(t){let e=rt[t.getMonth()]+t.getDate();t.getMonth()>2&&t.getFullYear()%4==0&&e++,e=24*e+t.getHours()-16;const i=t.getFullYear()+16,s=e/30;e%=30;let n=(t.getSeconds()+60*t.getMinutes())/2.25;const o=n/40;n%=40;const r=`${e.toFixed(0)}:${ct(o)}:${ct(n)}`,l=lt.findIndex((t=>t>=s));if(void 0===l||void 0===lt[l-1])return;const h=s-lt[l-1],a=(Math.ceil(h)-1)%6;return`${at[a]}, ${ht[l-1]} ${h.toFixed(0)}, 00${i.toFixed(0)}, ${r}`}render(){return D`
${this.tick(this.clock.value)}
`}}window.customElements.get("pendor-clock")||window.customElements.define("pendor-clock",vt); + */};var it,st;class nt extends f{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){var t,e;const i=super.createRenderRoot();return null!==(t=(e=this.renderOptions).renderBefore)&&void 0!==t||(e.renderBefore=i.firstChild),i}update(t){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=et(e,this.renderRoot,this.renderOptions)}connectedCallback(){var t;super.connectedCallback(),null===(t=this._$Do)||void 0===t||t.setConnected(!0)}disconnectedCallback(){var t;super.disconnectedCallback(),null===(t=this._$Do)||void 0===t||t.setConnected(!1)}render(){return I}}nt.finalized=!0,nt._$litElement$=!0,null===(it=globalThis.litElementHydrateSupport)||void 0===it||it.call(globalThis,{LitElement:nt});const ot=globalThis.litElementPolyfillSupport;null==ot||ot({LitElement:nt}),(null!==(st=globalThis.litElementVersions)&&void 0!==st?st:globalThis.litElementVersions=[]).push("3.3.3"); +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */ +const rt=(t,e)=>"method"===e.kind&&e.descriptor&&!("value"in e.descriptor)?{...e,finisher(i){i.createProperty(e.key,t)}}:{kind:"field",key:Symbol(),placement:"own",descriptor:{},originalKey:e.key,initializer(){"function"==typeof e.initializer&&(this[e.key]=e.initializer.call(this))},finisher(i){i.createProperty(e.key,t)}};const lt=[0,31,59,90,120,151,181,212,243,273,304,334],ht=[0,1,25,49,73,97,121,145,146,147,171,195,211,243,267,291,292],at=["Yestar","Narrin","Nenim","Sulim","Virta","Lothess","Narnya","Attendes","Loende","Cerim","Urim","Yavar","Narquel","Hiss","Ring","Mettare"],ct=["Seren","Anar","Noren","Aldea","Erwer","Elenya"],dt=t=>`${t<10?"0":""}${t.toFixed(0)}`;class ut{constructor(t,e=1e3){this.value=new Date,(this.host=t).addController(this),this.timeout=e}hostConnected(){this._timerID=setInterval((()=>{this.value=new Date,this.host.requestUpdate()}),this.timeout)}hostDisconnected(){clearInterval(this._timerID),this._timerID=void 0}}const pt=o`*,::after,::before{all:unset;display:revert;box-sizing:border-box}:host{padding-top:0;letter-spacing:1px;--default-font-size:calc(clamp(0.63rem, calc(0.5rem + 0.63vw), 0.9rem));font-family:Bitwise,Audiowide,Tahoma,Arial,Helvetica,sans-serif;flex:0 1 auto;text-align:left}div#clock{padding:.175rem .375rem .175rem .375rem;background-color:var(--pendorclock-background-color,#000030);color:var(--pendorclock-color,#fff);font-size:var(--pendorclock-font-size,--default-font-size);line-height:var(--pendorclock-line-height,1.35);font-weight:var(--pendorclock-font-weight,700);min-width:20ch;max-width:35ch;text-align:center}`,vt=o`@font-face{font-family:Audiowide;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/audiowide/v20/l7gdbjpo0cum0ckerWCdlg_O.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}`;class $t extends nt{static get styles(){return pt}constructor(){super(),this.useInternalFont=!1,this.clock=new ut(this,250)}connectedCallback(){if(super.connectedCallback(),!this.useInternalFont)return;if(document.getElementById("pendor-font-block"))return;const t=document.head||document.getElementsByTagName("head")[0],e=D``;et(e,t)}tick(t){let e=lt[t.getMonth()]+t.getDate();t.getMonth()>2&&t.getFullYear()%4==0&&e++,e=24*e+t.getHours()-16;const i=t.getFullYear()+16,s=e/30;e%=30;let n=(t.getSeconds()+60*t.getMinutes())/2.25;const o=n/40;n%=40;const r=`${e.toFixed(0)}:${dt(o)}:${dt(n)}`,l=ht.findIndex((t=>t>=s));if(void 0===l||void 0===ht[l-1])return;const h=s-ht[l-1],a=(Math.ceil(h)-1)%6;return`${ct[a]}, ${at[l-1]} ${h.toFixed(0)}, 00${i.toFixed(0)}, ${r}`}render(){return D`
${this.tick(this.clock.value)}
`}}!function(t,e,i,s){var n,o=arguments.length,r=o<3?e:null===s?s=Object.getOwnPropertyDescriptor(e,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(t,e,i,s);else for(var l=t.length-1;l>=0;l--)(n=t[l])&&(r=(o<3?n(r):o>3?n(e,i,r):n(e,i))||r);o>3&&r&&Object.defineProperty(e,i,r)}([function(t){return(e,i)=>void 0!==i?((t,e,i)=>{e.constructor.createProperty(i,t)})(t,e,i):rt(t,e)}({type:Boolean,attribute:"with-internal-font"})],$t.prototype,"useInternalFont",void 0),window.customElements.get("pendor-clock")||window.customElements.define("pendor-clock",$t); diff --git a/demo/Bitwise.ttf b/demo/Bitwise.ttf new file mode 100644 index 0000000..df8a45c Binary files /dev/null and b/demo/Bitwise.ttf differ diff --git a/demo/Bitwise.woff2 b/demo/Bitwise.woff2 new file mode 100644 index 0000000..c892a6a Binary files /dev/null and b/demo/Bitwise.woff2 differ diff --git a/demo/demo-with-font.html b/demo/demo-with-font.html new file mode 100644 index 0000000..9ce4dbc --- /dev/null +++ b/demo/demo-with-font.html @@ -0,0 +1,43 @@ + + + + + + + +
+ + + diff --git a/demo/index.html b/demo/index.html index 9b06e5e..d541f73 100644 --- a/demo/index.html +++ b/demo/index.html @@ -1,36 +1,34 @@ - + - - - - - -
- - - + + + + + +
+ + diff --git a/package-lock.json b/package-lock.json index 07e72de..e3f8371 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,6 @@ "@typescript-eslint/parser": "^5.48.0", "@web/dev-server": "^0.1.34", "@web/dev-server-storybook": "^0.5.4", - "codespell": "^1.1.7", "concurrently": "^5.3.0", "eslint": "^8.31.0", "eslint-config-prettier": "^8.3.0", @@ -4603,18 +4602,6 @@ "node": ">= 0.12.0" } }, - "node_modules/codespell": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/codespell/-/codespell-1.1.7.tgz", - "integrity": "sha512-WV6TdUbKUGCxCMTqM8Ow3R1ThkdBE6kRnix3PnxSIQ+EAbOBdUfAr/yX2uOubAVIczsOaXI4Q1RDSKMnQvqm1A==", - "dev": true, - "dependencies": { - "chalk": "^2.0.1" - }, - "bin": { - "codespell": "index.js" - } - }, "node_modules/collapse-white-space": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", diff --git a/src/PendorClock.ts b/src/PendorClock.ts index 8a996e1..8615571 100644 --- a/src/PendorClock.ts +++ b/src/PendorClock.ts @@ -1,8 +1,11 @@ import { LitElement, ReactiveController, ReactiveControllerHost, css, html, render } from "lit"; +import { property } from "lit/decorators/property.js"; const terranMonthIntervals = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; -const pendorMonthIntervals = [0, 1, 25, 49, 73, 97, 121, 145, 146, 147, 171, 195, 211, 243, 267, 291, 292]; +const pendorMonthIntervals = [ + 0, 1, 25, 49, 73, 97, 121, 145, 146, 147, 171, 195, 211, 243, 267, 291, 292, +]; const pendorMonthNames = [ "Yestar", @@ -23,6 +26,21 @@ const pendorMonthNames = [ "Mettare", ]; +const centaurMonthIntervals = [0, 1, 43, 85, 145, 146, 147, 189, 249, 291, 292]; + +const centaurMonthNames = [ + "Yestr", + "Tuil", + "Layr", + "Yaiv", + "Attendes", + "Loende", + "Quel", + "Rive", + "Cair", + "Mettare", +]; + const pendorWeekdayNames = ["Seren", "Anar", "Noren", "Aldea", "Erwer", "Elenya"]; const prefix = (n: number) => `${n < 10 ? "0" : ""}${n.toFixed(0)}`; @@ -91,9 +109,11 @@ const fontStyle = css` font-style: normal; font-weight: 400; font-display: swap; - src: url(https://fonts.gstatic.com/s/audiowide/v20/l7gdbjpo0cum0ckerWCdlg_O.woff2) format("woff2"); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, - U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; + src: url(https://fonts.gstatic.com/s/audiowide/v20/l7gdbjpo0cum0ckerWCdlg_O.woff2) + format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, + U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, + U+FEFF, U+FFFD; } `; @@ -104,6 +124,12 @@ export class PendorClock extends LitElement { clock: ClockController; + @property({ type: Boolean, attribute: "with-internal-font" }) + useInternalFont = false; + + @property({ type: Boolean, attribute: "centaurs" }) + useCentaurCalendar = false; + constructor() { super(); this.clock = new ClockController(this, 250); @@ -111,6 +137,9 @@ export class PendorClock extends LitElement { connectedCallback() { super.connectedCallback(); + if (!this.useInternalFont) { + return; + } if (document.getElementById("pendor-font-block")) { return; } @@ -121,17 +150,61 @@ export class PendorClock extends LitElement { render(style, head); } + pendorDate(days: number) { + const nextMonth = pendorMonthIntervals.findIndex((i) => i >= days); + if (nextMonth === undefined || pendorMonthIntervals[nextMonth - 1] === undefined) { + return undefined; + } + const thisMonth = nextMonth - 1; + + // Holidays! Which have no Day-of-Week or Day-of-Month + if ([0, 145, 146, 291].includes(days)) { + return `${pendorMonthNames[thisMonth]}`; + } + + const dayOfMonth = days - pendorMonthIntervals[thisMonth]; + const dayOfWeek = (Math.ceil(days) - 1) % 6; + return `${pendorWeekdayNames[dayOfWeek]}, ${ + pendorMonthNames[thisMonth] + } ${dayOfMonth.toFixed(0)}`; + } + + centaurDate(days: number) { + const nextMonth = centaurMonthIntervals.findIndex((i) => i >= days); + if (nextMonth === undefined || centaurMonthIntervals[nextMonth - 1] === undefined) { + return undefined; + } + const thisMonth = nextMonth - 1; + + // Holidays! Which have no Day-of-Week or Day-of-Month + if ([0, 145, 146, 291].includes(days)) { + return `${centaurMonthNames[thisMonth]}`; + } + + const dayOfMonth = days - centaurMonthIntervals[thisMonth]; + const dayOfWeek = (Math.ceil(days) - 1) % 6; + return `${pendorWeekdayNames[dayOfWeek]}, ${ + centaurMonthNames[thisMonth] + } ${dayOfMonth.toFixed(0)}`; + } + tick(now: Date) { let hours = terranMonthIntervals[now.getMonth()] + now.getDate(); if (now.getMonth() > 2 && now.getFullYear() % 4 == 0) { hours++; } - // DST Calculation, and wildly wrong, but WTF + // DST Calculation, and wildly wrong, but WTF. It was prejudiced against where I live, + // sorry. I just liked watching the clock turnover at midnight every four days, when + // Terra's and Pendor's clocks had the same midnight. + hours = hours * 24 + now.getHours() - 16; + + // Canonically, Pendor was seeded in 1884 CE. This is just a convenience to get the dates + // closer. This sixteen has nothing to do with the one above. const year = now.getFullYear() + 16; - const dayOfYear = hours / 30; + const days = hours / 30; hours = hours % 30; let seconds = (now.getSeconds() + now.getMinutes() * 60) / 2.25; @@ -139,16 +212,8 @@ export class PendorClock extends LitElement { seconds = seconds % 40; const timePart = `${hours.toFixed(0)}:${prefix(minutes)}:${prefix(seconds)}`; - const nextMonth = pendorMonthIntervals.findIndex(i => i >= dayOfYear); - if (nextMonth === undefined || pendorMonthIntervals[nextMonth - 1] === undefined) { - return undefined; - } - - const dayOfMonth = dayOfYear - pendorMonthIntervals[nextMonth - 1]; - const dayOfWeek = (Math.ceil(dayOfMonth) - 1) % 6; - return `${pendorWeekdayNames[dayOfWeek]}, ${pendorMonthNames[nextMonth - 1]} ${dayOfMonth.toFixed( - 0 - )}, 00${year.toFixed(0)}, ${timePart}`; + const daysPart = this.useCentaurCalendar ? this.centaurDate(days) : this.pendorDate(days); + return `${daysPart}, 00${year.toFixed(0)}, ${timePart}`; } render() {