@blkc-code/render-canvas 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/draw.d.ts +16 -0
- package/dist/draw.d.ts.map +1 -0
- package/dist/draw.js +427 -0
- package/dist/draw.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/office.d.ts +18 -0
- package/dist/office.d.ts.map +1 -0
- package/dist/office.js +119 -0
- package/dist/office.js.map +1 -0
- package/dist/runtime.d.ts +2 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +11 -0
- package/dist/runtime.js.map +1 -0
- package/dist/runtime.txt +11 -0
- package/dist/types.d.ts +49 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/world.d.ts +117 -0
- package/dist/world.d.ts.map +1 -0
- package/dist/world.js +322 -0
- package/dist/world.js.map +1 -0
- package/package.json +43 -4
- package/src/draw.ts +429 -0
- package/src/index.ts +73 -0
- package/src/office.ts +137 -0
- package/src/runtime.ts +8 -0
- package/src/types.ts +33 -0
- package/src/world.ts +363 -0
- package/README.md +0 -3
package/dist/office.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/** Puts a world on a canvas: sizing, the frame loop, and pointer and keyboard input. */
|
|
2
|
+
import { drawWorld, TILE } from "./draw.js";
|
|
3
|
+
import { agentAt, applyUpdate, createWorld, step } from "./world.js";
|
|
4
|
+
const SAFE_COLOUR = /^(#[0-9a-f]{3,8}|rgba?\([\d\s.,%/]+\)|hsla?\([\d\s.,%/a-z]+\))$/i;
|
|
5
|
+
function readPalette(canvas) {
|
|
6
|
+
const styles = getComputedStyle(canvas);
|
|
7
|
+
const token = (name, fallback) => {
|
|
8
|
+
const value = styles.getPropertyValue(name).trim();
|
|
9
|
+
return SAFE_COLOUR.test(value) ? value : fallback;
|
|
10
|
+
};
|
|
11
|
+
return {
|
|
12
|
+
primary: token("--blkc-color-primary", "#3b82f6"),
|
|
13
|
+
accent: token("--blkc-color-accent", "#f59e0b"),
|
|
14
|
+
background: token("--blkc-color-background", "#1a1a2e"),
|
|
15
|
+
text: token("--blkc-color-text", "#ffffff"),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** Draw an office and keep it running until destroy(). */
|
|
19
|
+
export function createOffice(canvas, scene = {}, options = {}) {
|
|
20
|
+
const world = createWorld(scene);
|
|
21
|
+
const context = canvas.getContext("2d");
|
|
22
|
+
if (!context)
|
|
23
|
+
throw new Error("This browser can't draw to a canvas.");
|
|
24
|
+
const c = context;
|
|
25
|
+
const width = world.cols * TILE;
|
|
26
|
+
const height = world.rows * TILE;
|
|
27
|
+
const palette = readPalette(canvas);
|
|
28
|
+
const still = typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
29
|
+
let selected;
|
|
30
|
+
let scale = 0;
|
|
31
|
+
let time = 0;
|
|
32
|
+
let last = 0;
|
|
33
|
+
let frame = 0;
|
|
34
|
+
let visible = true;
|
|
35
|
+
let destroyed = false;
|
|
36
|
+
const paint = () => {
|
|
37
|
+
c.setTransform(scale, 0, 0, scale, 0, 0);
|
|
38
|
+
c.imageSmoothingEnabled = false;
|
|
39
|
+
drawWorld(c, world, time, palette, selected);
|
|
40
|
+
};
|
|
41
|
+
// The backing store is a whole multiple of the art, so every pixel stays square and text stays sharp.
|
|
42
|
+
const resize = () => {
|
|
43
|
+
const shown = canvas.getBoundingClientRect().width || width;
|
|
44
|
+
const ratio = typeof devicePixelRatio === "number" ? devicePixelRatio : 1;
|
|
45
|
+
const next = Math.max(1, Math.ceil((shown * ratio) / width));
|
|
46
|
+
if (next === scale)
|
|
47
|
+
return;
|
|
48
|
+
scale = next;
|
|
49
|
+
canvas.width = width * scale;
|
|
50
|
+
canvas.height = height * scale;
|
|
51
|
+
paint();
|
|
52
|
+
};
|
|
53
|
+
const loop = (now) => {
|
|
54
|
+
if (destroyed)
|
|
55
|
+
return;
|
|
56
|
+
frame = requestAnimationFrame(loop);
|
|
57
|
+
if (!visible) {
|
|
58
|
+
last = now;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const dt = Math.min((now - last) / 1000 || 0, 0.1); // a stalled tab mustn't teleport people
|
|
62
|
+
last = now;
|
|
63
|
+
time += dt;
|
|
64
|
+
step(world, dt);
|
|
65
|
+
paint();
|
|
66
|
+
};
|
|
67
|
+
const select = (id) => {
|
|
68
|
+
const next = id === selected ? undefined : id;
|
|
69
|
+
selected = next;
|
|
70
|
+
options.onSelect?.(selected);
|
|
71
|
+
if (still)
|
|
72
|
+
paint();
|
|
73
|
+
};
|
|
74
|
+
const pointerTile = (event) => {
|
|
75
|
+
const box = canvas.getBoundingClientRect();
|
|
76
|
+
return { x: ((event.clientX - box.left) / box.width) * world.cols, y: ((event.clientY - box.top) / box.height) * world.rows };
|
|
77
|
+
};
|
|
78
|
+
const onDown = (event) => {
|
|
79
|
+
const { x, y } = pointerTile(event);
|
|
80
|
+
select(agentAt(world, x, y)?.id);
|
|
81
|
+
};
|
|
82
|
+
const onMove = (event) => {
|
|
83
|
+
const { x, y } = pointerTile(event);
|
|
84
|
+
canvas.style.cursor = agentAt(world, x, y) ? "pointer" : "default";
|
|
85
|
+
};
|
|
86
|
+
canvas.addEventListener("pointerdown", onDown);
|
|
87
|
+
canvas.addEventListener("pointermove", onMove);
|
|
88
|
+
const resizer = typeof ResizeObserver === "function" ? new ResizeObserver(resize) : undefined;
|
|
89
|
+
resizer?.observe(canvas);
|
|
90
|
+
const viewer = typeof IntersectionObserver === "function"
|
|
91
|
+
? new IntersectionObserver((entries) => { visible = entries.some((entry) => entry.isIntersecting); })
|
|
92
|
+
: undefined;
|
|
93
|
+
viewer?.observe(canvas);
|
|
94
|
+
resize();
|
|
95
|
+
if (scale === 0) {
|
|
96
|
+
scale = 1;
|
|
97
|
+
paint();
|
|
98
|
+
}
|
|
99
|
+
if (!still)
|
|
100
|
+
frame = requestAnimationFrame(loop);
|
|
101
|
+
return {
|
|
102
|
+
world,
|
|
103
|
+
update(next) {
|
|
104
|
+
applyUpdate(world, next);
|
|
105
|
+
if (still)
|
|
106
|
+
paint();
|
|
107
|
+
},
|
|
108
|
+
select,
|
|
109
|
+
destroy() {
|
|
110
|
+
destroyed = true;
|
|
111
|
+
cancelAnimationFrame(frame);
|
|
112
|
+
resizer?.disconnect();
|
|
113
|
+
viewer?.disconnect();
|
|
114
|
+
canvas.removeEventListener("pointerdown", onDown);
|
|
115
|
+
canvas.removeEventListener("pointermove", onMove);
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=office.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"office.js","sourceRoot":"","sources":["../src/office.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":""}
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";(()=>{var E={desk:{w:3,h:2,spot:{x:1,y:2}},coffee:{w:2,h:1,spot:{x:0,y:1}},water:{w:1,h:1,spot:{x:0,y:1}},sofa:{w:3,h:1,spot:{x:1,y:1}},plant:{w:1,h:1},board:{w:4,h:1,spot:{x:1,y:1}},shelf:{w:2,h:1,spot:{x:0,y:1}},server:{w:1,h:1},table:{w:3,h:2,spot:{x:1,y:2}},rug:{w:4,h:3,solid:!1}},ct=["working","thinking","blocked","reviewing","idle","done","away"],ut=["todo","doing","done"],dt=["wood","carpet","tile"],C={cols:26,rows:17,rooms:[{id:"studio",name:"Studio",x:1,y:3,w:15,h:13,floor:"wood"},{id:"lounge",name:"Lounge",x:17,y:3,w:8,h:6,floor:"carpet"},{id:"quests",name:"Quests",x:17,y:10,w:8,h:6,floor:"tile"}],doors:[{x:16,y:6},{x:16,y:13},{x:23,y:9}],furniture:[{type:"desk",x:2,y:4},{type:"desk",x:7,y:4},{type:"desk",x:12,y:4},{type:"desk",x:2,y:10},{type:"desk",x:7,y:10},{type:"desk",x:12,y:10},{type:"plant",x:1,y:8},{type:"plant",x:15,y:8},{type:"server",x:15,y:15},{type:"server",x:14,y:15},{type:"shelf",x:1,y:15},{type:"coffee",x:19,y:3},{type:"water",x:21,y:3},{type:"sofa",x:22,y:3},{type:"rug",x:20,y:5},{type:"plant",x:24,y:8},{type:"board",x:19,y:10},{type:"table",x:19,y:13},{type:"plant",x:24,y:15}]},A=(t,e)=>typeof t=="number"&&Number.isFinite(t)?Math.floor(t):e,w=(t,e=120)=>typeof t=="string"?t.slice(0,e):"",S=(t,e)=>Array.isArray(t)?t.slice(0,e):[];function V(t){let e=2166136261;for(let n=0;n<t.length;n++)e=Math.imul(e^t.charCodeAt(n),16777619);return e>>>0}var Y=["#2b1b12","#5a3a22","#a8622d","#d9b36c","#20242e","#7d2f3f","#4a5568","#e5e7eb"],Q=["#f4d3b5","#e8b98f","#c98d62","#9c6644","#6f4530","#4e2f20"],J=["#3b82f6","#ef4444","#10b981","#f59e0b","#8b5cf6","#ec4899","#14b8a6","#f97316"],_=(t,e)=>typeof t=="string"&&/^#[0-9a-f]{3,8}$/i.test(t)?t:e,F=(t,e,n)=>n*t.cols+e;function R(t,e,n){return e>=0&&n>=0&&e<t.cols&&n<t.rows&&t.walkable[F(t,e,n)]===!0}function Z(t,e,n){if(!R(t,n.x,n.y))return null;if(e.x===n.x&&e.y===n.y)return[];let i=new Int32Array(t.cols*t.rows).fill(-1),r=F(t,e.x,e.y);i[r]=r;let s=[r];for(let o=0;o<s.length;o++){let a=s[o],u=a%t.cols,l=Math.floor(a/t.cols);if(u===n.x&&l===n.y){let h=[];for(let p=a;p!==r;p=i[p])h.unshift({x:p%t.cols,y:Math.floor(p/t.cols)});return h}for(let[h,p]of[[0,1],[0,-1],[1,0],[-1,0]]){let x=u+h,k=l+p;if(!R(t,x,k))continue;let M=F(t,x,k);i[M]===-1&&(i[M]=a,s.push(M))}}return null}function tt(t,e){let n=w(t?.id,60)||`agent-${e+1}`,i=V(n),r=ct.includes(t?.state)?t.state:"idle";return{id:n,name:w(t?.name,24)||n,role:w(t?.role,40),state:r,task:w(t?.task,120),hair:_(t?.hair,Y[i%Y.length]),skin:_(t?.skin,Q[(i>>>4)%Q.length]),shirt:_(t?.shirt,J[(i>>>8)%J.length]),x:0,y:0,path:[],facing:"down",walking:!1,rest:0,seed:i}}function et(t){return{title:w(t?.title,80),state:ut.includes(t?.state)?t.state:"todo",agent:w(t?.agent,60)}}function B(t={}){let e=Array.isArray(t?.rooms)&&t.rooms.length>0,n=Math.min(Math.max(A(t?.cols,e?20:C.cols),6),64),i=Math.min(Math.max(A(t?.rows,e?14:C.rows),6),40),r=e?S(t.rooms,40):C.rooms,s=e?S(t.doors,60):C.doors,o=Array.isArray(t?.furniture)?S(t.furniture,300):e?[]:C.furniture,a=r.map(c=>{let b=Math.min(Math.max(A(c?.x,0),0),n),y=Math.min(Math.max(A(c?.y,0),0),i);return{name:w(c?.name,24),x:b,y,w:Math.min(Math.max(A(c?.w,0),0),n-b),h:Math.min(Math.max(A(c?.h,0),0),i-y),floor:dt.includes(c?.floor)?c.floor:"wood"}}),u=new Array(n*i).fill(!1),l=(c,b,y)=>{c>=0&&b>=0&&c<n&&b<i&&(u[b*n+c]=y)};for(let c of a)for(let b=c.y;b<c.y+c.h;b++)for(let y=c.x;y<c.x+c.w;y++)l(y,b,!0);let h=s.map(c=>({x:A(c?.x,-1),y:A(c?.y,-1)})).filter(c=>c.x>=0&&c.y>=0);for(let c of h)l(c.x,c.y,!0);let p=o.filter(c=>c&&Object.hasOwn(E,c.type)).map(c=>({type:c.type,x:A(c.x,-99),y:A(c.y,-99)}));for(let c of p){let b=E[c.type];if(b.solid!==!1)for(let y=c.y;y<c.y+b.h;y++)for(let T=c.x;T<c.x+b.w;T++)l(T,y,!1)}let x={cols:n,rows:i,rooms:a,doors:h,furniture:p,walkable:u,agents:S(t?.agents,40).map(tt),tasks:S(t?.tasks,60).map(et),spots:{lounge:[],board:[]}},k=c=>{let b=E[c.type].spot;if(!b)return;let y={x:c.x+b.x,y:c.y+b.y};return R(x,y.x,y.y)?y:void 0},M=p.filter(c=>c.type==="desk").map(k).filter(c=>!!c);for(let c of p){let b=k(c);b&&((c.type==="coffee"||c.type==="sofa"||c.type==="water"||c.type==="shelf")&&x.spots.lounge.push(b),(c.type==="board"||c.type==="table")&&x.spots.board.push(b))}return x.agents.forEach((c,b)=>{c.seat=M[b],nt(x,c)}),x}function ht(t){for(let e=0;e<t.rows;e++)for(let n=0;n<t.cols;n++)if(R(t,n,e))return{x:n,y:e};return{x:0,y:0}}function I(t,e){let n=i=>i.length>0?i[(e.seed+Math.floor(e.rest*1e3))%i.length]:void 0;switch(e.state){case"working":case"thinking":case"blocked":return e.seat??n(t.spots.lounge);case"reviewing":return n(t.spots.board)??e.seat;case"idle":case"done":return n(t.spots.lounge)??e.seat;default:return}}function nt(t,e){let n=I(t,e)??e.seat??ht(t);e.x=n.x,e.y=n.y,e.path=[],e.walking=!1,e.facing=O(e)?"up":"down",e.rest=2+e.seed%50/10}var O=t=>(t.state==="working"||t.state==="thinking"||t.state==="blocked")&&t.seat!==void 0&&t.seat.x===t.x&&t.seat.y===t.y&&t.path.length===0;function ot(t,e,n){if(!n)return;let i={x:Math.round(e.x),y:Math.round(e.y)};e.path=Z(t,i,n)??[]}function D(t,e){for(let n of t.agents)if(n.state!=="away"){if(n.path.length>0){let i=n.path[0],r=i.x-n.x,s=i.y-n.y,o=Math.hypot(r,s),a=3.2*e;Math.abs(r)>Math.abs(s)?n.facing=r>0?"right":"left":s!==0&&(n.facing=s>0?"down":"up"),n.walking=!0,o<=a?(n.x=i.x,n.y=i.y,n.path.shift()):(n.x+=r/o*a,n.y+=s/o*a);continue}n.walking=!1,n.state==="idle"&&(n.rest-=e,n.rest<=0&&(n.seed=V(String(n.seed)),n.rest=3+n.seed%60/10,ot(t,n,I(t,n)))),O(n)&&(n.facing="up")}}function P(t,e){if(Array.isArray(e.tasks)&&(t.tasks=S(e.tasks,60).map(et)),!Array.isArray(e.agents))return;let n=new Map(t.agents.map(r=>[r.id,r])),i=t.furniture.filter(r=>r.type==="desk").map(r=>({x:r.x+1,y:r.y+2})).filter(r=>R(t,r.x,r.y));t.agents=S(e.agents,40).map((r,s)=>{let o=tt(r,s),a=n.get(o.id);return o.seat=i[s],a?(Object.assign(a,{name:o.name,role:o.role,task:o.task,hair:o.hair,skin:o.skin,shirt:o.shirt,seat:o.seat}),a.state!==o.state&&(a.state=o.state,o.state!=="away"&&ot(t,a,I(t,a))),a):(nt(t,o),o)})}function L(t,e,n){let i,r=1/0;for(let s of t.agents){if(s.state==="away")continue;let o=e-(s.x+.5),a=n-(s.y+.1),u=Math.hypot(o,a);Math.abs(o)<.8&&a>-1.6&&a<1.1&&u<r&&(i=s,r=u)}return i}var d=16,f=(t,e,n,i,r,s)=>{t.fillStyle=e,t.fillRect(Math.round(n),Math.round(i),r,s)},bt=["...hhhhhh...","..hhhhhhhh..","..hhhhhhhh..","..hssssssh..","..ssessess..","..ssssssss..","...ssssss..."],pt=["...hhhhhh...","..hhhhhhhh..","..hhhhhhhh..","..hhhhhhhh..","..hhhhhhhh..","..hhhhhhhh..","...ssssss..."],yt=["...hhhhhh...","..hhhhhhhh..","..hhhhhhhh..","..hhssssss..","..hhsssess..","..hsssssss..","...ssssss..."],mt=["..tttttttt..",".tttttttttt.",".stttttttts.",".stTTTTTTts."],xt=["...tttttt...","...tttttt...","...ttsttt...","...TTsTTT..."],gt=["..llllllll..","..lll..lll..","..lll..lll..","..bbb..bbb.."],kt=["..llllllll..","..lll..lll..","..bbb..lll..",".......bbb.."],Mt=["..llllllll..","..lll..lll..","..lll..bbb..","..bbb......."],At=["...llllll...","...lll.lll..","...lll.lll..","...bbb.bbb.."],St=["...llllll...","..lll..lll..",".lll....lll.",".bb......bb."],wt=["...llllll...","...llllll...","....llll....","....bbbb...."];function $(t,e,n,i,r,s=!1){e.forEach((o,a)=>{for(let u=0;u<o.length;u++){let l=o[s?o.length-1-u:u],h=r[l];h&&f(t,h,n+u,i+a,1,1)}})}function Tt(t,e){let n=parseInt(t.slice(1).padEnd(6,t.slice(-1)),16),i=r=>Math.max(0,Math.min(255,(n>>r&255)+e));return`rgb(${i(16)},${i(8)},${i(0)})`}function vt(t,e,n,i){let r=e.x*d+2,s=O(e),o={h:e.hair,s:e.skin,e:"#1a1a24",t:e.shirt,T:Tt(e.shirt,-36),l:"#39415a",b:"#1f2433"},a=Math.floor(n*8+e.seed)%2===0,u=!e.walking&&Math.floor(n*1.5+e.seed%7)%2===0?1:0,l=s?11:15,h=e.y*d+(s?6:-1)-(e.walking&&a?1:0);s&&(f(t,"#1f2937",r+1,e.y*d+3,10,9),f(t,"#374151",r+2,e.y*d+11,8,3),f(t,"#111827",r+5,e.y*d+14,2,2)),t.fillStyle="rgba(0,0,0,0.25)",t.fillRect(Math.round(r+2),Math.round(e.y*d+14),8,2),i&&(t.fillStyle="rgba(255,255,255,0.28)",t.fillRect(Math.round(r-1),Math.round(e.y*d+13),14,4));let p=e.facing==="left"||e.facing==="right",x=p?yt:e.facing==="up"?pt:bt,k=p?xt:mt,M=e.walking?p?a?St:wt:a?kt:Mt:p?At:gt,c=e.facing==="left";if($(t,x,r,h-l+u*0,o,c),$(t,k,r,h-l+x.length,o,c),!s)$(t,M,r,h-l+x.length+k.length,o,c);else if(e.state==="working"){let b=Math.floor(n*9+e.seed)%2;f(t,e.skin,r+1+b,h-l+x.length+3,1,1),f(t,e.skin,r+10-(1-b),h-l+x.length+3,1,1)}}function W(t,e,n,i){f(t,"#111827",e-1,n-1,13,11),f(t,"#ffffff",e,n,11,9),f(t,"#ffffff",e+4,n+9,3,1),f(t,"#111827",e+4,n+10,3,1),i(e,n)}function Et(t,e,n){let i=Math.round(e.x*d+2),r=Math.round(e.y*d-26+(O(e)?8:0)),s=Math.floor(n*2+e.seed%3)%2===0;if(e.state==="blocked")W(t,i,r,(o,a)=>{f(t,s?"#dc2626":"#991b1b",o+5,a+1,2,5),f(t,s?"#dc2626":"#991b1b",o+5,a+7,2,1)});else if(e.state==="thinking"){let o=Math.floor(n*3)%4;W(t,i,r,(a,u)=>{for(let l=0;l<3;l++)f(t,l<o?"#111827":"#d1d5db",a+2+l*3,u+4,2,2)})}else if(e.state==="reviewing"&&!e.walking)W(t,i,r,(o,a)=>{f(t,"#2563eb",o+4,a+1,4,1),f(t,"#2563eb",o+7,a+2,1,2),f(t,"#2563eb",o+5,a+4,2,1),f(t,"#2563eb",o+5,a+5,1,1),f(t,"#2563eb",o+5,a+7,1,1)});else if(e.state==="done"){let o=s?"#f59e0b":"#fbbf24";W(t,i,r,(a,u)=>{f(t,o,a+5,u+1,1,7),f(t,o,a+2,u+3,7,2),f(t,o,a+4,u+2,3,5)})}}function Ot(t,e,n){for(let i=e.y;i<e.y+e.h;i++)for(let r=e.x;r<e.x+e.w;r++){let s=r*d,o=i*d;if(e.floor==="carpet"){f(t,"#4c4f7a",s,o,d,d);for(let a=0;a<6;a++)f(t,"#55588a",s+(r*7+a*5)%15,o+(i*3+a*7)%15,1,1)}else if(e.floor==="tile")f(t,(r+i)%2===0?"#cfd8e3":"#bcc7d4",s,o,d,d),f(t,"#aab5c2",s,o+15,d,1),f(t,"#aab5c2",s+15,o,1,d);else{f(t,"#a06f45",s,o,d,d);let a=i%2===0?0:8;f(t,"#8f6039",s,o+7,d,1),f(t,"#8f6039",s,o+15,d,1),f(t,"#8f6039",s+(a+r*8)%16,o,1,7),f(t,"#ad7c52",s+3,o+3,4,1)}}}var it="#2f3350",Ct="#565c86",Rt="#454a70";function Lt(t,e,n){let i=new Set;for(let r of e.rooms)for(let s=r.y;s<r.y+r.h;s++)for(let o=r.x;o<r.x+r.w;o++)i.add(`${o},${s}`);for(let r of e.doors)i.add(`${r.x},${r.y}`);for(let r=0;r<e.rows;r++)for(let s=0;s<e.cols;s++){if(i.has(`${s},${r}`))continue;let o=s*d,a=r*d;i.has(`${s},${r+1}`)?(f(t,Ct,o,a,d,d),f(t,Rt,o,a+13,d,3),f(t,n.primary,o,a+12,d,1),s%4===3&&r<=3&&(f(t,"#1f2937",o+1,a+1,14,9),f(t,"#8ed0ff",o+2,a+2,12,7),f(t,"#bfe6ff",o+3,a+3,4,2),f(t,"#1f2937",o+8,a+2,1,7))):f(t,it,o,a,d,d)}for(let r of e.doors)f(t,"#6b4a2f",r.x*d,r.y*d,d,d),f(t,"#7c5637",r.x*d+2,r.y*d,12,d)}function Wt(t,e,n,i,r,s,o){if(f(t,"#6b4427",e+1,n+13,46,17),f(t,"#8a5a33",e+1,n+11,46,11),f(t,"#a06c3f",e+1,n+11,46,2),f(t,"#4a2e1a",e+3,n+22,3,9),f(t,"#4a2e1a",e+42,n+22,3,9),f(t,"#111827",e+15,n-1,18,13),f(t,"#374151",e+22,n+12,4,2),i){f(t,"#0f2a2e",e+16,n,16,11);let a=Math.floor(r*3+s%13);for(let u=0;u<4;u++){let l=3+((s>>u)+(a+u)*7)%11;f(t,u%2===0?o.primary:"#7dd3fc",e+17,n+1+u*2.5,l,1)}t.fillStyle="rgba(125,211,252,0.10)",t.fillRect(e+11,n+11,26,8)}else f(t,"#1f2937",e+16,n,16,11),f(t,"#374151",e+18,n+2,3,1);f(t,"#d1d5db",e+17,n+15,14,4),f(t,"#9ca3af",e+18,n+16,12,1),f(t,"#f3f4f6",e+38,n+14,4,4),f(t,o.primary,e+38,n+16,4,1)}function _t(t,e,n,i){f(t,"#2b2118",e,n-11,64,26),f(t,"#d9c29c",e+2,n-9,60,22);let r={todo:"#fde68a",doing:"#93c5fd",done:"#86efac"},s=8;i.tasks.slice(0,s*2).forEach((o,a)=>{let u=a%s,l=Math.floor(a/s);f(t,"#00000033",e+5+u*7,n-6+l*9,6,7),f(t,r[o.state],e+4+u*7,n-7+l*9,6,7),f(t,"#00000040",e+5+u*7,n-5+l*9,4,1)})}function st(t,e,n,i,r){let s=e.x*d,o=e.y*d;switch(e.type){case"desk":{let a=e.x+1,u=e.y+2,l=n.agents.find(h=>h.seat?.x===a&&h.seat?.y===u&&O(h)&&h.state!=="blocked");Wt(t,s,o,!!l,i,l?.seed??0,r);break}case"coffee":f(t,"#374151",s,o+2,32,14),f(t,"#6b7280",s,o+2,32,2),f(t,"#111827",s+4,o-8,14,14),f(t,"#ef4444",s+15,o-5,2,2),f(t,"#f3f4f6",s+8,o+3,5,4),f(t,"#f3f4f6",s+22,o-1,5,5);for(let a=0;a<3;a++)t.fillStyle="rgba(255,255,255,0.45)",t.fillRect(s+9+Math.round(Math.sin(i*2+a)*1.5),o-1-(i*8+a*4)%9,1,2);break;case"water":f(t,"#e5e7eb",s+3,o+3,10,13),f(t,"#7dd3fc",s+4,o-7,8,10),f(t,"#bae6fd",s+5,o-6,2,8),f(t,"#3b82f6",s+5,o+6,2,2);break;case"sofa":f(t,r.primary,s+1,o-6,46,9),f(t,"#00000030",s+1,o+1,46,2),f(t,"#4b5563",s,o+3,48,11),f(t,"#6b7280",s+3,o+3,20,7),f(t,"#6b7280",s+25,o+3,20,7),f(t,"#374151",s,o+12,48,3);break;case"plant":f(t,"#92400e",s+4,o+9,8,7),f(t,"#b45309",s+3,o+8,10,2);for(let[a,u,l,h]of[[6,-3,4,11],[2,0,5,6],[9,1,5,6],[4,-6,3,6],[9,-5,3,5]])f(t,"#15803d",s+a,o+u,l,h);f(t,"#22c55e",s+7,o-3,2,8),f(t,"#22c55e",s+3,o+1,2,3);break;case"board":_t(t,s,o,n);break;case"shelf":f(t,"#5b3a21",s,o-12,32,28);for(let a=0;a<2;a++){f(t,"#3b2413",s+2,o-10+a*13,28,11);for(let u=0;u<8;u++){let l=["#ef4444","#3b82f6","#10b981","#f59e0b","#8b5cf6"][(u*3+a)%5];f(t,l,s+3+u*3,o-8+a*13+u%3,2,9-u%3)}}break;case"server":f(t,"#111827",s+1,o-12,14,28);for(let a=0;a<5;a++){f(t,"#1f2937",s+2,o-11+a*5,12,4);let u=Math.floor(i*3+a*2+e.x)%3!==0;f(t,u?"#22c55e":"#14532d",s+3,o-10+a*5,1,1),f(t,a%2===0?"#f59e0b":"#3b82f6",s+5,o-10+a*5,1,1)}break;case"table":f(t,"#57534e",s+2,o+14,44,14),f(t,"#78716c",s+2,o+3,44,14),f(t,"#a8a29e",s+2,o+3,44,2),f(t,"#f9fafb",s+10,o+6,8,6),f(t,"#f9fafb",s+28,o+8,8,6);break;case"rug":f(t,r.primary,s,o,64,48),t.fillStyle="rgba(0,0,0,0.35)",t.fillRect(s+3,o+3,58,42),f(t,r.primary,s+6,o+6,52,1),f(t,r.primary,s+6,o+41,52,1);break}}function Ft(t,e){t.font="bold 7px ui-monospace, Menlo, Consolas, monospace",t.textBaseline="top";for(let n of e.rooms){if(!n.name)continue;let i=n.name.toUpperCase(),r=n.x*d+3,s=n.y*d-12;t.fillStyle="rgba(0,0,0,0.45)",t.fillText(i,r+1,s+1),t.fillStyle="rgba(255,255,255,0.85)",t.fillText(i,r,s)}}function Bt(t,e,n,i){let r=e.name;t.font="bold 7px ui-monospace, Menlo, Consolas, monospace",t.textBaseline="top";let s=Math.ceil(t.measureText(r).width)+5,o=e.x*d+8,a=Math.round(Math.max(1,Math.min(i-s-1,o-s/2))),u=Math.round(e.y*d+15);t.fillStyle=n?"#ffffff":"rgba(17,24,39,0.82)",t.fillRect(a,u,s,10),t.fillStyle=n?"#111827":"#ffffff",t.fillText(r,a+2.5,u+1.5)}function It(t,e,n){let i=[],r="";for(let s of e.split(/\s+/)){let o=r?`${r} ${s}`:s;t.measureText(o).width>n&&r?(i.push(r),r=s):r=o}return r&&i.push(r),i.slice(0,3)}var rt={working:"Working",thinking:"Thinking",blocked:"Blocked",reviewing:"Reviewing",idle:"On a break",done:"Finished",away:"Away"};function Dt(t,e,n){t.font="7px ui-monospace, Menlo, Consolas, monospace",t.textBaseline="top";let i=It(t,e.task||rt[e.state]||"",104),r=114,s=18+i.length*9+3,o=Math.round(Math.max(2,Math.min(n-r-2,e.x*d+8-r/2))),a=Math.round(Math.max(2,e.y*d-s-22));f(t,"#111827",o-1,a-1,r+2,s+2),f(t,"#ffffff",o,a,r,s),t.fillStyle="#111827",t.font="bold 7px ui-monospace, Menlo, Consolas, monospace",t.fillText(`${e.name}: ${rt[e.state]??""}`.slice(0,26),o+4,a+4),t.fillStyle="#374151",t.font="7px ui-monospace, Menlo, Consolas, monospace",i.forEach((u,l)=>t.fillText(u,o+4,a+15+l*9))}function Pt(t,e,n){if(e.tasks.length===0)return;let i=e.tasks.filter(o=>o.state==="done").length,r=`QUESTS ${i}/${e.tasks.length}`;t.font="bold 7px ui-monospace, Menlo, Consolas, monospace",t.textBaseline="top";let s=96;f(t,"rgba(17,24,39,0.85)",4,4,s,20),t.fillStyle="#ffffff",t.fillText(r,8,6.5),f(t,"#374151",8,16,s-8,4),f(t,n.primary,8,16,Math.round((s-8)*i/e.tasks.length),4)}function at(t,e,n,i,r){let s=e.cols*d;f(t,it,0,0,s,e.rows*d);for(let l of e.rooms)Ot(t,l,i);Lt(t,e,i);for(let l of e.furniture)l.type==="rug"&&st(t,l,e,n,i);let o=[];for(let l of e.furniture)l.type!=="rug"&&o.push({depth:(l.y+E[l.type].h)*d-2,draw:()=>st(t,l,e,n,i)});let a=e.agents.filter(l=>l.state!=="away");for(let l of a)o.push({depth:l.y*d+14,draw:()=>vt(t,l,n,l.id===r)});o.sort((l,h)=>l.depth-h.depth);for(let l of o)l.draw();Ft(t,e);for(let l of a)Bt(t,l,l.id===r,s);for(let l of a)l.id!==r&&Et(t,l,n);Pt(t,e,i);let u=a.find(l=>l.id===r);u&&Dt(t,u,s)}var $t=/^(#[0-9a-f]{3,8}|rgba?\([\d\s.,%/]+\)|hsla?\([\d\s.,%/a-z]+\))$/i;function Ht(t){let e=getComputedStyle(t),n=(i,r)=>{let s=e.getPropertyValue(i).trim();return $t.test(s)?s:r};return{primary:n("--blkc-color-primary","#3b82f6"),accent:n("--blkc-color-accent","#f59e0b"),background:n("--blkc-color-background","#1a1a2e"),text:n("--blkc-color-text","#ffffff")}}function H(t,e={},n={}){let i=B(e),r=t.getContext("2d");if(!r)throw new Error("This browser can't draw to a canvas.");let s=r,o=i.cols*d,a=i.rows*d,u=Ht(t),l=typeof matchMedia=="function"&&matchMedia("(prefers-reduced-motion: reduce)").matches,h,p=0,x=0,k=0,M=0,c=!0,b=!1,y=()=>{s.setTransform(p,0,0,p,0,0),s.imageSmoothingEnabled=!1,at(s,i,x,u,h)},T=()=>{let m=t.getBoundingClientRect().width||o,v=Math.max(1,Math.ceil(m*(typeof devicePixelRatio=="number"?devicePixelRatio:1)/o));v!==p&&(p=v,t.width=o*p,t.height=a*p,y())},U=m=>{if(b)return;if(M=requestAnimationFrame(U),!c){k=m;return}let g=Math.min((m-k)/1e3||0,.1);k=m,x+=g,D(i,g),y()},X=m=>{h=m===h?void 0:m,n.onSelect?.(h),l&&y()},G=m=>{let g=t.getBoundingClientRect();return{x:(m.clientX-g.left)/g.width*i.cols,y:(m.clientY-g.top)/g.height*i.rows}},K=m=>{let{x:g,y:v}=G(m);X(L(i,g,v)?.id)},j=m=>{let{x:g,y:v}=G(m);t.style.cursor=L(i,g,v)?"pointer":"default"};t.addEventListener("pointerdown",K),t.addEventListener("pointermove",j);let q=typeof ResizeObserver=="function"?new ResizeObserver(T):void 0;q?.observe(t);let z=typeof IntersectionObserver=="function"?new IntersectionObserver(m=>{c=m.some(g=>g.isIntersecting)}):void 0;return z?.observe(t),T(),p===0&&(p=1,y()),l||(M=requestAnimationFrame(U)),{world:i,update(m){P(i,m),l&&y()},select:X,destroy(){b=!0,cancelAnimationFrame(M),q?.disconnect(),z?.disconnect(),t.removeEventListener("pointerdown",K),t.removeEventListener("pointermove",j)}}}var lt=new Map;function Nt(t,e){lt.set(t,e)}function Ut(t,e,n){let i=[...n.querySelectorAll("button[data-blkc-agent]")],r=H(t,e,{onSelect(s){for(let o of i)o.setAttribute("aria-pressed",String(o.dataset.blkcAgent===s))}});for(let s of i)s.disabled=!1,s.addEventListener("click",()=>r.select(s.dataset.blkcAgent));return r}Nt("office",Ut);var ft=new WeakSet;function N(t=document){let e=[];for(let n of t.querySelectorAll("canvas[data-blkc-canvas]")){if(ft.has(n))continue;let i=lt.get(n.dataset.blkcCanvas??"");if(!i)continue;let r=n.closest("[data-blkc-canvas-root]")??n.parentElement??n,s=r.querySelector("script[data-blkc-canvas-data]"),o={};try{o=JSON.parse(s?.textContent||"{}")}catch{o={}}ft.add(n);let a=i(n,o,r);e.push({element:n,destroy:()=>a.destroy()})}return e}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>N()):N();})();
|
|
2
|
+
/**
|
|
3
|
+
* BLKC Render-Canvas.
|
|
4
|
+
*
|
|
5
|
+
* A canvas Block is ordinary markup from @blkc-code/render-web plus its data, and this
|
|
6
|
+
* package brings it to life. Call mountCanvasBlocks() once the page is in the document:
|
|
7
|
+
* a <canvas data-blkc-canvas="office"> with a JSON <script> beside it starts running.
|
|
8
|
+
*
|
|
9
|
+
* @package @blkc-code/render-canvas
|
|
10
|
+
* @license Apache-2.0
|
|
11
|
+
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,IAAI,QAAQ,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;IACtC,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC;AAC3E,CAAC;KAAM,CAAC;IACN,iBAAiB,EAAE,CAAC;AACtB,CAAC"}
|
package/dist/runtime.txt
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";(()=>{var E={desk:{w:3,h:2,spot:{x:1,y:2}},coffee:{w:2,h:1,spot:{x:0,y:1}},water:{w:1,h:1,spot:{x:0,y:1}},sofa:{w:3,h:1,spot:{x:1,y:1}},plant:{w:1,h:1},board:{w:4,h:1,spot:{x:1,y:1}},shelf:{w:2,h:1,spot:{x:0,y:1}},server:{w:1,h:1},table:{w:3,h:2,spot:{x:1,y:2}},rug:{w:4,h:3,solid:!1}},ct=["working","thinking","blocked","reviewing","idle","done","away"],ut=["todo","doing","done"],dt=["wood","carpet","tile"],C={cols:26,rows:17,rooms:[{id:"studio",name:"Studio",x:1,y:3,w:15,h:13,floor:"wood"},{id:"lounge",name:"Lounge",x:17,y:3,w:8,h:6,floor:"carpet"},{id:"quests",name:"Quests",x:17,y:10,w:8,h:6,floor:"tile"}],doors:[{x:16,y:6},{x:16,y:13},{x:23,y:9}],furniture:[{type:"desk",x:2,y:4},{type:"desk",x:7,y:4},{type:"desk",x:12,y:4},{type:"desk",x:2,y:10},{type:"desk",x:7,y:10},{type:"desk",x:12,y:10},{type:"plant",x:1,y:8},{type:"plant",x:15,y:8},{type:"server",x:15,y:15},{type:"server",x:14,y:15},{type:"shelf",x:1,y:15},{type:"coffee",x:19,y:3},{type:"water",x:21,y:3},{type:"sofa",x:22,y:3},{type:"rug",x:20,y:5},{type:"plant",x:24,y:8},{type:"board",x:19,y:10},{type:"table",x:19,y:13},{type:"plant",x:24,y:15}]},A=(t,e)=>typeof t=="number"&&Number.isFinite(t)?Math.floor(t):e,w=(t,e=120)=>typeof t=="string"?t.slice(0,e):"",S=(t,e)=>Array.isArray(t)?t.slice(0,e):[];function V(t){let e=2166136261;for(let n=0;n<t.length;n++)e=Math.imul(e^t.charCodeAt(n),16777619);return e>>>0}var Y=["#2b1b12","#5a3a22","#a8622d","#d9b36c","#20242e","#7d2f3f","#4a5568","#e5e7eb"],Q=["#f4d3b5","#e8b98f","#c98d62","#9c6644","#6f4530","#4e2f20"],J=["#3b82f6","#ef4444","#10b981","#f59e0b","#8b5cf6","#ec4899","#14b8a6","#f97316"],_=(t,e)=>typeof t=="string"&&/^#[0-9a-f]{3,8}$/i.test(t)?t:e,F=(t,e,n)=>n*t.cols+e;function R(t,e,n){return e>=0&&n>=0&&e<t.cols&&n<t.rows&&t.walkable[F(t,e,n)]===!0}function Z(t,e,n){if(!R(t,n.x,n.y))return null;if(e.x===n.x&&e.y===n.y)return[];let i=new Int32Array(t.cols*t.rows).fill(-1),r=F(t,e.x,e.y);i[r]=r;let s=[r];for(let o=0;o<s.length;o++){let a=s[o],u=a%t.cols,l=Math.floor(a/t.cols);if(u===n.x&&l===n.y){let h=[];for(let p=a;p!==r;p=i[p])h.unshift({x:p%t.cols,y:Math.floor(p/t.cols)});return h}for(let[h,p]of[[0,1],[0,-1],[1,0],[-1,0]]){let x=u+h,k=l+p;if(!R(t,x,k))continue;let M=F(t,x,k);i[M]===-1&&(i[M]=a,s.push(M))}}return null}function tt(t,e){let n=w(t?.id,60)||`agent-${e+1}`,i=V(n),r=ct.includes(t?.state)?t.state:"idle";return{id:n,name:w(t?.name,24)||n,role:w(t?.role,40),state:r,task:w(t?.task,120),hair:_(t?.hair,Y[i%Y.length]),skin:_(t?.skin,Q[(i>>>4)%Q.length]),shirt:_(t?.shirt,J[(i>>>8)%J.length]),x:0,y:0,path:[],facing:"down",walking:!1,rest:0,seed:i}}function et(t){return{title:w(t?.title,80),state:ut.includes(t?.state)?t.state:"todo",agent:w(t?.agent,60)}}function B(t={}){let e=Array.isArray(t?.rooms)&&t.rooms.length>0,n=Math.min(Math.max(A(t?.cols,e?20:C.cols),6),64),i=Math.min(Math.max(A(t?.rows,e?14:C.rows),6),40),r=e?S(t.rooms,40):C.rooms,s=e?S(t.doors,60):C.doors,o=Array.isArray(t?.furniture)?S(t.furniture,300):e?[]:C.furniture,a=r.map(c=>{let b=Math.min(Math.max(A(c?.x,0),0),n),y=Math.min(Math.max(A(c?.y,0),0),i);return{name:w(c?.name,24),x:b,y,w:Math.min(Math.max(A(c?.w,0),0),n-b),h:Math.min(Math.max(A(c?.h,0),0),i-y),floor:dt.includes(c?.floor)?c.floor:"wood"}}),u=new Array(n*i).fill(!1),l=(c,b,y)=>{c>=0&&b>=0&&c<n&&b<i&&(u[b*n+c]=y)};for(let c of a)for(let b=c.y;b<c.y+c.h;b++)for(let y=c.x;y<c.x+c.w;y++)l(y,b,!0);let h=s.map(c=>({x:A(c?.x,-1),y:A(c?.y,-1)})).filter(c=>c.x>=0&&c.y>=0);for(let c of h)l(c.x,c.y,!0);let p=o.filter(c=>c&&Object.hasOwn(E,c.type)).map(c=>({type:c.type,x:A(c.x,-99),y:A(c.y,-99)}));for(let c of p){let b=E[c.type];if(b.solid!==!1)for(let y=c.y;y<c.y+b.h;y++)for(let T=c.x;T<c.x+b.w;T++)l(T,y,!1)}let x={cols:n,rows:i,rooms:a,doors:h,furniture:p,walkable:u,agents:S(t?.agents,40).map(tt),tasks:S(t?.tasks,60).map(et),spots:{lounge:[],board:[]}},k=c=>{let b=E[c.type].spot;if(!b)return;let y={x:c.x+b.x,y:c.y+b.y};return R(x,y.x,y.y)?y:void 0},M=p.filter(c=>c.type==="desk").map(k).filter(c=>!!c);for(let c of p){let b=k(c);b&&((c.type==="coffee"||c.type==="sofa"||c.type==="water"||c.type==="shelf")&&x.spots.lounge.push(b),(c.type==="board"||c.type==="table")&&x.spots.board.push(b))}return x.agents.forEach((c,b)=>{c.seat=M[b],nt(x,c)}),x}function ht(t){for(let e=0;e<t.rows;e++)for(let n=0;n<t.cols;n++)if(R(t,n,e))return{x:n,y:e};return{x:0,y:0}}function I(t,e){let n=i=>i.length>0?i[(e.seed+Math.floor(e.rest*1e3))%i.length]:void 0;switch(e.state){case"working":case"thinking":case"blocked":return e.seat??n(t.spots.lounge);case"reviewing":return n(t.spots.board)??e.seat;case"idle":case"done":return n(t.spots.lounge)??e.seat;default:return}}function nt(t,e){let n=I(t,e)??e.seat??ht(t);e.x=n.x,e.y=n.y,e.path=[],e.walking=!1,e.facing=O(e)?"up":"down",e.rest=2+e.seed%50/10}var O=t=>(t.state==="working"||t.state==="thinking"||t.state==="blocked")&&t.seat!==void 0&&t.seat.x===t.x&&t.seat.y===t.y&&t.path.length===0;function ot(t,e,n){if(!n)return;let i={x:Math.round(e.x),y:Math.round(e.y)};e.path=Z(t,i,n)??[]}function D(t,e){for(let n of t.agents)if(n.state!=="away"){if(n.path.length>0){let i=n.path[0],r=i.x-n.x,s=i.y-n.y,o=Math.hypot(r,s),a=3.2*e;Math.abs(r)>Math.abs(s)?n.facing=r>0?"right":"left":s!==0&&(n.facing=s>0?"down":"up"),n.walking=!0,o<=a?(n.x=i.x,n.y=i.y,n.path.shift()):(n.x+=r/o*a,n.y+=s/o*a);continue}n.walking=!1,n.state==="idle"&&(n.rest-=e,n.rest<=0&&(n.seed=V(String(n.seed)),n.rest=3+n.seed%60/10,ot(t,n,I(t,n)))),O(n)&&(n.facing="up")}}function P(t,e){if(Array.isArray(e.tasks)&&(t.tasks=S(e.tasks,60).map(et)),!Array.isArray(e.agents))return;let n=new Map(t.agents.map(r=>[r.id,r])),i=t.furniture.filter(r=>r.type==="desk").map(r=>({x:r.x+1,y:r.y+2})).filter(r=>R(t,r.x,r.y));t.agents=S(e.agents,40).map((r,s)=>{let o=tt(r,s),a=n.get(o.id);return o.seat=i[s],a?(Object.assign(a,{name:o.name,role:o.role,task:o.task,hair:o.hair,skin:o.skin,shirt:o.shirt,seat:o.seat}),a.state!==o.state&&(a.state=o.state,o.state!=="away"&&ot(t,a,I(t,a))),a):(nt(t,o),o)})}function L(t,e,n){let i,r=1/0;for(let s of t.agents){if(s.state==="away")continue;let o=e-(s.x+.5),a=n-(s.y+.1),u=Math.hypot(o,a);Math.abs(o)<.8&&a>-1.6&&a<1.1&&u<r&&(i=s,r=u)}return i}var d=16,f=(t,e,n,i,r,s)=>{t.fillStyle=e,t.fillRect(Math.round(n),Math.round(i),r,s)},bt=["...hhhhhh...","..hhhhhhhh..","..hhhhhhhh..","..hssssssh..","..ssessess..","..ssssssss..","...ssssss..."],pt=["...hhhhhh...","..hhhhhhhh..","..hhhhhhhh..","..hhhhhhhh..","..hhhhhhhh..","..hhhhhhhh..","...ssssss..."],yt=["...hhhhhh...","..hhhhhhhh..","..hhhhhhhh..","..hhssssss..","..hhsssess..","..hsssssss..","...ssssss..."],mt=["..tttttttt..",".tttttttttt.",".stttttttts.",".stTTTTTTts."],xt=["...tttttt...","...tttttt...","...ttsttt...","...TTsTTT..."],gt=["..llllllll..","..lll..lll..","..lll..lll..","..bbb..bbb.."],kt=["..llllllll..","..lll..lll..","..bbb..lll..",".......bbb.."],Mt=["..llllllll..","..lll..lll..","..lll..bbb..","..bbb......."],At=["...llllll...","...lll.lll..","...lll.lll..","...bbb.bbb.."],St=["...llllll...","..lll..lll..",".lll....lll.",".bb......bb."],wt=["...llllll...","...llllll...","....llll....","....bbbb...."];function $(t,e,n,i,r,s=!1){e.forEach((o,a)=>{for(let u=0;u<o.length;u++){let l=o[s?o.length-1-u:u],h=r[l];h&&f(t,h,n+u,i+a,1,1)}})}function Tt(t,e){let n=parseInt(t.slice(1).padEnd(6,t.slice(-1)),16),i=r=>Math.max(0,Math.min(255,(n>>r&255)+e));return`rgb(${i(16)},${i(8)},${i(0)})`}function vt(t,e,n,i){let r=e.x*d+2,s=O(e),o={h:e.hair,s:e.skin,e:"#1a1a24",t:e.shirt,T:Tt(e.shirt,-36),l:"#39415a",b:"#1f2433"},a=Math.floor(n*8+e.seed)%2===0,u=!e.walking&&Math.floor(n*1.5+e.seed%7)%2===0?1:0,l=s?11:15,h=e.y*d+(s?6:-1)-(e.walking&&a?1:0);s&&(f(t,"#1f2937",r+1,e.y*d+3,10,9),f(t,"#374151",r+2,e.y*d+11,8,3),f(t,"#111827",r+5,e.y*d+14,2,2)),t.fillStyle="rgba(0,0,0,0.25)",t.fillRect(Math.round(r+2),Math.round(e.y*d+14),8,2),i&&(t.fillStyle="rgba(255,255,255,0.28)",t.fillRect(Math.round(r-1),Math.round(e.y*d+13),14,4));let p=e.facing==="left"||e.facing==="right",x=p?yt:e.facing==="up"?pt:bt,k=p?xt:mt,M=e.walking?p?a?St:wt:a?kt:Mt:p?At:gt,c=e.facing==="left";if($(t,x,r,h-l+u*0,o,c),$(t,k,r,h-l+x.length,o,c),!s)$(t,M,r,h-l+x.length+k.length,o,c);else if(e.state==="working"){let b=Math.floor(n*9+e.seed)%2;f(t,e.skin,r+1+b,h-l+x.length+3,1,1),f(t,e.skin,r+10-(1-b),h-l+x.length+3,1,1)}}function W(t,e,n,i){f(t,"#111827",e-1,n-1,13,11),f(t,"#ffffff",e,n,11,9),f(t,"#ffffff",e+4,n+9,3,1),f(t,"#111827",e+4,n+10,3,1),i(e,n)}function Et(t,e,n){let i=Math.round(e.x*d+2),r=Math.round(e.y*d-26+(O(e)?8:0)),s=Math.floor(n*2+e.seed%3)%2===0;if(e.state==="blocked")W(t,i,r,(o,a)=>{f(t,s?"#dc2626":"#991b1b",o+5,a+1,2,5),f(t,s?"#dc2626":"#991b1b",o+5,a+7,2,1)});else if(e.state==="thinking"){let o=Math.floor(n*3)%4;W(t,i,r,(a,u)=>{for(let l=0;l<3;l++)f(t,l<o?"#111827":"#d1d5db",a+2+l*3,u+4,2,2)})}else if(e.state==="reviewing"&&!e.walking)W(t,i,r,(o,a)=>{f(t,"#2563eb",o+4,a+1,4,1),f(t,"#2563eb",o+7,a+2,1,2),f(t,"#2563eb",o+5,a+4,2,1),f(t,"#2563eb",o+5,a+5,1,1),f(t,"#2563eb",o+5,a+7,1,1)});else if(e.state==="done"){let o=s?"#f59e0b":"#fbbf24";W(t,i,r,(a,u)=>{f(t,o,a+5,u+1,1,7),f(t,o,a+2,u+3,7,2),f(t,o,a+4,u+2,3,5)})}}function Ot(t,e,n){for(let i=e.y;i<e.y+e.h;i++)for(let r=e.x;r<e.x+e.w;r++){let s=r*d,o=i*d;if(e.floor==="carpet"){f(t,"#4c4f7a",s,o,d,d);for(let a=0;a<6;a++)f(t,"#55588a",s+(r*7+a*5)%15,o+(i*3+a*7)%15,1,1)}else if(e.floor==="tile")f(t,(r+i)%2===0?"#cfd8e3":"#bcc7d4",s,o,d,d),f(t,"#aab5c2",s,o+15,d,1),f(t,"#aab5c2",s+15,o,1,d);else{f(t,"#a06f45",s,o,d,d);let a=i%2===0?0:8;f(t,"#8f6039",s,o+7,d,1),f(t,"#8f6039",s,o+15,d,1),f(t,"#8f6039",s+(a+r*8)%16,o,1,7),f(t,"#ad7c52",s+3,o+3,4,1)}}}var it="#2f3350",Ct="#565c86",Rt="#454a70";function Lt(t,e,n){let i=new Set;for(let r of e.rooms)for(let s=r.y;s<r.y+r.h;s++)for(let o=r.x;o<r.x+r.w;o++)i.add(`${o},${s}`);for(let r of e.doors)i.add(`${r.x},${r.y}`);for(let r=0;r<e.rows;r++)for(let s=0;s<e.cols;s++){if(i.has(`${s},${r}`))continue;let o=s*d,a=r*d;i.has(`${s},${r+1}`)?(f(t,Ct,o,a,d,d),f(t,Rt,o,a+13,d,3),f(t,n.primary,o,a+12,d,1),s%4===3&&r<=3&&(f(t,"#1f2937",o+1,a+1,14,9),f(t,"#8ed0ff",o+2,a+2,12,7),f(t,"#bfe6ff",o+3,a+3,4,2),f(t,"#1f2937",o+8,a+2,1,7))):f(t,it,o,a,d,d)}for(let r of e.doors)f(t,"#6b4a2f",r.x*d,r.y*d,d,d),f(t,"#7c5637",r.x*d+2,r.y*d,12,d)}function Wt(t,e,n,i,r,s,o){if(f(t,"#6b4427",e+1,n+13,46,17),f(t,"#8a5a33",e+1,n+11,46,11),f(t,"#a06c3f",e+1,n+11,46,2),f(t,"#4a2e1a",e+3,n+22,3,9),f(t,"#4a2e1a",e+42,n+22,3,9),f(t,"#111827",e+15,n-1,18,13),f(t,"#374151",e+22,n+12,4,2),i){f(t,"#0f2a2e",e+16,n,16,11);let a=Math.floor(r*3+s%13);for(let u=0;u<4;u++){let l=3+((s>>u)+(a+u)*7)%11;f(t,u%2===0?o.primary:"#7dd3fc",e+17,n+1+u*2.5,l,1)}t.fillStyle="rgba(125,211,252,0.10)",t.fillRect(e+11,n+11,26,8)}else f(t,"#1f2937",e+16,n,16,11),f(t,"#374151",e+18,n+2,3,1);f(t,"#d1d5db",e+17,n+15,14,4),f(t,"#9ca3af",e+18,n+16,12,1),f(t,"#f3f4f6",e+38,n+14,4,4),f(t,o.primary,e+38,n+16,4,1)}function _t(t,e,n,i){f(t,"#2b2118",e,n-11,64,26),f(t,"#d9c29c",e+2,n-9,60,22);let r={todo:"#fde68a",doing:"#93c5fd",done:"#86efac"},s=8;i.tasks.slice(0,s*2).forEach((o,a)=>{let u=a%s,l=Math.floor(a/s);f(t,"#00000033",e+5+u*7,n-6+l*9,6,7),f(t,r[o.state],e+4+u*7,n-7+l*9,6,7),f(t,"#00000040",e+5+u*7,n-5+l*9,4,1)})}function st(t,e,n,i,r){let s=e.x*d,o=e.y*d;switch(e.type){case"desk":{let a=e.x+1,u=e.y+2,l=n.agents.find(h=>h.seat?.x===a&&h.seat?.y===u&&O(h)&&h.state!=="blocked");Wt(t,s,o,!!l,i,l?.seed??0,r);break}case"coffee":f(t,"#374151",s,o+2,32,14),f(t,"#6b7280",s,o+2,32,2),f(t,"#111827",s+4,o-8,14,14),f(t,"#ef4444",s+15,o-5,2,2),f(t,"#f3f4f6",s+8,o+3,5,4),f(t,"#f3f4f6",s+22,o-1,5,5);for(let a=0;a<3;a++)t.fillStyle="rgba(255,255,255,0.45)",t.fillRect(s+9+Math.round(Math.sin(i*2+a)*1.5),o-1-(i*8+a*4)%9,1,2);break;case"water":f(t,"#e5e7eb",s+3,o+3,10,13),f(t,"#7dd3fc",s+4,o-7,8,10),f(t,"#bae6fd",s+5,o-6,2,8),f(t,"#3b82f6",s+5,o+6,2,2);break;case"sofa":f(t,r.primary,s+1,o-6,46,9),f(t,"#00000030",s+1,o+1,46,2),f(t,"#4b5563",s,o+3,48,11),f(t,"#6b7280",s+3,o+3,20,7),f(t,"#6b7280",s+25,o+3,20,7),f(t,"#374151",s,o+12,48,3);break;case"plant":f(t,"#92400e",s+4,o+9,8,7),f(t,"#b45309",s+3,o+8,10,2);for(let[a,u,l,h]of[[6,-3,4,11],[2,0,5,6],[9,1,5,6],[4,-6,3,6],[9,-5,3,5]])f(t,"#15803d",s+a,o+u,l,h);f(t,"#22c55e",s+7,o-3,2,8),f(t,"#22c55e",s+3,o+1,2,3);break;case"board":_t(t,s,o,n);break;case"shelf":f(t,"#5b3a21",s,o-12,32,28);for(let a=0;a<2;a++){f(t,"#3b2413",s+2,o-10+a*13,28,11);for(let u=0;u<8;u++){let l=["#ef4444","#3b82f6","#10b981","#f59e0b","#8b5cf6"][(u*3+a)%5];f(t,l,s+3+u*3,o-8+a*13+u%3,2,9-u%3)}}break;case"server":f(t,"#111827",s+1,o-12,14,28);for(let a=0;a<5;a++){f(t,"#1f2937",s+2,o-11+a*5,12,4);let u=Math.floor(i*3+a*2+e.x)%3!==0;f(t,u?"#22c55e":"#14532d",s+3,o-10+a*5,1,1),f(t,a%2===0?"#f59e0b":"#3b82f6",s+5,o-10+a*5,1,1)}break;case"table":f(t,"#57534e",s+2,o+14,44,14),f(t,"#78716c",s+2,o+3,44,14),f(t,"#a8a29e",s+2,o+3,44,2),f(t,"#f9fafb",s+10,o+6,8,6),f(t,"#f9fafb",s+28,o+8,8,6);break;case"rug":f(t,r.primary,s,o,64,48),t.fillStyle="rgba(0,0,0,0.35)",t.fillRect(s+3,o+3,58,42),f(t,r.primary,s+6,o+6,52,1),f(t,r.primary,s+6,o+41,52,1);break}}function Ft(t,e){t.font="bold 7px ui-monospace, Menlo, Consolas, monospace",t.textBaseline="top";for(let n of e.rooms){if(!n.name)continue;let i=n.name.toUpperCase(),r=n.x*d+3,s=n.y*d-12;t.fillStyle="rgba(0,0,0,0.45)",t.fillText(i,r+1,s+1),t.fillStyle="rgba(255,255,255,0.85)",t.fillText(i,r,s)}}function Bt(t,e,n,i){let r=e.name;t.font="bold 7px ui-monospace, Menlo, Consolas, monospace",t.textBaseline="top";let s=Math.ceil(t.measureText(r).width)+5,o=e.x*d+8,a=Math.round(Math.max(1,Math.min(i-s-1,o-s/2))),u=Math.round(e.y*d+15);t.fillStyle=n?"#ffffff":"rgba(17,24,39,0.82)",t.fillRect(a,u,s,10),t.fillStyle=n?"#111827":"#ffffff",t.fillText(r,a+2.5,u+1.5)}function It(t,e,n){let i=[],r="";for(let s of e.split(/\s+/)){let o=r?`${r} ${s}`:s;t.measureText(o).width>n&&r?(i.push(r),r=s):r=o}return r&&i.push(r),i.slice(0,3)}var rt={working:"Working",thinking:"Thinking",blocked:"Blocked",reviewing:"Reviewing",idle:"On a break",done:"Finished",away:"Away"};function Dt(t,e,n){t.font="7px ui-monospace, Menlo, Consolas, monospace",t.textBaseline="top";let i=It(t,e.task||rt[e.state]||"",104),r=114,s=18+i.length*9+3,o=Math.round(Math.max(2,Math.min(n-r-2,e.x*d+8-r/2))),a=Math.round(Math.max(2,e.y*d-s-22));f(t,"#111827",o-1,a-1,r+2,s+2),f(t,"#ffffff",o,a,r,s),t.fillStyle="#111827",t.font="bold 7px ui-monospace, Menlo, Consolas, monospace",t.fillText(`${e.name}: ${rt[e.state]??""}`.slice(0,26),o+4,a+4),t.fillStyle="#374151",t.font="7px ui-monospace, Menlo, Consolas, monospace",i.forEach((u,l)=>t.fillText(u,o+4,a+15+l*9))}function Pt(t,e,n){if(e.tasks.length===0)return;let i=e.tasks.filter(o=>o.state==="done").length,r=`QUESTS ${i}/${e.tasks.length}`;t.font="bold 7px ui-monospace, Menlo, Consolas, monospace",t.textBaseline="top";let s=96;f(t,"rgba(17,24,39,0.85)",4,4,s,20),t.fillStyle="#ffffff",t.fillText(r,8,6.5),f(t,"#374151",8,16,s-8,4),f(t,n.primary,8,16,Math.round((s-8)*i/e.tasks.length),4)}function at(t,e,n,i,r){let s=e.cols*d;f(t,it,0,0,s,e.rows*d);for(let l of e.rooms)Ot(t,l,i);Lt(t,e,i);for(let l of e.furniture)l.type==="rug"&&st(t,l,e,n,i);let o=[];for(let l of e.furniture)l.type!=="rug"&&o.push({depth:(l.y+E[l.type].h)*d-2,draw:()=>st(t,l,e,n,i)});let a=e.agents.filter(l=>l.state!=="away");for(let l of a)o.push({depth:l.y*d+14,draw:()=>vt(t,l,n,l.id===r)});o.sort((l,h)=>l.depth-h.depth);for(let l of o)l.draw();Ft(t,e);for(let l of a)Bt(t,l,l.id===r,s);for(let l of a)l.id!==r&&Et(t,l,n);Pt(t,e,i);let u=a.find(l=>l.id===r);u&&Dt(t,u,s)}var $t=/^(#[0-9a-f]{3,8}|rgba?\([\d\s.,%/]+\)|hsla?\([\d\s.,%/a-z]+\))$/i;function Ht(t){let e=getComputedStyle(t),n=(i,r)=>{let s=e.getPropertyValue(i).trim();return $t.test(s)?s:r};return{primary:n("--blkc-color-primary","#3b82f6"),accent:n("--blkc-color-accent","#f59e0b"),background:n("--blkc-color-background","#1a1a2e"),text:n("--blkc-color-text","#ffffff")}}function H(t,e={},n={}){let i=B(e),r=t.getContext("2d");if(!r)throw new Error("This browser can't draw to a canvas.");let s=r,o=i.cols*d,a=i.rows*d,u=Ht(t),l=typeof matchMedia=="function"&&matchMedia("(prefers-reduced-motion: reduce)").matches,h,p=0,x=0,k=0,M=0,c=!0,b=!1,y=()=>{s.setTransform(p,0,0,p,0,0),s.imageSmoothingEnabled=!1,at(s,i,x,u,h)},T=()=>{let m=t.getBoundingClientRect().width||o,v=Math.max(1,Math.ceil(m*(typeof devicePixelRatio=="number"?devicePixelRatio:1)/o));v!==p&&(p=v,t.width=o*p,t.height=a*p,y())},U=m=>{if(b)return;if(M=requestAnimationFrame(U),!c){k=m;return}let g=Math.min((m-k)/1e3||0,.1);k=m,x+=g,D(i,g),y()},X=m=>{h=m===h?void 0:m,n.onSelect?.(h),l&&y()},G=m=>{let g=t.getBoundingClientRect();return{x:(m.clientX-g.left)/g.width*i.cols,y:(m.clientY-g.top)/g.height*i.rows}},K=m=>{let{x:g,y:v}=G(m);X(L(i,g,v)?.id)},j=m=>{let{x:g,y:v}=G(m);t.style.cursor=L(i,g,v)?"pointer":"default"};t.addEventListener("pointerdown",K),t.addEventListener("pointermove",j);let q=typeof ResizeObserver=="function"?new ResizeObserver(T):void 0;q?.observe(t);let z=typeof IntersectionObserver=="function"?new IntersectionObserver(m=>{c=m.some(g=>g.isIntersecting)}):void 0;return z?.observe(t),T(),p===0&&(p=1,y()),l||(M=requestAnimationFrame(U)),{world:i,update(m){P(i,m),l&&y()},select:X,destroy(){b=!0,cancelAnimationFrame(M),q?.disconnect(),z?.disconnect(),t.removeEventListener("pointerdown",K),t.removeEventListener("pointermove",j)}}}var lt=new Map;function Nt(t,e){lt.set(t,e)}function Ut(t,e,n){let i=[...n.querySelectorAll("button[data-blkc-agent]")],r=H(t,e,{onSelect(s){for(let o of i)o.setAttribute("aria-pressed",String(o.dataset.blkcAgent===s))}});for(let s of i)s.disabled=!1,s.addEventListener("click",()=>r.select(s.dataset.blkcAgent));return r}Nt("office",Ut);var ft=new WeakSet;function N(t=document){let e=[];for(let n of t.querySelectorAll("canvas[data-blkc-canvas]")){if(ft.has(n))continue;let i=lt.get(n.dataset.blkcCanvas??"");if(!i)continue;let r=n.closest("[data-blkc-canvas-root]")??n.parentElement??n,s=r.querySelector("script[data-blkc-canvas-data]"),o={};try{o=JSON.parse(s?.textContent||"{}")}catch{o={}}ft.add(n);let a=i(n,o,r);e.push({element:n,destroy:()=>a.destroy()})}return e}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>N()):N();})();
|
|
2
|
+
/**
|
|
3
|
+
* BLKC Render-Canvas.
|
|
4
|
+
*
|
|
5
|
+
* A canvas Block is ordinary markup from @blkc-code/render-web plus its data, and this
|
|
6
|
+
* package brings it to life. Call mountCanvasBlocks() once the page is in the document:
|
|
7
|
+
* a <canvas data-blkc-canvas="office"> with a JSON <script> beside it starts running.
|
|
8
|
+
*
|
|
9
|
+
* @package @blkc-code/render-canvas
|
|
10
|
+
* @license Apache-2.0
|
|
11
|
+
*/
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** What a Kit writes to describe an office. All of it is plain JSON. */
|
|
2
|
+
export type AgentState = "working" | "thinking" | "blocked" | "reviewing" | "idle" | "done" | "away";
|
|
3
|
+
export type TaskState = "todo" | "doing" | "done";
|
|
4
|
+
export type FloorStyle = "wood" | "carpet" | "tile";
|
|
5
|
+
export type FurnitureType = "desk" | "coffee" | "sofa" | "plant" | "board" | "shelf" | "server" | "table" | "rug" | "water";
|
|
6
|
+
export interface OfficeRoom {
|
|
7
|
+
id?: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
w: number;
|
|
12
|
+
h: number;
|
|
13
|
+
floor?: FloorStyle;
|
|
14
|
+
}
|
|
15
|
+
export interface OfficeDoor {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
}
|
|
19
|
+
export interface OfficeFurniture {
|
|
20
|
+
type: FurnitureType;
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
}
|
|
24
|
+
export interface OfficeAgent {
|
|
25
|
+
id: string;
|
|
26
|
+
name?: string;
|
|
27
|
+
role?: string;
|
|
28
|
+
state?: AgentState;
|
|
29
|
+
task?: string;
|
|
30
|
+
/** Character colours. Anything left out is picked from the id. */
|
|
31
|
+
hair?: string;
|
|
32
|
+
skin?: string;
|
|
33
|
+
shirt?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface OfficeTask {
|
|
36
|
+
title: string;
|
|
37
|
+
state?: TaskState;
|
|
38
|
+
agent?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface OfficeScene {
|
|
41
|
+
cols?: number;
|
|
42
|
+
rows?: number;
|
|
43
|
+
rooms?: OfficeRoom[];
|
|
44
|
+
doors?: OfficeDoor[];
|
|
45
|
+
furniture?: OfficeFurniture[];
|
|
46
|
+
agents?: OfficeAgent[];
|
|
47
|
+
tasks?: OfficeTask[];
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAExE,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AACrG,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAClD,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AACpD,MAAM,MAAM,aAAa,GACrB,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO,CAAC;AAEpG,MAAM,WAAW,UAAU;IAAG,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,UAAU,CAAA;CAAE;AAC1H,MAAM,WAAW,UAAU;IAAG,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE;AACpD,MAAM,WAAW,eAAe;IAAG,IAAI,EAAE,aAAa,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE;AAC9E,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,UAAU;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;AAEhF,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAC9B,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;CACtB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,wEAAwE"}
|
package/dist/world.d.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The office as data: which tiles can be walked on, who is where, and where they are
|
|
3
|
+
* heading. Nothing in here touches a canvas, so all of it can be tested.
|
|
4
|
+
*/
|
|
5
|
+
import type { AgentState, FloorStyle, FurnitureType, OfficeDoor, OfficeFurniture, OfficeRoom, OfficeScene, TaskState } from "./types.js";
|
|
6
|
+
export declare const MAX_COLS = 64;
|
|
7
|
+
export declare const MAX_ROWS = 40;
|
|
8
|
+
export declare const WALK_SPEED = 3.2;
|
|
9
|
+
/** Footprint in tiles, and where someone stands to use it, relative to its corner. */
|
|
10
|
+
export declare const FURNITURE: Record<FurnitureType, {
|
|
11
|
+
w: number;
|
|
12
|
+
h: number;
|
|
13
|
+
solid?: boolean;
|
|
14
|
+
spot?: {
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
};
|
|
18
|
+
}>;
|
|
19
|
+
export declare const DEFAULT_LAYOUT: {
|
|
20
|
+
cols: number;
|
|
21
|
+
rows: number;
|
|
22
|
+
rooms: OfficeRoom[];
|
|
23
|
+
doors: OfficeDoor[];
|
|
24
|
+
furniture: OfficeFurniture[];
|
|
25
|
+
};
|
|
26
|
+
export interface Room {
|
|
27
|
+
name: string;
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
w: number;
|
|
31
|
+
h: number;
|
|
32
|
+
floor: FloorStyle;
|
|
33
|
+
}
|
|
34
|
+
export interface Item {
|
|
35
|
+
type: FurnitureType;
|
|
36
|
+
x: number;
|
|
37
|
+
y: number;
|
|
38
|
+
}
|
|
39
|
+
export interface Task {
|
|
40
|
+
title: string;
|
|
41
|
+
state: TaskState;
|
|
42
|
+
agent: string;
|
|
43
|
+
}
|
|
44
|
+
export interface Agent {
|
|
45
|
+
id: string;
|
|
46
|
+
name: string;
|
|
47
|
+
role: string;
|
|
48
|
+
state: AgentState;
|
|
49
|
+
task: string;
|
|
50
|
+
hair: string;
|
|
51
|
+
skin: string;
|
|
52
|
+
shirt: string;
|
|
53
|
+
/** Position in tiles; x/y is the tile the feet are on. */
|
|
54
|
+
x: number;
|
|
55
|
+
y: number;
|
|
56
|
+
path: {
|
|
57
|
+
x: number;
|
|
58
|
+
y: number;
|
|
59
|
+
}[];
|
|
60
|
+
facing: "up" | "down" | "left" | "right";
|
|
61
|
+
walking: boolean;
|
|
62
|
+
seat?: {
|
|
63
|
+
x: number;
|
|
64
|
+
y: number;
|
|
65
|
+
};
|
|
66
|
+
/** Seconds until an idle agent picks somewhere new. */
|
|
67
|
+
rest: number;
|
|
68
|
+
seed: number;
|
|
69
|
+
}
|
|
70
|
+
export interface World {
|
|
71
|
+
cols: number;
|
|
72
|
+
rows: number;
|
|
73
|
+
rooms: Room[];
|
|
74
|
+
doors: OfficeDoor[];
|
|
75
|
+
furniture: Item[];
|
|
76
|
+
agents: Agent[];
|
|
77
|
+
tasks: Task[];
|
|
78
|
+
walkable: boolean[];
|
|
79
|
+
spots: {
|
|
80
|
+
lounge: {
|
|
81
|
+
x: number;
|
|
82
|
+
y: number;
|
|
83
|
+
}[];
|
|
84
|
+
board: {
|
|
85
|
+
x: number;
|
|
86
|
+
y: number;
|
|
87
|
+
}[];
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
export declare function hash(text: string): number;
|
|
91
|
+
export declare function isWalkable(world: World, x: number, y: number): boolean;
|
|
92
|
+
/** Shortest walk between two tiles, or null if they aren't connected. Excludes the start. */
|
|
93
|
+
export declare function findPath(world: World, from: {
|
|
94
|
+
x: number;
|
|
95
|
+
y: number;
|
|
96
|
+
}, to: {
|
|
97
|
+
x: number;
|
|
98
|
+
y: number;
|
|
99
|
+
}): {
|
|
100
|
+
x: number;
|
|
101
|
+
y: number;
|
|
102
|
+
}[] | null;
|
|
103
|
+
/** Build a world from a scene. Bad values are dropped or clamped, so it never throws. */
|
|
104
|
+
export declare function createWorld(scene?: OfficeScene): World;
|
|
105
|
+
/** Where this agent's current state wants them to be. */
|
|
106
|
+
export declare function goalFor(world: World, agent: Agent): {
|
|
107
|
+
x: number;
|
|
108
|
+
y: number;
|
|
109
|
+
} | undefined;
|
|
110
|
+
export declare const isSeated: (agent: Agent) => boolean;
|
|
111
|
+
/** Advance the whole office by `dt` seconds. */
|
|
112
|
+
export declare function step(world: World, dt: number): void;
|
|
113
|
+
/** Change what people are doing without restarting them. New agents appear at their goal. */
|
|
114
|
+
export declare function applyUpdate(world: World, scene: Pick<OfficeScene, "agents" | "tasks">): void;
|
|
115
|
+
/** Agent under a point given in tiles, nearest first. */
|
|
116
|
+
export declare function agentAt(world: World, x: number, y: number): Agent | undefined;
|
|
117
|
+
//# sourceMappingURL=world.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"world.d.ts","sourceRoot":"","sources":["../src/world.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAe,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,EAAc,SAAS,EAAE,MAAM,YAAY,CAAC;AAElK,eAAO,MAAM,QAAQ,KAAK,CAAC;AAC3B,eAAO,MAAM,QAAQ,KAAK,CAAC;AAI3B,eAAO,MAAM,UAAU,MAAM,CAAC;AAE9B,sFAAsF;AACtF,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,aAAa,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAWvH,CAAC;AAMF,eAAO,MAAM,cAAc;;;WAOpB,UAAU,EAAE;WAC8C,UAAU,EAAE;eAQtE,eAAe,EAAE;CACvB,CAAC;AAMF,MAAM,WAAW,IAAI;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE;AACrG,MAAM,WAAW,IAAI;IAAG,IAAI,EAAE,aAAa,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE;AACnE,MAAM,WAAW,IAAI;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AAExE,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjC,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChC,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,SAAS,EAAE,IAAI,EAAE,CAAC;IAClB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE;QAAE,MAAM,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAAC,KAAK,EAAE;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAAE,CAAC;CAClF;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIzC;AAYD,wBAAgB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED,6FAA6F;AAC7F,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,EAAE,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,IAAI,CA6BtI;AA6BD,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,KAAK,GAAE,WAAgB,GAAG,KAAK,CAiE1D;AAOD,yDAAyD;AACzD,wBAAgB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAgBxF;AAYD,eAAO,MAAM,QAAQ,GAAI,OAAO,KAAK,KAAG,OAEqE,CAAC;AAQ9G,gDAAgD;AAChD,wBAAgB,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAmCnD;AAED,6FAA6F;AAC7F,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,IAAI,CAuB5F;AAED,yDAAyD;AACzD,wBAAgB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAc7E"}
|