2shay commited on
Commit
316dc2d
·
verified ·
1 Parent(s): e46b947

deploy e3c9fb1

Browse files
assets/index-BbVBwNLj.css ADDED
@@ -0,0 +1 @@
 
 
1
+ @font-face{font-family:Atkinson Hyperlegible;src:url(/fonts/AtkinsonHyperlegible-Regular.woff2)format("woff2");font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:Atkinson Hyperlegible;src:url(/fonts/AtkinsonHyperlegible-Bold.woff2)format("woff2");font-weight:700;font-style:normal;font-display:swap}@font-face{font-family:Atkinson Hyperlegible;src:url(/fonts/AtkinsonHyperlegible-Italic.woff2)format("woff2");font-weight:400;font-style:italic;font-display:swap}@font-face{font-family:Atkinson Hyperlegible;src:url(/fonts/AtkinsonHyperlegible-BoldItalic.woff2)format("woff2");font-weight:700;font-style:italic;font-display:swap}:root{--gutter:16px;--measure:65ch;--border-radius:8px;--color-bg:#faf9f6;--color-fg:#1a1a1a;--color-muted:#5b5b5b;--color-border:#d8d5cd;--color-accent:#7a3b2e;--color-accent-fg:#fff;--color-panel-bg:#fff;--color-input-bg:#fff;--color-focus-ring:#7a3b2e}@media (prefers-color-scheme:dark){:root:not([data-theme=light]){--color-bg:#17171a;--color-fg:#eceae6;--color-muted:#a8a49c;--color-border:#3a3a3f;--color-accent:#e0a893;--color-accent-fg:#17171a;--color-panel-bg:#201f23;--color-input-bg:#201f23;--color-focus-ring:#e0a893}}:root[data-theme=dark]{--color-bg:#17171a;--color-fg:#eceae6;--color-muted:#a8a49c;--color-border:#3a3a3f;--color-accent:#e0a893;--color-accent-fg:#17171a;--color-panel-bg:#201f23;--color-input-bg:#201f23;--color-focus-ring:#e0a893}*{box-sizing:border-box}html,body{max-width:100%;margin:0;padding:0;overflow-x:hidden}body{background:var(--color-bg);color:var(--color-fg);font-family:Atkinson Hyperlegible,system-ui,sans-serif;line-height:1.5}.visually-hidden{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.app-shell{min-height:100vh;padding:var(--gutter);padding-bottom:calc(var(--gutter) * 6);flex-direction:column;display:flex}.app-header{justify-content:space-between;align-items:center;gap:var(--gutter);padding-bottom:var(--gutter);border-bottom:1px solid var(--color-border);margin-bottom:var(--gutter);flex-wrap:wrap;display:flex}.app-title{flex:auto;min-width:0;margin:0;font-size:1.25rem}.dial{border:1px solid var(--color-border);border-radius:var(--border-radius);flex-wrap:wrap;gap:4px;margin:0;padding:4px;display:flex}.dial-option{border-radius:calc(var(--border-radius) - 2px);cursor:pointer;align-items:center;gap:6px;padding:6px 10px;font-size:.9rem;display:inline-flex}.dial-option:has(input:checked){background:var(--color-accent);color:var(--color-accent-fg)}.dial-option input{accent-color:var(--color-accent)}.dial-option input:focus-visible{outline:2px solid var(--color-focus-ring);outline-offset:2px}.theme-toggle{border:1px solid var(--color-border);background:var(--color-panel-bg);color:var(--color-fg);border-radius:var(--border-radius);cursor:pointer;font:inherit;padding:6px 12px}.theme-toggle:focus-visible{outline:2px solid var(--color-focus-ring);outline-offset:2px}.app-main{gap:calc(var(--gutter) * 1.5);max-width:var(--measure);flex-direction:column;flex:auto;width:100%;margin:0 auto;display:flex}.article p{margin:0 0 1em}.paste-box{flex-direction:column;gap:6px;display:flex}.paste-label{font-weight:700}.paste-textarea{border:1px solid var(--color-border);border-radius:var(--border-radius);background:var(--color-input-bg);width:100%;max-width:100%;min-height:8em;color:var(--color-fg);font:inherit;resize:vertical;padding:10px}.paste-textarea:focus-visible{outline:2px solid var(--color-focus-ring);outline-offset:2px}.word-count{color:var(--color-muted);margin:0;font-size:.85rem}.panel{right:var(--gutter);bottom:var(--gutter);width:min(320px, calc(100% - var(--gutter) * 2));background:var(--color-panel-bg);border:1px solid var(--color-border);border-radius:var(--border-radius);padding:var(--gutter);position:fixed}.panel-empty{color:var(--color-muted);margin:0}@media (width<=640px){.panel{left:var(--gutter);right:var(--gutter);width:auto}}
assets/index-DJY3KawE.js ADDED
@@ -0,0 +1 @@
 
 
1
+ import{t as e}from"./net-Czt2kcl5.js";var t,n,r,i,a,o,s,c,l,u,d,f,p,m,h={},g=[],_=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,v=Array.isArray;function y(e,t){for(var n in t)e[n]=t[n];return e}function b(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function x(e,n,r){var i,a,o,s={};for(o in n)o==`key`?i=n[o]:o==`ref`?a=n[o]:s[o]=n[o];if(arguments.length>2&&(s.children=arguments.length>3?t.call(arguments,2):r),typeof e==`function`&&e.defaultProps!=null)for(o in e.defaultProps)s[o]===void 0&&(s[o]=e.defaultProps[o]);return S(e,s,i,a,null)}function S(e,t,i,a,o){var s={type:e,props:t,key:i,ref:a,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:o??++r,__i:-1,__u:0};return o==null&&n.vnode!=null&&n.vnode(s),s}function C(e){return e.children}function w(e,t){this.props=e,this.context=t}function T(e,t){if(t==null)return e.__?T(e.__,e.__i+1):null;for(var n;t<e.__k.length;t++)if((n=e.__k[t])!=null&&n.__e!=null)return n.__e;return typeof e.type==`function`?T(e):null}function E(e){if(e.__P&&e.__d){var t=e.__v,r=t.__e,i=[],a=[],o=y({},t);o.__v=t.__v+1,n.vnode&&n.vnode(o),I(e.__P,o,t,e.__n,e.__P.namespaceURI,32&t.__u?[r]:null,i,r??T(t),!!(32&t.__u),a),o.__v=t.__v,o.__.__k[o.__i]=o,ne(i,o,a),t.__e=t.__=null,o.__e!=r&&D(o)}}function D(e){if((e=e.__)!=null&&e.__c!=null)return e.__e=e.__c.base=null,e.__k.some(function(t){if(t!=null&&t.__e!=null)return e.__e=e.__c.base=t.__e}),D(e)}function O(e){(!e.__d&&(e.__d=!0)&&i.push(e)&&!k.__r++||a!=n.debounceRendering)&&((a=n.debounceRendering)||o)(k)}function k(){try{for(var e,t=1;i.length;)i.length>t&&i.sort(s),e=i.shift(),t=i.length,E(e)}finally{i.length=k.__r=0}}function ee(e,t,n,r,i,a,o,s,c,l,u){var d,f,p,m,_,v,y=r&&r.__k||g,b=t.length;for(c=A(n,t,y,c,b),d=0;d<b;d++)(p=n.__k[d])!=null&&(f=p.__i!=-1&&y[p.__i]||h,p.__i=d,v=I(e,p,f,i,a,o,s,c,l,u),m=p.__e,p.ref&&f.ref!=p.ref&&(f.ref&&R(f.ref,null,p),u.push(p.ref,p.__c||m,p)),_==null&&m!=null&&(_=m),4&p.__u?(c=j(p,c,e),f.__e&&(f.__e=null)):typeof p.type==`function`&&v!==void 0?c=v:m&&(c=m.nextSibling),p.__u&=-7);return n.__e=_,c}function A(e,t,n,r,i){var a,o,s,c,l,u=n.length,d=u,f=0;for(e.__k=Array(i),a=0;a<i;a++)(o=t[a])!=null&&typeof o!=`boolean`&&typeof o!=`function`?(typeof o==`string`||typeof o==`number`||typeof o==`bigint`||o.constructor==String?o=e.__k[a]=S(null,o,null,null,null):v(o)?o=e.__k[a]=S(C,{children:o},null,null,null):o.constructor===void 0&&o.__b>0?o=e.__k[a]=S(o.type,o.props,o.key,o.ref?o.ref:null,o.__v):e.__k[a]=o,c=a+f,o.__=e,o.__b=e.__b+1,s=null,(l=o.__i=M(o,n,c,d))!=-1&&(d--,(s=n[l])&&(s.__u|=2)),s==null||s.__v==null?(l==-1&&(i>u?f--:i<u&&f++),typeof o.type!=`function`&&(o.__u|=4)):l!=c&&(l==c-1?f--:l==c+1?f++:(l>c?f--:f++,o.__u|=4))):e.__k[a]=null;if(d)for(a=0;a<u;a++)(s=n[a])!=null&&!(2&s.__u)&&(s.__e==r&&(r=T(s)),ie(s,s));return r}function j(e,t,n){var r,i;if(typeof e.type==`function`){for(r=e.__k,i=0;r&&i<r.length;i++)r[i]&&(r[i].__=e,t=j(r[i],t,n));return t}e.__e!=t&&(t&&e.type&&!t.parentNode&&(t=T(e)),t=n.insertBefore(e.__e,t||null));do t&&=t.nextSibling;while(t!=null&&t.nodeType==8);return t}function M(e,t,n,r){var i,a,o,s=e.key,c=e.type,l=t[n],u=l!=null&&!(2&l.__u);if(l===null&&s==null||u&&s==l.key&&c==l.type)return n;if(r>+!!u){for(i=n-1,a=n+1;i>=0||a<t.length;)if((l=t[o=i>=0?i--:a++])!=null&&!(2&l.__u)&&s==l.key&&c==l.type)return o}return-1}function N(e,t,n){t[0]==`-`?e.setProperty(t,n??``):e[t]=n==null?``:typeof n!=`number`||_.test(t)?n:n+`px`}function P(e,t,n,r,i){var a,o;n:if(t==`style`){if(typeof n==`string`)e.style.cssText=n;else{if(typeof r==`string`&&(e.style.cssText=r=``),r)for(t in r)n&&t in n||N(e.style,t,``);if(n)for(t in n)r&&n[t]==r[t]||N(e.style,t,n[t])}}else if(t[0]==`o`&&t[1]==`n`)a=t!=(t=t.replace(d,`$1`)),o=t.toLowerCase(),t=o in e||t==`onFocusOut`||t==`onFocusIn`?o.slice(2):t.slice(2),e.l||={},e.l[t+a]=n,n?r?n[u]=r[u]:(n[u]=f,e.addEventListener(t,a?m:p,a)):e.removeEventListener(t,a?m:p,a);else{if(i==`http://www.w3.org/2000/svg`)t=t.replace(/xlink(H|:h)/,`h`).replace(/sName$/,`s`);else if(t!=`width`&&t!=`height`&&t!=`href`&&t!=`list`&&t!=`form`&&t!=`tabIndex`&&t!=`download`&&t!=`rowSpan`&&t!=`colSpan`&&t!=`role`&&t!=`popover`&&t in e)try{e[t]=n??``;break n}catch{}typeof n==`function`||(n==null||!1===n&&t[4]!=`-`?e.removeAttribute(t):e.setAttribute(t,t==`popover`&&n==1?``:n))}}function F(e){return function(t){if(this.l){var r=this.l[t.type+e];if(t[l]==null)t[l]=f++;else if(t[l]<r[u])return;return r(n.event?n.event(t):t)}}}function I(e,t,r,i,a,o,s,c,l,u){var d,f,p,m,h,_,x,S,E,D,O,k,A,j,M,N,P=t.type;if(t.constructor!==void 0)return null;128&r.__u&&(l=!!(32&r.__u),o=[c=t.__e=r.__e]),(d=n.__b)&&d(t);n:if(typeof P==`function`){f=s.length;try{if(E=t.props,D=P.prototype&&P.prototype.render,O=(d=P.contextType)&&i[d.__c],k=d?O?O.props.value:d.__:i,r.__c?S=(p=t.__c=r.__c).__=p.__E:(D?t.__c=p=new P(E,k):(t.__c=p=new w(E,k),p.constructor=P,p.render=ae),O&&O.sub(p),p.state||(p.state={}),p.__n=i,m=p.__d=!0,p.__h=[],p._sb=[]),D&&p.__s==null&&(p.__s=p.state),D&&P.getDerivedStateFromProps!=null&&(p.__s==p.state&&(p.__s=y({},p.__s)),y(p.__s,P.getDerivedStateFromProps(E,p.__s))),h=p.props,_=p.state,p.__v=t,m)D&&P.getDerivedStateFromProps==null&&p.componentWillMount!=null&&p.componentWillMount(),D&&p.componentDidMount!=null&&p.__h.push(p.componentDidMount);else{if(D&&P.getDerivedStateFromProps==null&&E!==h&&p.componentWillReceiveProps!=null&&p.componentWillReceiveProps(E,k),t.__v==r.__v||!p.__e&&p.shouldComponentUpdate!=null&&!1===p.shouldComponentUpdate(E,p.__s,k)){t.__v!=r.__v&&(p.props=E,p.state=p.__s,p.__d=!1),t.__e=r.__e,t.__k=r.__k,t.__k.some(function(e){e&&(e.__=t)}),g.push.apply(p.__h,p._sb),p._sb=[],p.__h.length&&s.push(p),c=T(r);break n}p.componentWillUpdate!=null&&p.componentWillUpdate(E,p.__s,k),D&&p.componentDidUpdate!=null&&p.__h.push(function(){p.componentDidUpdate(h,_,x)})}if(p.context=k,p.props=E,p.__P=e,p.__e=!1,A=n.__r,j=0,D)p.state=p.__s,p.__d=!1,A&&A(t),d=p.render(p.props,p.state,p.context),g.push.apply(p.__h,p._sb),p._sb=[];else do p.__d=!1,A&&A(t),d=p.render(p.props,p.state,p.context),p.state=p.__s;while(p.__d&&++j<25);p.state=p.__s,p.getChildContext!=null&&(i=y(y({},i),p.getChildContext())),D&&!m&&p.getSnapshotBeforeUpdate!=null&&(x=p.getSnapshotBeforeUpdate(h,_)),M=d!=null&&d.type===C&&d.key==null?L(d.props.children):d,c=ee(e,v(M)?M:[M],t,r,i,a,o,s,c,l,u),p.base=t.__e,t.__u&=-161,p.__h.length&&s.push(p),S&&(p.__E=p.__=null)}catch(e){if(s.length=f,t.__v=null,l||o!=null){if(e.then){for(t.__u|=l?160:128;c&&c.nodeType==8&&c.nextSibling;)c=c.nextSibling;o!=null&&(o[o.indexOf(c)]=null),t.__e=c}else if(o!=null)for(N=o.length;N--;)b(o[N])}else t.__e=r.__e;t.__k??=r.__k||[],e.then||te(t),n.__e(e,t,r)}}else o==null&&t.__v==r.__v?(t.__k=r.__k,t.__e=r.__e):c=t.__e=re(r.__e,t,r,i,a,o,s,l,u);return(d=n.diffed)&&d(t),128&t.__u?void 0:c}function te(e){e&&(e.__c&&(e.__c.__e=!0),e.__k&&e.__k.some(te))}function ne(e,t,r){for(var i=0;i<r.length;i++)R(r[i],r[++i],r[++i]);n.__c&&n.__c(t,e),e.some(function(t){try{e=t.__h,t.__h=[],e.some(function(e){e.call(t)})}catch(e){n.__e(e,t.__v)}})}function L(e){return typeof e!=`object`||!e||e.__b>0?e:v(e)?e.map(L):e.constructor===void 0?y({},e):null}function re(e,r,i,a,o,s,c,l,u){var d,f,p,m,g,_,y,x=i.props||h,S=r.props,C=r.type;if(C==`svg`?o=`http://www.w3.org/2000/svg`:C==`math`?o=`http://www.w3.org/1998/Math/MathML`:o||=`http://www.w3.org/1999/xhtml`,s!=null){for(d=0;d<s.length;d++)if((g=s[d])&&`setAttribute`in g==!!C&&(C?g.localName==C:g.nodeType==3)){e=g,s[d]=null;break}}if(e==null){if(C==null)return document.createTextNode(S);e=document.createElementNS(o,C,S.is&&S),l&&=(n.__m&&n.__m(r,s),!1),s=null}if(C==null)x===S||l&&e.data==S||(e.data=S);else{if(s=C==`textarea`&&S.defaultValue!=null?null:s&&t.call(e.childNodes),!l&&s!=null)for(x={},d=0;d<e.attributes.length;d++)x[(g=e.attributes[d]).name]=g.value;for(d in x)g=x[d],d==`dangerouslySetInnerHTML`?p=g:d==`children`||d in S||d==`value`&&`defaultValue`in S||d==`checked`&&`defaultChecked`in S||P(e,d,null,g,o);for(d in S)g=S[d],d==`children`?m=g:d==`dangerouslySetInnerHTML`?f=g:d==`value`?_=g:d==`checked`?y=g:l&&typeof g!=`function`||x[d]===g||P(e,d,g,x[d],o);if(f)l||p&&(f.__html==p.__html||f.__html==e.innerHTML)||(e.innerHTML=f.__html),r.__k=[];else if(p&&(e.innerHTML=``),ee(r.type==`template`?e.content:e,v(m)?m:[m],r,i,a,C==`foreignObject`?`http://www.w3.org/1999/xhtml`:o,s,c,s?s[0]:i.__k&&T(i,0),l,u),s!=null)for(d=s.length;d--;)b(s[d]);l&&C!=`textarea`||(d=`value`,C==`progress`&&_==null?e.removeAttribute(`value`):_!=null&&(_!==e[d]||C==`progress`&&!_||C==`option`&&_!=x[d])&&P(e,d,_,x[d],o),d=`checked`,y!=null&&y!=e[d]&&P(e,d,y,x[d],o))}return e}function R(e,t,r){try{if(typeof e==`function`){var i=typeof e.__u==`function`;i&&e.__u(),i&&t==null||(e.__u=e(t))}else e.current=t}catch(e){n.__e(e,r)}}function ie(e,t,r){var i,a;if(n.unmount&&n.unmount(e),(i=e.ref)&&(i.current&&i.current!=e.__e||R(i,null,t)),(i=e.__c)!=null){if(i.componentWillUnmount)try{i.componentWillUnmount()}catch(e){n.__e(e,t)}i.base=i.__P=i.__n=null}if(i=e.__k)for(a=0;a<i.length;a++)i[a]&&ie(i[a],t,r||typeof e.type!=`function`);r||b(e.__e),e.__c=e.__=e.__e=void 0}function ae(e,t,n){return this.constructor(e,n)}function oe(e,r,i){var a,o,s,c;r==document&&(r=document.documentElement),n.__&&n.__(e,r),o=(a=typeof i==`function`)?null:i&&i.__k||r.__k,s=[],c=[],I(r,e=(!a&&i||r).__k=x(C,null,[e]),o||h,h,r.namespaceURI,!a&&i?[i]:o?null:r.firstChild?t.call(r.childNodes):null,s,!a&&i?i:o?o.__e:r.firstChild,a,c),ne(s,e,c),e.props.children=null}t=g.slice,n={__e:function(e,t,n,r){for(var i,a,o;t=t.__;)if((i=t.__c)&&!i.__)try{if((a=i.constructor)&&a.getDerivedStateFromError!=null&&(i.setState(a.getDerivedStateFromError(e)),o=i.__d),i.componentDidCatch!=null&&(i.componentDidCatch(e,r||{}),o=i.__d),o)return i.__E=i}catch(t){e=t}throw e}},r=0,w.prototype.setState=function(e,t){var n=this.__s!=null&&this.__s!=this.state?this.__s:this.__s=y({},this.state);typeof e==`function`&&(e=e(y({},n),this.props)),e&&y(n,e),e!=null&&this.__v&&(t&&this._sb.push(t),O(this))},w.prototype.forceUpdate=function(e){this.__v&&(this.__e=!0,e&&this.__h.push(e),O(this))},w.prototype.render=C,i=[],o=typeof Promise==`function`?Promise.prototype.then.bind(Promise.resolve()):setTimeout,s=function(e,t){return e.__v.__b-t.__v.__b},k.__r=0,c=Math.random().toString(8),l=`__d`+c,u=`__a`+c,d=/(PointerCapture)$|Capture$/i,f=0,p=F(!1),m=F(!0);var z,B,V,H,U=0,W=[],G=n,K=G.__b,q=G.__r,J=G.diffed,se=G.__c,ce=G.unmount,le=G.__;function ue(e,t){G.__h&&G.__h(B,e,U||t),U=0;var n=B.__H||(B.__H={__:[],__h:[]});return e>=n.__.length&&n.__.push({}),n.__[e]}function Y(e){return U=1,de(_e,e)}function de(e,t,n){var r=ue(z++,2);if(r.t=e,!r.__c&&(r.__=[n?n(t):_e(void 0,t),function(e){var t=r.__N?r.__N[0]:r.__[0],n=r.t(t,e);t!==n&&(r.__N=[n,r.__[1]],r.__c.setState({}))}],r.__c=B,!B.__f)){var i=function(e,t,n){if(!r.__c.__H)return!0;var i=!1,o=r.__c.props!==e;if(r.__c.__H.__.some(function(e){if(e.__N){i=!0;var t=e.__[0];e.__=e.__N,e.__N=void 0,t!==e.__[0]&&(o=!0)}}),a){var s=a.call(this,e,t,n);return i?s||o:s}return!i||o};B.__f=!0;var a=B.shouldComponentUpdate,o=B.componentWillUpdate;B.componentWillUpdate=function(e,t,n){if(this.__e){var r=a;a=void 0,i(e,t,n),a=r}o&&o.call(this,e,t,n)},B.shouldComponentUpdate=i}return r.__N||r.__}function fe(e,t){var n=ue(z++,3);!G.__s&&ge(n.__H,t)&&(n.__=e,n.u=t,B.__H.__h.push(n))}function pe(){for(var e;e=W.shift();){var t=e.__H;if(e.__P&&t)try{t.__h.some(X),t.__h.some(Z),t.__h=[]}catch(n){t.__h=[],G.__e(n,e.__v)}}}G.__b=function(e){B=null,K&&K(e)},G.__=function(e,t){e&&t.__k&&t.__k.__m&&(e.__m=t.__k.__m),le&&le(e,t)},G.__r=function(e){q&&q(e),z=0;var t=(B=e.__c).__H;t&&(V===B?(t.__h=[],B.__h=[],t.__.some(function(e){e.__N&&(e.__=e.__N),e.u=e.__N=void 0})):(t.__h.some(X),t.__h.some(Z),t.__h=[],z=0)),V=B},G.diffed=function(e){J&&J(e);var t=e.__c;t&&t.__H&&(t.__H.__h.length&&(W.push(t)!==1&&H===G.requestAnimationFrame||((H=G.requestAnimationFrame)||he)(pe)),t.__H.__.some(function(e){e.u&&=(e.__H=e.u,void 0)})),V=B=null},G.__c=function(e,t){t.some(function(e){try{e.__h.some(X),e.__h=e.__h.filter(function(e){return!e.__||Z(e)})}catch(n){t.some(function(e){e.__h&&=[]}),t=[],G.__e(n,e.__v)}}),se&&se(e,t)},G.unmount=function(e){ce&&ce(e);var t,n=e.__c;n&&n.__H&&(n.__H.__.some(function(e){try{X(e)}catch(e){t=e}}),n.__H=void 0,t&&G.__e(t,n.__v))};var me=typeof requestAnimationFrame==`function`;function he(e){var t,n=function(){clearTimeout(r),me&&cancelAnimationFrame(t),setTimeout(e)},r=setTimeout(n,35);me&&(t=requestAnimationFrame(n))}function X(e){var t=B,n=e.__c;typeof n==`function`&&(e.__c=void 0,n()),B=t}function Z(e){var t=B;e.__c=e.__(),B=t}function ge(e,t){return!e||e.length!==t.length||t.some(function(t,n){return t!==e[n]})}function _e(e,t){return typeof t==`function`?t(e):t}var ve={$comment:`The compression dial (docs/PLAN.md C3, S0-03). Web and Mac load this file; neither hard-codes a level. Order = dial order, longest first. Labels come from spec/strings/en.json by label_key. Prompts are complete user messages with a {{text}} placeholder (reduce: {{lines}}); the runtime sends them through the model's chat template with thinking off.`,version:1,default:`short`,levels:[{id:`readall`,label_key:`dial.readall`,uses_llm:!1,spoken:!0,description:`Every sentence, in order, read aloud. No model. Always one key away.`},{id:`short`,label_key:`dial.short`,uses_llm:!0,spoken:!0,prompt:`prompts/short.md`,max_bullets_per_chunk:6,min_bullets_per_chunk:1,max_words_per_bullet:18,max_new_tokens:220,description:`3 to 6 plain sentences per chunk.`},{id:`caveman`,label_key:`dial.caveman`,uses_llm:!0,spoken:!0,prompt:`prompts/caveman.md`,max_bullets_per_chunk:5,min_bullets_per_chunk:1,max_words_per_bullet:9,max_new_tokens:120,description:`2 to 5 bullets of at most 9 words. Register: plain words, one idea per line, answer first.`},{id:`oneline`,label_key:`dial.oneline`,uses_llm:!0,spoken:!0,prompt:`prompts/oneline.md`,reduce_prompt:`prompts/reduce-oneline.md`,max_bullets_per_chunk:1,min_bullets_per_chunk:1,max_words_per_bullet:25,max_new_tokens:60,reduce:{group_size:10,max_depth:2,fallback_level:`short`,max_cut_fraction:.5},description:`One line for the whole document. More than one chunk: per-chunk lines, then reduce. Only the final line is spoken.`}]},ye={$comment:`Every user-facing string, both targets (docs/PLAN.md rule 8). S0-03 owns the KEYS; S1-L0 (Claude, Voice Bank) fills every VALUE. Web and Mac load this file; no string literal lives in UI code (scripts/strings-check.mjs). Every notice/error is also spoken (rule 8, 'Speak messages' default on). Placeholders {n} {mb} {words} {level} are filled at runtime.`,version:1,locale:`en`,$plan_wording:{"notice.dial_shorter":`Making it shorter.`,"notice.dial_longer":`Adding detail.`,"notice.all_cut":`Couldn't make a summary I trust for this part.`,"notice.oneline_failed":`Couldn't boil this down to one line I trust. Here's the short version.`,"notice.input_limit":`This is over 120,000 words. Select a part of it.`,"mac.intake.press_cmd_c":`Press ⌘C to read it`,"mac.intake.no_copy_seen":`Didn't see a copy.`,"loading.summarizer_button":`Load summarizer ({mb} MB)`,"dial.readall":`Read all`,"dial.short":`Short`,"dial.caveman":`Caveman`,"dial.oneline":`One line`,$comment:`Wording the plan fixes (rules 2, 11, C3, C9, Architecture). S1-L0 keeps the meaning; it may tune words after the Voice Bank pass.`},strings:{"app.title":`TODO(S1-L0)`,"theme.toggle":`TODO(S1-L0)`,"dial.readall":`TODO(S1-L0)`,"dial.short":`TODO(S1-L0)`,"dial.caveman":`TODO(S1-L0)`,"dial.oneline":`TODO(S1-L0)`,"panel.title":`TODO(S1-L0)`,"panel.empty":`TODO(S1-L0)`,"panel.read_chip":`TODO(S1-L0)`,"panel.summarize":`TODO(S1-L0)`,"panel.stop":`TODO(S1-L0)`,"panel.pause":`TODO(S1-L0)`,"panel.resume":`TODO(S1-L0)`,"panel.skip":`TODO(S1-L0)`,"panel.read_this_part":`TODO(S1-L0)`,"panel.rate":`TODO(S1-L0)`,"panel.rate_slower":`TODO(S1-L0)`,"panel.rate_faster":`TODO(S1-L0)`,"panel.voice":`TODO(S1-L0)`,"panel.speak_messages":`TODO(S1-L0)`,"panel.hide_pip":`TODO(S1-L0)`,"panel.show_pip":`TODO(S1-L0)`,"panel.font_size":`TODO(S1-L0)`,"panel.spacing":`TODO(S1-L0)`,"panel.dark_mode":`TODO(S1-L0)`,"panel.position":`TODO(S1-L0)`,"panel.bug_report":`TODO(S1-L0)`,"panel.stats":`TODO(S1-L0)`,"panel.close":`TODO(S1-L0)`,"panel.now_reading":`TODO(S1-L0)`,"panel.next_up":`TODO(S1-L0)`,"intake.paste_placeholder":`TODO(S1-L0)`,"intake.word_count":`TODO(S1-L0)`,"intake.drop_here":`TODO(S1-L0)`,"intake.empty":`TODO(S1-L0)`,"intake.sample_label":`TODO(S1-L0)`,"demo.try_it_now":`TODO(S1-L0)`,"demo.recording_label":`TODO(S1-L0)`,"demo.switch_level":`TODO(S1-L0)`,"loading.probing":`TODO(S1-L0)`,"loading.voice":`TODO(S1-L0)`,"loading.summarizer_button":`TODO(S1-L0)`,"loading.summarizer_size":`TODO(S1-L0)`,"loading.progress":`TODO(S1-L0)`,"loading.cached":`TODO(S1-L0)`,"loading.first_time":`TODO(S1-L0)`,"loading.save_data":`TODO(S1-L0)`,"loading.mobile":`TODO(S1-L0)`,"loading.almost":`TODO(S1-L0)`,"loading.ready":`TODO(S1-L0)`,"notice.dial_shorter":`TODO(S1-L0)`,"notice.dial_longer":`TODO(S1-L0)`,"notice.all_cut":`TODO(S1-L0)`,"notice.oneline_failed":`TODO(S1-L0)`,"notice.input_limit":`TODO(S1-L0)`,"notice.no_webgpu":`TODO(S1-L0)`,"notice.probe_failed":`TODO(S1-L0)`,"notice.low_end_tier":`TODO(S1-L0)`,"notice.stopped":`TODO(S1-L0)`,"notice.done":`TODO(S1-L0)`,"notice.paused":`TODO(S1-L0)`,"notice.making_summary":`TODO(S1-L0)`,"notice.reading_all":`TODO(S1-L0)`,"error.model_download":`TODO(S1-L0)`,"error.voice":`TODO(S1-L0)`,"error.generation":`TODO(S1-L0)`,"error.storage_full":`TODO(S1-L0)`,"error.empty_input":`TODO(S1-L0)`,"error.offline":`TODO(S1-L0)`,"error.unknown":`TODO(S1-L0)`,"report.title":`TODO(S1-L0)`,"report.preview_intro":`TODO(S1-L0)`,"report.describe":`TODO(S1-L0)`,"report.open_github":`TODO(S1-L0)`,"report.copy":`TODO(S1-L0)`,"report.copied":`TODO(S1-L0)`,"report.privacy_note":`TODO(S1-L0)`,"stats.title":`TODO(S1-L0)`,"stats.empty":`TODO(S1-L0)`,"stats.export":`TODO(S1-L0)`,"stats.clear":`TODO(S1-L0)`,"a11y.panel_region":`TODO(S1-L0)`,"a11y.bullet_list":`TODO(S1-L0)`,"a11y.dial":`TODO(S1-L0)`,"a11y.pip":`TODO(S1-L0)`,"mac.menu.summarize_selection":`TODO(S1-L0)`,"mac.menu.summarize_clipboard":`TODO(S1-L0)`,"mac.menu.summarize_region":`TODO(S1-L0)`,"mac.menu.settings":`TODO(S1-L0)`,"mac.menu.stats":`TODO(S1-L0)`,"mac.menu.check_updates":`TODO(S1-L0)`,"mac.menu.quit":`TODO(S1-L0)`,"mac.onboarding.try_it":`TODO(S1-L0)`,"mac.onboarding.first_success":`TODO(S1-L0)`,"mac.onboarding.offer_accessibility":`TODO(S1-L0)`,"mac.onboarding.updates_disclosure":`TODO(S1-L0)`,"mac.onboarding.done":`TODO(S1-L0)`,"mac.permission.accessibility":`TODO(S1-L0)`,"mac.permission.accessibility_denied":`TODO(S1-L0)`,"mac.permission.screen_recording":`TODO(S1-L0)`,"mac.permission.screen_recording_denied":`TODO(S1-L0)`,"mac.permission.open_settings":`TODO(S1-L0)`,"mac.intake.press_cmd_c":`TODO(S1-L0)`,"mac.intake.no_copy_seen":`TODO(S1-L0)`,"mac.intake.clipboard_empty":`TODO(S1-L0)`,"mac.intake.clipboard_not_text":`TODO(S1-L0)`,"mac.ocr.first_run_warning":`TODO(S1-L0)`,"mac.ocr.nothing_found":`TODO(S1-L0)`,"mac.ocr.pick_region":`TODO(S1-L0)`,"mac.update.toggle":`TODO(S1-L0)`,"mac.update.available":`TODO(S1-L0)`,"mac.update.up_to_date":`TODO(S1-L0)`,"mac.license.trial_days_left":`TODO(S1-L0)`,"mac.license.enter_key":`TODO(S1-L0)`,"mac.license.licensed":`TODO(S1-L0)`,"mac.license.nag":`TODO(S1-L0)`,"mac.license.sign_out":`TODO(S1-L0)`,"mac.license.invalid":`TODO(S1-L0)`}}.strings;function Q(e){return ye[e]??e}var be=0;Array.isArray;function $(e,t,r,i,a,o){t||={};var s,c,l=t;if(`ref`in l)for(c in l={},t)c==`ref`?s=t[c]:l[c]=t[c];var u={type:e,props:l,key:r,ref:s,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--be,__i:-1,__u:0,__source:a,__self:o};if(typeof e==`function`&&(s=e.defaultProps))for(c in s)l[c]===void 0&&(l[c]=s[c]);return n.vnode&&n.vnode(u),u}var xe=ve.levels,Se=ve.default??`short`;function Ce({level:e,onChange:t}){return $(`fieldset`,{class:`dial`,children:[$(`legend`,{class:`visually-hidden`,children:Q(`a11y.dial`)}),xe.map(n=>$(`label`,{class:`dial-option`,children:[$(`input`,{type:`radio`,name:`level`,value:n.id,checked:e===n.id,onChange:()=>t(n.id)}),$(`span`,{children:Q(n.label_key)})]},n.id))]})}function we(){if(typeof document<`u`){let e=document.documentElement.getAttribute(`data-theme`);if(e===`dark`||e===`light`)return e}return typeof matchMedia<`u`&&matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`}function Te(){let[e,t]=Y(we);return $(`button`,{type:`button`,class:`theme-toggle`,onClick:()=>{let n=e===`dark`?`light`:`dark`;t(n),document.documentElement.setAttribute(`data-theme`,n);try{localStorage.setItem(`fruitbat-theme`,n)}catch{}},"aria-pressed":e===`dark`,children:Q(`theme.toggle`)})}function Ee({paragraphs:e}){return $(`article`,{class:`article`,"aria-label":Q(`intake.sample_label`),children:e.map((e,t)=>$(`p`,{children:e},t))})}function De(e){let t=e.trim();return t===``?0:t.split(/\s+/).length}function Oe(){let[e,t]=Y(``),n=De(e);return $(`div`,{class:`paste-box`,children:[$(`label`,{class:`paste-label`,for:`paste-input`,children:Q(`intake.paste_placeholder`)}),$(`textarea`,{id:`paste-input`,class:`paste-textarea`,placeholder:Q(`intake.paste_placeholder`),value:e,onInput:e=>t(e.target.value)}),$(`p`,{class:`word-count`,"aria-live":`polite`,"data-word-count":n,children:Q(`intake.word_count`).replace(`{n}`,String(n))})]})}function ke(){let[t,n]=Y([]);return fe(()=>{let t=!1;return e(`/sample.txt`).then(e=>e.text()).then(e=>{t||n(e.split(/\n{2,}/).map(e=>e.trim()).filter(Boolean))}).catch(()=>{t||n([])}),()=>{t=!0}},[]),t}function Ae(){let[e,t]=Y(Se),n=ke();return fe(()=>{document.title=Q(`app.title`)},[]),$(`div`,{class:`app-shell`,children:[$(`header`,{class:`app-header`,children:[$(`h1`,{class:`app-title`,children:Q(`app.title`)}),$(Ce,{level:e,onChange:t}),$(Te,{})]}),$(`main`,{class:`app-main`,children:[$(Ee,{paragraphs:n}),$(Oe,{})]}),$(`aside`,{id:`panel`,class:`panel`,"aria-label":Q(`a11y.panel_region`),children:$(`p`,{class:`panel-empty`,children:Q(`panel.empty`)})})]})}function je(){try{let e=localStorage.getItem(`fruitbat-theme`);(e===`dark`||e===`light`)&&document.documentElement.setAttribute(`data-theme`,e)}catch{}}var Me=0,Ne=null;window.__fruitbat={run(e,t){Me+=1,Ne={level:t,chars:e.length},window.dispatchEvent(new CustomEvent(`fruitbat:run`,{detail:{text:e,level:t}}))},stop(){window.dispatchEvent(new CustomEvent(`fruitbat:stop`))},stats(){return{runs:Me,last:Ne}}},je();var Pe=document.getElementById(`app`);Pe&&oe($(Ae,{}),Pe);
assets/net-Czt2kcl5.js ADDED
@@ -0,0 +1 @@
 
 
1
+ (function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e={$comment:`Every allowed outbound destination per target (docs/PLAN.md rule 1). Source for the privacy test (S1-12), the generated CSP connect-src (scripts/csp.mjs), NetworkPolicy.swift, and PRIVACY.md. web: S1-00b recorded the observed requests and redirects from a cold load of the dev Space on 2026-09-24 (plus curl -sI on the pinned file URLs); S0-03 added allowed_urls for every model tier, the same-origin prefixes, the CSP list, and the mac section (Hub placeholder for S2-03a, Polar x3, appcast fixed URL, release assets + objects.githubusercontent.com).`,version:1,web:{same_origin:{$comment:`The privacy test restricts same-origin requests to the Vite build manifest plus public/.`,paths_observed:[`/`,`/index.html`,`/coi-serviceworker.js`,`/assets/*`,`/ort/ort-wasm-simd-threaded.asyncify.mjs`,`/ort/ort-wasm-simd-threaded.asyncify.wasm`,`/models/kokoro-voices/af_heart.bin`,`/skeleton.html`,`/sample.txt`,`/fonts/AtkinsonHyperlegible-Regular.woff2`,`/fonts/AtkinsonHyperlegible-Bold.woff2`,`/fonts/AtkinsonHyperlegible-Italic.woff2`,`/fonts/AtkinsonHyperlegible-BoldItalic.woff2`],prefixes:[`/assets/`,`/ort/`,`/models/`,`/demo/`,`/coi-serviceworker.js`,`/`,`/index.html`,`/fonts/`,`/skeleton.html`,`/sample.txt`]},hub_files:{$comment:`Exact file URLs = url_template from spec/models.json with each model's pinned revision. GET only. No query string on the first request. allowed_urls (S0-03) is derived from spec/models.json for every tier (default, fallback-a, fallback-b, low-end, the CPU try-out files, the q8f16 voice variant); observed_2026_09_24 (S1-00b) is the subset the default configuration actually requested on the dev Space, and must stay a subset of allowed_urls. The privacy test asserts every Hub request URL is in allowed_urls and that the request count matches the chosen configuration.`,url_template:`https://huggingface.co/{id}/resolve/{revision}/{path}`,observed_2026_09_24:[`https://huggingface.co/onnx-community/Qwen3.5-0.8B-Text-ONNX/resolve/1e45daba048899e7f771657ada617ec49350aa91/config.json`,`https://huggingface.co/onnx-community/Qwen3.5-0.8B-Text-ONNX/resolve/1e45daba048899e7f771657ada617ec49350aa91/generation_config.json`,`https://huggingface.co/onnx-community/Qwen3.5-0.8B-Text-ONNX/resolve/1e45daba048899e7f771657ada617ec49350aa91/tokenizer.json`,`https://huggingface.co/onnx-community/Qwen3.5-0.8B-Text-ONNX/resolve/1e45daba048899e7f771657ada617ec49350aa91/tokenizer_config.json`,`https://huggingface.co/onnx-community/Qwen3.5-0.8B-Text-ONNX/resolve/1e45daba048899e7f771657ada617ec49350aa91/onnx/model_q4f16.onnx`,`https://huggingface.co/onnx-community/Qwen3.5-0.8B-Text-ONNX/resolve/1e45daba048899e7f771657ada617ec49350aa91/onnx/model_q4f16.onnx_data`,`https://huggingface.co/onnx-community/Kokoro-82M-v1.0-ONNX/resolve/1939ad2a8e416c0acfeecc08a694d14ef25f2231/config.json`,`https://huggingface.co/onnx-community/Kokoro-82M-v1.0-ONNX/resolve/1939ad2a8e416c0acfeecc08a694d14ef25f2231/tokenizer.json`,`https://huggingface.co/onnx-community/Kokoro-82M-v1.0-ONNX/resolve/1939ad2a8e416c0acfeecc08a694d14ef25f2231/tokenizer_config.json`,`https://huggingface.co/onnx-community/Kokoro-82M-v1.0-ONNX/resolve/1939ad2a8e416c0acfeecc08a694d14ef25f2231/onnx/model_quantized.onnx`],unpinned_seen_2026_09_24:[`https://huggingface.co/onnx-community/Qwen3.5-0.8B-Text-ONNX/resolve/main/tokenizer_config.json`,`https://huggingface.co/onnx-community/Kokoro-82M-v1.0-ONNX/resolve/main/tokenizer_config.json`],unpinned_note:`Transformers.js 4.3.0 fetched tokenizer_config.json at main once per model despite the revision option. S1-03a's loader must pin it; the privacy test must fail on any resolve/main/ URL.`,allowed_urls:`https://huggingface.co/onnx-community/Qwen3.5-0.8B-Text-ONNX/resolve/1e45daba048899e7f771657ada617ec49350aa91/config.json,https://huggingface.co/onnx-community/Qwen3.5-0.8B-Text-ONNX/resolve/1e45daba048899e7f771657ada617ec49350aa91/generation_config.json,https://huggingface.co/onnx-community/Qwen3.5-0.8B-Text-ONNX/resolve/1e45daba048899e7f771657ada617ec49350aa91/tokenizer.json,https://huggingface.co/onnx-community/Qwen3.5-0.8B-Text-ONNX/resolve/1e45daba048899e7f771657ada617ec49350aa91/tokenizer_config.json,https://huggingface.co/onnx-community/Qwen3.5-0.8B-Text-ONNX/resolve/1e45daba048899e7f771657ada617ec49350aa91/onnx/model_q4f16.onnx,https://huggingface.co/onnx-community/Qwen3.5-0.8B-Text-ONNX/resolve/1e45daba048899e7f771657ada617ec49350aa91/onnx/model_q4f16.onnx_data,https://huggingface.co/onnx-community/Qwen3.5-0.8B-Text-ONNX/resolve/1e45daba048899e7f771657ada617ec49350aa91/onnx/model_q4.onnx,https://huggingface.co/onnx-community/Qwen3.5-0.8B-Text-ONNX/resolve/1e45daba048899e7f771657ada617ec49350aa91/onnx/model_q4.onnx_data,https://huggingface.co/onnx-community/Qwen2.5-0.5B-Instruct/resolve/cc5cc01a65cc3ff17bdb73a7de33d879f62599b0/config.json,https://huggingface.co/onnx-community/Qwen2.5-0.5B-Instruct/resolve/cc5cc01a65cc3ff17bdb73a7de33d879f62599b0/generation_config.json,https://huggingface.co/onnx-community/Qwen2.5-0.5B-Instruct/resolve/cc5cc01a65cc3ff17bdb73a7de33d879f62599b0/tokenizer.json,https://huggingface.co/onnx-community/Qwen2.5-0.5B-Instruct/resolve/cc5cc01a65cc3ff17bdb73a7de33d879f62599b0/tokenizer_config.json,https://huggingface.co/onnx-community/Qwen2.5-0.5B-Instruct/resolve/cc5cc01a65cc3ff17bdb73a7de33d879f62599b0/onnx/model_q4f16.onnx,https://huggingface.co/onnx-community/Qwen3-0.6B-ONNX/resolve/da1453100cf3ff33ef56d17983fc7a8648706db6/config.json,https://huggingface.co/onnx-community/Qwen3-0.6B-ONNX/resolve/da1453100cf3ff33ef56d17983fc7a8648706db6/generation_config.json,https://huggingface.co/onnx-community/Qwen3-0.6B-ONNX/resolve/da1453100cf3ff33ef56d17983fc7a8648706db6/tokenizer.json,https://huggingface.co/onnx-community/Qwen3-0.6B-ONNX/resolve/da1453100cf3ff33ef56d17983fc7a8648706db6/tokenizer_config.json,https://huggingface.co/onnx-community/Qwen3-0.6B-ONNX/resolve/da1453100cf3ff33ef56d17983fc7a8648706db6/onnx/model_q4f16.onnx,https://huggingface.co/HuggingFaceTB/SmolLM2-360M-Instruct/resolve/a10cc1512eabd3dde888204e902eca88bddb4951/config.json,https://huggingface.co/HuggingFaceTB/SmolLM2-360M-Instruct/resolve/a10cc1512eabd3dde888204e902eca88bddb4951/generation_config.json,https://huggingface.co/HuggingFaceTB/SmolLM2-360M-Instruct/resolve/a10cc1512eabd3dde888204e902eca88bddb4951/tokenizer.json,https://huggingface.co/HuggingFaceTB/SmolLM2-360M-Instruct/resolve/a10cc1512eabd3dde888204e902eca88bddb4951/tokenizer_config.json,https://huggingface.co/HuggingFaceTB/SmolLM2-360M-Instruct/resolve/a10cc1512eabd3dde888204e902eca88bddb4951/onnx/model_q4f16.onnx,https://huggingface.co/onnx-community/Kokoro-82M-v1.0-ONNX/resolve/1939ad2a8e416c0acfeecc08a694d14ef25f2231/config.json,https://huggingface.co/onnx-community/Kokoro-82M-v1.0-ONNX/resolve/1939ad2a8e416c0acfeecc08a694d14ef25f2231/tokenizer.json,https://huggingface.co/onnx-community/Kokoro-82M-v1.0-ONNX/resolve/1939ad2a8e416c0acfeecc08a694d14ef25f2231/tokenizer_config.json,https://huggingface.co/onnx-community/Kokoro-82M-v1.0-ONNX/resolve/1939ad2a8e416c0acfeecc08a694d14ef25f2231/onnx/model_quantized.onnx,https://huggingface.co/onnx-community/Kokoro-82M-v1.0-ONNX/resolve/1939ad2a8e416c0acfeecc08a694d14ef25f2231/onnx/model_q8f16.onnx`.split(`,`)},redirect_hosts:[`us.aws.cdn.hf.co`,`huggingface.co`],redirect_host_patterns:[`*.cdn.hf.co`],redirects_observed:{lfs:`https://huggingface.co/{id}/resolve/{revision}/{path} -> 302 -> https://us.aws.cdn.hf.co/xet-bridge-us/{hash}/{hash}?{signed params} -> 200`,small_json:`https://huggingface.co/{id}/resolve/{revision}/{path} -> 307 -> https://huggingface.co/api/resolve-cache/models/{id}/{revision}/{path}?{encoded path}=&etag={etag} -> 200`,how_checked:`curl -sI on 2026-09-24; the coi-serviceworker hides these hops from page-level Playwright capture`},redirect_query_params:{"us.aws.cdn.hf.co":[`user_id`,`X-Xet-Cas-Uid`,`response-content-disposition`,`Expires`,`Policy`,`Signature`,`Key-Pair-Id`,`Hash-Algorithm`,`response-content-type`,`xip`],"huggingface.co":[`etag`,`<url-encoded original path as the parameter name>`],$comment:"Keyed by host. A host that matches a redirect_host_pattern uses the parameters recorded for any listed host under the same pattern (region prefixes vary). S1-03a added response-content-type: the Hub sends it on small LFS files such as tokenizer.json (curl -sI 2026-09-24). 2026-09-25: the CDN began adding `xip`; without it every real-network model load was refused by net.ts. Redirect parameter names drift; the weekly health check should diff the observed names against this list."},methods:[`GET`],everything_else:`denied`,csp_connect_src:[`'self'`,`https://huggingface.co`,`https://us.aws.cdn.hf.co`,`https://*.cdn.hf.co`],$comment_csp:`scripts/csp.mjs (S1-12) generates <meta http-equiv=Content-Security-Policy> connect-src from this list. The CDN entries come from S1-00b's observed redirects; a new redirect host observed later is added here, never guessed.`},mac:{methods:[`GET`,`POST`],hub:{$comment:`Exact file URLs added in S2-03a from models.json.mac.`,allowed_urls:[],redirect_hosts:[]},polar:{$comment:`Stage 2b, deferred (docs/PLAN.md Q2). validate at most weekly; nag, never lock.`,allowed_urls:[`https://api.polar.sh/v1/customer-portal/license-keys/activate`,`https://api.polar.sh/v1/customer-portal/license-keys/validate`,`https://api.polar.sh/v1/customer-portal/license-keys/deactivate`]},updates:{$comment:`Sparkle 2. Fixed appcast URL (rule 10, C13); release assets redirect to objects.githubusercontent.com.`,appcast:`https://aj-prabhu.github.io/fruitbat/appcast.xml`,release_assets_prefix:`https://github.com/aj-prabhu/fruitbat/releases/download/`,redirect_hosts:[`objects.githubusercontent.com`]},bug_report:{$comment:`Opened in the user's browser, never by the app: a prefilled GitHub issue form URL.`,prefix:`https://github.com/aj-prabhu/fruitbat/issues/new`}}},t={$comment:`Pinned models, voices, and inference libraries per target (docs/PLAN.md rule 4). Every file URL is exact (url_template filled with id, revision, path); spec/network.json is generated from this list and the privacy test allows nothing else. S1-00a pinned the web runtime and the two default models it proved; S0-03 added the fallback tiers, the WebGPU voice variant, and licenses. Licenses: the onnx-community conversion cards carry no license field; the value recorded is the base model's license from its card (checked 2026-09-23 via the Hub API).`,version:1,web:{libraries:{"@huggingface/transformers":`4.3.0`,"onnxruntime-web":`1.31.0-dev.20260914-8d85527a0`,phonemizer:`1.2.1`,"kokoro-js":`1.2.1 (vendored loader in web/src/vendor/kokoro, Apache-2.0; npm package pins Transformers.js 3.x)`},summarizer:{role:`default`,id:`onnx-community/Qwen3.5-0.8B-Text-ONNX`,revision:`1e45daba048899e7f771657ada617ec49350aa91`,dtype:`q4f16`,device:`webgpu`,license:`apache-2.0 (base model Qwen/Qwen3.5-0.8B; the onnx-community card has no license field)`,files:[{path:`config.json`,bytes:1989},{path:`generation_config.json`,bytes:120},{path:`tokenizer.json`,bytes:19226111},{path:`tokenizer_config.json`,bytes:9119},{path:`onnx/model_q4f16.onnx`,bytes:597442},{path:`onnx/model_q4f16.onnx_data`,bytes:469331968}],url_template:`https://huggingface.co/{id}/resolve/{revision}/{path}`,cpu_tryout:{$comment:`spec/tools/try-prompts.mjs uses model_q4 on CPU (q4f16 has no CPU kernels).`,dtype:`q4`,files:[{path:`onnx/model_q4.onnx`,bytes:482783},{path:`onnx/model_q4.onnx_data`,bytes:550764544}]},cold_budget_with_voice_mb:562},voice:{id:`onnx-community/Kokoro-82M-v1.0-ONNX`,revision:`1939ad2a8e416c0acfeecc08a694d14ef25f2231`,dtype:`q8`,device:`wasm`,license:`apache-2.0 (card and base model hexgrad/Kokoro-82M)`,files:[{path:`config.json`,bytes:44},{path:`tokenizer.json`,bytes:3497},{path:`tokenizer_config.json`,bytes:113},{path:`onnx/model_quantized.onnx`,bytes:92361116}],url_template:`https://huggingface.co/{id}/resolve/{revision}/{path}`,voices_vendored:{path:`web/public/models/kokoro-voices/`,revision:`1939ad2a8e416c0acfeecc08a694d14ef25f2231`,files:[`af_heart.bin`],bytes_each:522240,planned:[`af_bella.bin (second voice for 9/29, S1-04)`]},tts_phoneme_limit:510,tts_phoneme_target:300,variants:{q8f16:{$comment:`WebGPU voice tried in the S1-05 bake-off (Fable pass); not the default.`,path:`onnx/model_q8f16.onnx`,bytes:86033585,device:`webgpu`}}},runtime_assets_same_origin:{path:`web/public/ort/`,from:`node_modules/onnxruntime-web/dist/ort-wasm-simd-threaded*.{mjs,wasm}`,why:`Transformers.js otherwise loads the WASM runtime from a CDN, which rule 1 forbids`},summarizer_fallbacks:[{role:`fallback-a`,id:`onnx-community/Qwen2.5-0.5B-Instruct`,revision:`cc5cc01a65cc3ff17bdb73a7de33d879f62599b0`,dtype:`q4f16`,device:`webgpu`,license:`apache-2.0 (base model Qwen/Qwen2.5-0.5B-Instruct)`,cold_budget_with_voice_mb:575,files:[{path:`config.json`,bytes:678},{path:`generation_config.json`,bytes:242},{path:`tokenizer.json`,bytes:7031673},{path:`tokenizer_config.json`,bytes:7306},{path:`onnx/model_q4f16.onnx`,bytes:483003582}],url_template:`https://huggingface.co/{id}/resolve/{revision}/{path}`},{role:`fallback-b`,id:`onnx-community/Qwen3-0.6B-ONNX`,revision:`da1453100cf3ff33ef56d17983fc7a8648706db6`,dtype:`q4f16`,device:`webgpu`,license:`apache-2.0 (base model Qwen/Qwen3-0.6B)`,cold_budget_with_voice_mb:662,files:[{path:`config.json`,bytes:912},{path:`generation_config.json`,bytes:219},{path:`tokenizer.json`,bytes:9117040},{path:`tokenizer_config.json`,bytes:9705},{path:`onnx/model_q4f16.onnx`,bytes:569789750}],url_template:`https://huggingface.co/{id}/resolve/{revision}/{path}`},{role:`low-end`,id:`HuggingFaceTB/SmolLM2-360M-Instruct`,revision:`a10cc1512eabd3dde888204e902eca88bddb4951`,dtype:`q4f16`,device:`webgpu`,license:`apache-2.0`,cold_budget_with_voice_mb:365,files:[{path:`config.json`,bytes:846},{path:`generation_config.json`,bytes:132},{path:`tokenizer.json`,bytes:2104556},{path:`tokenizer_config.json`,bytes:3764},{path:`onnx/model_q4f16.onnx`,bytes:272737275}],url_template:`https://huggingface.co/{id}/resolve/{revision}/{path}`}],cold_budget_mb:700},mac:{$comment:`Pinned in S2-03a (mlx-community Qwen3.5-2B-4bit or Qwen3-1.7B-4bit; mlx-community/Kokoro-82M-bf16; G2P assets inventory).`,libraries:{},summarizer:null,voice:null}};function n(){return t}function r(e,t){return e.url_template.replace(`{id}`,e.id).replace(`{revision}`,e.revision).replace(`{path}`,t)}function i(){let{summarizer:e,voice:t}=n().web;return[...e.files.map(t=>r(e,t.path)),...t.files.map(e=>r(t,e.path))]}var a=class extends Error{reason;url;constructor(e,t){super(`network policy: ${e}`),this.reason=e,this.url=t,this.name=`NetworkPolicyError`}};function o(){return e.web??{}}var s={allowed:0,rejected:0,redirect_rejected:0},c=null;function l(){if(!c){let e=[];for(let[t,n]of Object.entries(o().hub_files??{}))t.startsWith(`observed`)&&Array.isArray(n)&&e.push(...n);c=new Set([...i(),...e])}return c}function u(e){let t=o();if((t.redirect_hosts??[]).includes(e))return!0;for(let n of t.redirect_host_patterns??[])if(n.startsWith(`*.`)&&e.endsWith(n.slice(1))&&e.length>n.length-1)return!0;return!1}function d(e){for(let t of o().redirect_host_patterns??[])if(t.startsWith(`*.`)&&e.endsWith(t.slice(1))&&e.length>t.length-1)return t;return null}function f(e){let t=o().redirect_query_params??{};if(Array.isArray(t[e]))return new Set(t[e]);let n=d(e),r=new Set;if(n)for(let[e,i]of Object.entries(t))Array.isArray(i)&&d(e)===n&&i.forEach(e=>r.add(e));return r}function p(e){return e.slice(e.lastIndexOf(`/`)+1)}function m(e){if(!u(e.host))return{ok:!1,reason:`host not in redirect_hosts`};let t=f(e.host),n=[...l()].map(e=>new URL(e).pathname),r=null;for(let t of n){let n=t.match(/^\/(.+)\/resolve\/([0-9a-f]{40})\/(.+)$/);if(!n)continue;let i=`/api/resolve-cache/models/${n[1]}/${n[2]}/${n[3]}`;e.pathname===i&&(r=t)}let i=e.searchParams.get(`response-content-disposition`),a=/^\/xet-bridge-[a-z0-9-]+\/[0-9a-f]{8,64}\/[0-9a-f]{8,64}$/.test(e.pathname);if(!r&&i&&a){let e=/filename\*?=(?:UTF-8'')?"?([^";]+)"?/i.exec(i)?.[1];if(e){let t=n.find(t=>p(t)===decodeURIComponent(e));t&&(r=t)}}if(!r)return{ok:!1,reason:`redirect target is not a pinned file`};for(let n of e.searchParams.keys())if(!t.has(n)&&decodeURIComponent(n)!==r)return{ok:!1,reason:`redirect query parameter not recorded`};return{ok:!0}}var h=new Set([`/sample.txt`]),g=[`/models/`,`/demo/`,`/assets/`,`/ort/`,`/fonts/`,`/__model_cache__/`];function _(e){return e.includes(`..`)?!1:h.has(e)||g.some(t=>e.startsWith(t))}function v(e,t){let n;try{n=new URL(e,t??(typeof location<`u`?location.origin:void 0))}catch{return{ok:!1,reason:`unparseable url`,url:null}}if(n.protocol!==`https:`&&n.protocol!==`http:`)return{ok:!1,reason:`scheme`,url:n};let r=typeof location<`u`?location.origin:null;if(r&&n.origin===r)return n.search?{ok:!1,reason:`query string on same-origin path`,url:n}:_(n.pathname)?{ok:!0,kind:`same-origin`,url:n}:{ok:!1,reason:`same-origin path not a shipped asset`,url:n};if(/\/resolve\/main\//.test(n.pathname))return{ok:!1,reason:`unpinned revision`,url:n};if(l().has(n.href)||n.search===``&&l().has(n.origin+n.pathname))return{ok:!0,kind:`exact`,url:n};let i=m(n);return i.ok?{ok:!0,kind:`redirect`,url:n}:{ok:!1,reason:i.reason??`not allowed`,url:n}}async function y(e,t){let n=v(e);if(!n.ok)throw s.rejected++,new a(n.reason,n.url?n.url.origin+n.url.pathname:`invalid`);if(t?.method&&t.method.toUpperCase()!==`GET`)throw s.rejected++,new a(`only GET`,n.url.origin+n.url.pathname);s.allowed++;let r=await fetch(n.url,{...t,method:`GET`,credentials:`omit`,referrerPolicy:`no-referrer`}),i=r.headers.get(`x-fruitbat-final-url`)||r.url||``;if(i&&i!==n.url.href){let e=v(i);if(!e.ok||e.kind!==`redirect`&&e.kind!==`same-origin`&&e.kind!==`exact`)throw s.redirect_rejected++,new a(`redirected off-list: ${e.ok?e.kind:e.reason}`,new URL(i).origin)}return r}var b=`/models/kokoro-voices/`,x=/^[a-z]{2}_[a-z]+$/;async function S(e){if(!x.test(e))throw Error(`bad voice id`);let t=await y(`${b}${e}.bin`);if(!t.ok)throw Error(`voice_http_${t.status}`);return new Float32Array(await t.arrayBuffer())}export{S as n,n as r,y as t};
assets/{index-Dx8oMn_o.js → skeleton-BVmU5cs7.js} RENAMED
The diff for this file is too large to render. See raw diff
 
fonts/AtkinsonHyperlegible-Bold.woff2 ADDED
Binary file (23.8 kB). View file
 
fonts/AtkinsonHyperlegible-BoldItalic.woff2 ADDED
Binary file (25.2 kB). View file
 
fonts/AtkinsonHyperlegible-Italic.woff2 ADDED
Binary file (24.9 kB). View file
 
fonts/AtkinsonHyperlegible-Regular.woff2 ADDED
Binary file (23.2 kB). View file
 
fonts/LICENSE ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright 2020 Braille Institute of America, Inc.
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ http://scripts.sil.org/OFL
6
+
7
+ -----------------------------------------------------------
8
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
9
+ -----------------------------------------------------------
10
+
11
+ PREAMBLE
12
+ The goals of the Open Font License (OFL) are to stimulate worldwide
13
+ development of collaborative font projects, to support the font creation
14
+ efforts of academic and linguistic communities, and to provide a free and
15
+ open framework in which fonts may be shared and improved in partnership
16
+ with others.
17
+
18
+ The OFL allows the licensed fonts to be used, studied, modified and
19
+ redistributed freely as long as they are not sold by themselves. The
20
+ fonts, including any derivative works, can be bundled, embedded,
21
+ redistributed and/or sold with any software provided that any reserved
22
+ names are not used by derivative works. The fonts and derivatives,
23
+ however, cannot be released under any other type of license. The
24
+ requirement for fonts to remain under this license does not apply
25
+ to any document created using the fonts or their derivatives.
26
+
27
+ DEFINITIONS
28
+ "Font Software" refers to the set of files released by the Copyright
29
+ Holder(s) under this license and clearly marked as such. This may
30
+ include source files, build scripts and documentation.
31
+
32
+ "Reserved Font Name" refers to any names specified as such after the
33
+ copyright statement(s).
34
+
35
+ "Original Version" refers to the collection of Font Software components as
36
+ distributed by the Copyright Holder(s).
37
+
38
+ "Modified Version" refers to any derivative made by adding to, deleting,
39
+ or substituting -- in part or in whole -- any of the components of the
40
+ Original Version, by changing formats or by porting the Font Software to a
41
+ new environment.
42
+
43
+ "Author" refers to any designer, engineer, programmer, technical
44
+ writer or other person who contributed to the Font Software.
45
+
46
+ PERMISSION & CONDITIONS
47
+ Permission is hereby granted, free of charge, to any person obtaining
48
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
49
+ redistribute, and sell modified and unmodified copies of the Font
50
+ Software, subject to the following conditions:
51
+
52
+ 1) Neither the Font Software nor any of its individual components,
53
+ in Original or Modified Versions, may be sold by itself.
54
+
55
+ 2) Original or Modified Versions of the Font Software may be bundled,
56
+ redistributed and/or sold with any software, provided that each copy
57
+ contains the above copyright notice and this license. These can be
58
+ included either as stand-alone text files, human-readable headers or
59
+ in the appropriate machine-readable metadata fields within text or
60
+ binary files as long as those fields can be easily viewed by the user.
61
+
62
+ 3) No Modified Version of the Font Software may use the Reserved Font
63
+ Name(s) unless explicit written permission is granted by the corresponding
64
+ Copyright Holder. This restriction only applies to the primary font name as
65
+ presented to the users.
66
+
67
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
68
+ Software shall not be used to promote, endorse or advertise any
69
+ Modified Version, except to acknowledge the contribution(s) of the
70
+ Copyright Holder(s) and the Author(s) or with their explicit written
71
+ permission.
72
+
73
+ 5) The Font Software, modified or unmodified, in part or in whole,
74
+ must be distributed entirely under this license, and must not be
75
+ distributed under any other license. The requirement for fonts to
76
+ remain under this license does not apply to any document created
77
+ using the Font Software.
78
+
79
+ TERMINATION
80
+ This license becomes null and void if any of the above conditions are
81
+ not met.
82
+
83
+ DISCLAIMER
84
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
85
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
86
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
87
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
88
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
89
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
90
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
91
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
92
+ OTHER DEALINGS IN THE FONT SOFTWARE.
index.html CHANGED
@@ -3,21 +3,14 @@
3
  <head>
4
  <meta charset="utf-8" />
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>Fruitbat walking skeleton</title>
7
  <!-- Cross-origin isolation on a static host: the service worker adds COOP/COEP (S1-00a). -->
8
  <script src="/coi-serviceworker.js"></script>
9
- <script type="module" crossorigin src="/assets/index-Dx8oMn_o.js"></script>
 
 
10
  </head>
11
  <body>
12
- <h1>Fruitbat, walking skeleton (S1-00a)</h1>
13
- <p>No styling on purpose. Real text in, real bullets out, spoken. Nothing you type leaves this page.</p>
14
- <p id="status">starting</p>
15
- <textarea id="text" rows="12" cols="90" placeholder="Paste text here"></textarea>
16
- <p>
17
- <button id="go" type="button">Summarize (downloads about 560 MB of models on first use)</button>
18
- <button id="stop" type="button">Stop</button>
19
- </p>
20
- <ul id="bullets"></ul>
21
- <pre id="raw"></pre>
22
  </body>
23
  </html>
 
3
  <head>
4
  <meta charset="utf-8" />
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>Fruitbat</title>
7
  <!-- Cross-origin isolation on a static host: the service worker adds COOP/COEP (S1-00a). -->
8
  <script src="/coi-serviceworker.js"></script>
9
+ <script type="module" crossorigin src="/assets/index-DJY3KawE.js"></script>
10
+ <link rel="modulepreload" crossorigin href="/assets/net-Czt2kcl5.js">
11
+ <link rel="stylesheet" crossorigin href="/assets/index-BbVBwNLj.css">
12
  </head>
13
  <body>
14
+ <div id="app"></div>
 
 
 
 
 
 
 
 
 
15
  </body>
16
  </html>
sample.txt ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The most famous of the park's mammals are the bats. The park hosts 17 different bat species. The large colony of Brazilian free-tailed bats wow visitors every evening from spring through fall with its spectacular outflights. Two other species have also been found regularly in Carlsbad Cavern—cave myotis and fringed myotis bats. They typically roost in a different part of the cavern and fly about 1.5 miles (2.4 km) before exiting the Natural Entrance.
2
+
3
+ But not all bat species roost in caves. Among the other species using the park are eastern red bats and hoary bats, which roost in trees, and parastrellus hesperus or canyon bats, which roost on rock cliffs and in cracks. Bats are mammals, which means that they give live birth to their young (do not lay eggs), are warm-blooded, have fur (not feathers), and baby bats or pups are fed breast milk (not insects) by their mothers. Bats are the only true flying mammals. All the bats in the area around Carlsbad Caverns National Park are insectivores. The Brazilian free-tailed bats weigh about 1/2 ounce (13 g), which is equivalent to the weight of three nickel coins. Their wingspan is approximately 11 inches (28 cm). Bat numbers in the Cavern are variable. The resident colony was around 400,000 in summer of 2005. During the spring and fall migration, the bat numbers in the cavern were documented as high as 793,000 in 2005. There are seasonal fluctuations of the numbers, as well as daily fluctuations. Researchers from Boston University have been assisting the park in getting accurate population estimates. They use advanced thermal infrared imaging cameras coupled with a custom-written visual recognition software program to count the bats. At Carlsbad Cavern, the resident colony should not be called the maternity colony because it is typically greater than 50% male. The males and females roost mix together in the same site. In many sites outside of the park, the really large Brazilian free-tailed bat colonies are almost exclusively female and the males roost separately in smaller groups. The health and well-being of bat colonies all over the United States is threatened by a deadly fungus affecting bats called White-nose Syndrome (WNS). WNS has already taken the lives of an estimated 7+ million bats in the United States and expected to spread wider than it is today. The bats that call the cavern home in the summertime have not been affected by this fatal fungus, and we do everything we can to keep it that way. We will ask you questions when you arrive to ensure you do not bring the fungus with you from another cave. Although this fungus is not harmful to humans, it can spread quickly through a bat colony with disasterous results. Learn more about White-nose Syndrome.
4
+
5
+ Benefits of Bats
6
+
7
+ Sure, it's interesting that bats navigate by echolocation and that they're nocturnal. But do they really matter? The short answer is "Yes!" These flying mammals bring many benefits to their ecosystems. More than 50 unique species of bats live in national parks, and different species provide different benefits. Some pollinate plants, others eat insects, many serve as prey to other animals, and they all inspire scientific discoveries.
8
+
9
+ Some Bats are Pollinators
10
+
11
+ Several species of bats in tropical and subtropical areas of the Americas eat nectar. Many types of plants in these regions rely on bats for pollination and seed dispersal, such as the blue agave. In some southwestern parks, long-nose and long-tongue bats are perfectly adapted to pollinate these plants, and they provide extensive value to the agricultural industry. So next time you sweeten your coffee with agave nectar, remember to thank a bat.
12
+
13
+ Bat Guano Supports Cave Communities
14
+
15
+ Caves are complex and unique ecosystems that provide homes for a diversity of creatures from insects to amphibians and fish as well as mammals like wood rats and bats. Many of these creatures can only survive within the cave, and they rely on nutrients carried into the cave by water or other animals. Bats benefit caves by providing important nutrients in their guano (better fertilizer than cow manure!) that support the growth of communities of cave organisms.
16
+
17
+ Some Bats Provide Insect Control
18
+
19
+ Bats that eat insects are called "insectivorous." They feast on insects each night, adding up to more than $3.7 billion worth of pest control each year in the U.S. When bats are around to eat insects, there are fewer insect pests causing damage to crops, and farmers don't have to invest as much in pesticides. Bats can eat 50% or more of their bodyweight in insects each night. Imagine eating 200 quarter-pound burgers—that's how much a bat eats in insects in one night!
20
+
21
+ Bats Are Also Prey
22
+
23
+ Just as some bats rely on thousands of insects each night for survival, other animals in the ecosystem rely on bats for their calories. Hawks, falcons, and owls eat bats, and mammals like weasels, ringtail cats, and raccoons sometimes attack bats while they roost.
24
+
25
+ Fruit-Eating Bats Disperse Seeds
26
+
27
+ Fruit-eating bats play important roles in distributing seeds to maintain plants and forests. These species of bats, often called "flying foxes" because of their larger body size and big eyes, live in tropical and subtropical areas of the Old World (Africa, Asia and Australia). Fruit-eating bats are also found in some Pacific islands, Latin America, and the Caribbean and live in national parks in Guam, American Samoa, and the Virgin Islands!
28
+
29
+ Bats Provide Inspiration
30
+
31
+ Some of bats' unique features like membrane wings and echolocation have inspired technological advances in engineering. Drones that have thin and flexible bat-like wings are are in the works as well as tiny, more efficient sonar systems for navigation. The wingsuits used by basejumpers take more than a few cues from bats' aerodynamic bodies.
32
+
33
+ White-nose Syndrome
34
+
35
+ White-nose syndrome (WNS) is a fatal disease of hibernating bats caused by the fungus Pseudogymnoascus destructans (Pd for short). The fungus infects bats while they are hibernating over winter. Researchers first discovered the disease in New York in the winter of 2006. Since then, it has spread across much of the United States and Canada, killing millions of bats—up to 99% of some bat colonies. The National Park Service works with many other state and federal agencies, tribes, universities, and conservation organizations who are part of the White-nose Syndrome Response Team to learn more about the fatal disease and how to reduce impacts to bats.
36
+
37
+ Help Bats
38
+
39
+ We need bats if we want healthy and diverse ecosystems filled with a variety of organisms. Many bats feast on insects, some pollinate plants, and some bats spread seeds, too. Larger animals may depend on bats for prey. Aside from all these great services, bats are the only mammal that's capable of true flight, and they're simply fascinating. The deadly fungal disease, white-nose syndrome (WNS), poses a real danger to cave-dwelling bats. WNS has killed 99% of some bat colonies. Tree-roosting and migratory bats face significant threats from wind turbines. Habitat loss and climate change also make it difficult for bats to survive and thrive. But we can all help protect bats and their habitats! Try some of these ideas to help conserve bats. You can help bats in your own yard and community, and you can learn how to protect bats when you visit parks, too.
40
+
41
+ Stay out of caves when directed. The bats at risk for WNS often hibernate or raise young in caves. They need to be undisturbed so they can rest and raise their young.
42
+
43
+ Decontaminate before going in a cave. It may be possible for humans to spread WNS from one cave into another. If you have visited another cave, make sure to decontaminate (or leave behind) your shoes, clothes, and gear before entering another cave.
44
+
45
+ Leave bats alone. If you see a bat, do not disturb it.
46
+
47
+ Tell a ranger if you see bats acting strangely. Rangers can take steps to protect both bats and people if a bat is behaving in an unusual way.
skeleton.html ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>Fruitbat walking skeleton</title>
7
+ <!-- Cross-origin isolation on a static host: the service worker adds COOP/COEP (S1-00a). -->
8
+ <script src="/coi-serviceworker.js"></script>
9
+ <script type="module" crossorigin src="/assets/skeleton-BVmU5cs7.js"></script>
10
+ <link rel="modulepreload" crossorigin href="/assets/net-Czt2kcl5.js">
11
+ </head>
12
+ <body>
13
+ <h1>Fruitbat, walking skeleton (S1-00a)</h1>
14
+ <p>No styling on purpose. Real text in, real bullets out, spoken. Nothing you type leaves this page.</p>
15
+ <p id="status">starting</p>
16
+ <textarea id="text" rows="12" cols="90" placeholder="Paste text here"></textarea>
17
+ <p>
18
+ <button id="go" type="button">Summarize (downloads about 560 MB of models on first use)</button>
19
+ <button id="stop" type="button">Stop</button>
20
+ </p>
21
+ <ul id="bullets"></ul>
22
+ <pre id="raw"></pre>
23
+ </body>
24
+ </html>