@mocklane/core 1.0.1 → 1.0.2
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/build/client/assets/home-BctYtJJe.js +178 -0
- package/build/client/assets/{manifest-08a95dab.js → manifest-cfa23094.js} +1 -1
- package/build/client/assets/{root-Di4etcLz.css → root-C9U4kG7U.css} +1 -1
- package/build/client/index.html +3 -3
- package/package.json +1 -1
- package/build/client/assets/home-CHNZ1EXV.js +0 -178
- /package/build/client/assets/{root-Dlix2DV-.js → root-BlLsNrT5.js} +0 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import{r as c,j as a,w as Mt}from"./jsx-runtime-BZbza59V.js";/**
|
|
2
|
+
* @license lucide-react v1.17.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const Ke=(...e)=>e.filter((t,r,n)=>!!t&&t.trim()!==""&&n.indexOf(t)===r).join(" ").trim();/**
|
|
7
|
+
* @license lucide-react v1.17.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const Ct=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase();/**
|
|
12
|
+
* @license lucide-react v1.17.0 - ISC
|
|
13
|
+
*
|
|
14
|
+
* This source code is licensed under the ISC license.
|
|
15
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
+
*/const Lt=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(t,r,n)=>n?n.toUpperCase():r.toLowerCase());/**
|
|
17
|
+
* @license lucide-react v1.17.0 - ISC
|
|
18
|
+
*
|
|
19
|
+
* This source code is licensed under the ISC license.
|
|
20
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
21
|
+
*/const Je=e=>{const t=Lt(e);return t.charAt(0).toUpperCase()+t.slice(1)};/**
|
|
22
|
+
* @license lucide-react v1.17.0 - ISC
|
|
23
|
+
*
|
|
24
|
+
* This source code is licensed under the ISC license.
|
|
25
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
26
|
+
*/var me={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};/**
|
|
27
|
+
* @license lucide-react v1.17.0 - ISC
|
|
28
|
+
*
|
|
29
|
+
* This source code is licensed under the ISC license.
|
|
30
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
31
|
+
*/const At=e=>{for(const t in e)if(t.startsWith("aria-")||t==="role"||t==="title")return!0;return!1},Tt=c.createContext({}),Ot=()=>c.useContext(Tt),Et=c.forwardRef(({color:e,size:t,strokeWidth:r,absoluteStrokeWidth:n,className:i="",children:l,iconNode:d,...o},u)=>{const{size:p=24,strokeWidth:y=2,absoluteStrokeWidth:h=!1,color:g="currentColor",className:b=""}=Ot()??{},j=n??h?Number(r??y)*24/Number(t??p):r??y;return c.createElement("svg",{ref:u,...me,width:t??p??me.width,height:t??p??me.height,stroke:e??g,strokeWidth:j,className:Ke("lucide",b,i),...!l&&!At(o)&&{"aria-hidden":"true"},...o},[...d.map(([se,W])=>c.createElement(se,W)),...Array.isArray(l)?l:[l]])});/**
|
|
32
|
+
* @license lucide-react v1.17.0 - ISC
|
|
33
|
+
*
|
|
34
|
+
* This source code is licensed under the ISC license.
|
|
35
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
36
|
+
*/const v=(e,t)=>{const r=c.forwardRef(({className:n,...i},l)=>c.createElement(Et,{ref:l,iconNode:t,className:Ke(`lucide-${Ct(Je(e))}`,`lucide-${e}`,n),...i}));return r.displayName=Je(e),r};/**
|
|
37
|
+
* @license lucide-react v1.17.0 - ISC
|
|
38
|
+
*
|
|
39
|
+
* This source code is licensed under the ISC license.
|
|
40
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
41
|
+
*/const It=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],Pt=v("check",It);/**
|
|
42
|
+
* @license lucide-react v1.17.0 - ISC
|
|
43
|
+
*
|
|
44
|
+
* This source code is licensed under the ISC license.
|
|
45
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
46
|
+
*/const _t=[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]],De=v("chevron-down",_t);/**
|
|
47
|
+
* @license lucide-react v1.17.0 - ISC
|
|
48
|
+
*
|
|
49
|
+
* This source code is licensed under the ISC license.
|
|
50
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
51
|
+
*/const $t=[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]],Rt=v("copy",$t);/**
|
|
52
|
+
* @license lucide-react v1.17.0 - ISC
|
|
53
|
+
*
|
|
54
|
+
* This source code is licensed under the ISC license.
|
|
55
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
56
|
+
*/const St=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],Jt=v("download",St);/**
|
|
57
|
+
* @license lucide-react v1.17.0 - ISC
|
|
58
|
+
*
|
|
59
|
+
* This source code is licensed under the ISC license.
|
|
60
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
61
|
+
*/const Dt=[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]],Gt=v("loader-circle",Dt);/**
|
|
62
|
+
* @license lucide-react v1.17.0 - ISC
|
|
63
|
+
*
|
|
64
|
+
* This source code is licensed under the ISC license.
|
|
65
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
66
|
+
*/const Wt=[["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]],Bt=v("moon",Wt);/**
|
|
67
|
+
* @license lucide-react v1.17.0 - ISC
|
|
68
|
+
*
|
|
69
|
+
* This source code is licensed under the ISC license.
|
|
70
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
71
|
+
*/const Ut=[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]],zt=v("pencil",Ut);/**
|
|
72
|
+
* @license lucide-react v1.17.0 - ISC
|
|
73
|
+
*
|
|
74
|
+
* This source code is licensed under the ISC license.
|
|
75
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
76
|
+
*/const Ft=[["path",{d:"M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z",key:"goz73y"}],["path",{d:"m2 22 3-3",key:"19mgm9"}],["path",{d:"M7.5 13.5 10 11",key:"7xgeeb"}],["path",{d:"M10.5 16.5 13 14",key:"10btkg"}],["path",{d:"m18 3-4 4h6l-4 4",key:"16psg9"}]],qt=v("plug-zap",Ft);/**
|
|
77
|
+
* @license lucide-react v1.17.0 - ISC
|
|
78
|
+
*
|
|
79
|
+
* This source code is licensed under the ISC license.
|
|
80
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
81
|
+
*/const Ht=[["path",{d:"M12 22v-5",key:"1ega77"}],["path",{d:"M15 8V2",key:"18g5xt"}],["path",{d:"M17 8a1 1 0 0 1 1 1v4a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V9a1 1 0 0 1 1-1z",key:"1xoxul"}],["path",{d:"M9 8V2",key:"14iosj"}]],Ge=v("plug",Ht);/**
|
|
82
|
+
* @license lucide-react v1.17.0 - ISC
|
|
83
|
+
*
|
|
84
|
+
* This source code is licensed under the ISC license.
|
|
85
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
86
|
+
*/const Vt=[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]],Kt=v("save",Vt);/**
|
|
87
|
+
* @license lucide-react v1.17.0 - ISC
|
|
88
|
+
*
|
|
89
|
+
* This source code is licensed under the ISC license.
|
|
90
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
91
|
+
*/const Qt=[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"m4.93 4.93 1.41 1.41",key:"149t6j"}],["path",{d:"m17.66 17.66 1.41 1.41",key:"ptbguv"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"m6.34 17.66-1.41 1.41",key:"1m8zz5"}],["path",{d:"m19.07 4.93-1.41 1.41",key:"1shlcs"}]],Zt=v("sun",Qt);/**
|
|
92
|
+
* @license lucide-react v1.17.0 - ISC
|
|
93
|
+
*
|
|
94
|
+
* This source code is licensed under the ISC license.
|
|
95
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
96
|
+
*/const Xt=[["path",{d:"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72",key:"ul74o6"}],["path",{d:"m14 7 3 3",key:"1r5n42"}],["path",{d:"M5 6v4",key:"ilb8ba"}],["path",{d:"M19 14v4",key:"blhpug"}],["path",{d:"M10 2v2",key:"7u0qdc"}],["path",{d:"M7 8H3",key:"zfb6yr"}],["path",{d:"M21 16h-4",key:"1cnmox"}],["path",{d:"M11 3H9",key:"1obp7u"}]],Yt=v("wand-sparkles",Xt);/**
|
|
97
|
+
* @license lucide-react v1.17.0 - ISC
|
|
98
|
+
*
|
|
99
|
+
* This source code is licensed under the ISC license.
|
|
100
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
101
|
+
*/const er=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],tr=v("x",er);function We({id:e,label:t,meta:r,value:n,onChange:i,placeholder:l,spellCheck:d=!0,variant:o="default"}){return a.jsxs("div",{className:`field-group ${o==="compact"?"prompt-group":""}`,children:[a.jsxs("div",{className:"field-heading",children:[a.jsx("label",{htmlFor:e,children:t}),a.jsx("span",{children:r})]}),a.jsx("textarea",{id:e,value:n,spellCheck:d,placeholder:l,onChange:u=>i(u.target.value)})]})}const rr="modulepreload",ar=function(e){return"/"+e},Be={},Qe=function(t,r,n){let i=Promise.resolve();if(r&&r.length>0){let d=function(p){return Promise.all(p.map(y=>Promise.resolve(y).then(h=>({status:"fulfilled",value:h}),h=>({status:"rejected",reason:h}))))};document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),u=(o==null?void 0:o.nonce)||(o==null?void 0:o.getAttribute("nonce"));i=d(r.map(p=>{if(p=ar(p),p in Be)return;Be[p]=!0;const y=p.endsWith(".css"),h=y?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${p}"]${h}`))return;const g=document.createElement("link");if(g.rel=y?"stylesheet":rr,y||(g.as="script"),g.crossOrigin="",g.href=p,u&&g.setAttribute("nonce",u),document.head.appendChild(g),y)return new Promise((b,j)=>{g.addEventListener("load",b),g.addEventListener("error",()=>j(new Error(`Unable to preload CSS for ${p}`)))})}))}function l(d){const o=new Event("vite:preloadError",{cancelable:!0});if(o.payload=d,window.dispatchEvent(o),!o.defaultPrevented)throw d}return i.then(d=>{for(const o of d||[])o.status==="rejected"&&l(o.reason);return t().catch(l)})},x="Qwen2.5-0.5B-Instruct-q4f16_1-MLC",nr=5e4;let E=null,N=null,ke=!1;function ve(){return typeof navigator>"u"?{available:!1,label:"WebLLM unavailable"}:"gpu"in navigator?N?{available:!0,label:"WebLLM ready",detail:x}:E?{available:!0,label:"WebLLM warming up",detail:x}:ke?{available:!1,label:"WebLLM unavailable",detail:"WebLLM failed to load."}:{available:!0,label:"WebLLM available",detail:x}:{available:!1,label:"WebLLM unavailable",detail:"WebGPU is unavailable in this browser."}}function sr(e,t={}){if(!(!ve().available||E)){if(N&&!t.reload){e==null||e({available:!0,label:"WebLLM ready",detail:x});return}e==null||e({available:!0,label:"WebLLM warming up",detail:x}),ke=!1,E=lr(e).then(r=>(N=r,E=null,e==null||e({available:!0,label:"WebLLM ready",detail:x}),r)),E.catch(r=>{ke=!0,E=null,e==null||e({available:!1,label:"WebLLM unavailable",detail:r instanceof Error?r.message:"WebLLM failed to load."})})}}async function ir({model:e,prompt:t,onStatus:r}){var n;if(!N)return null;r==null||r({available:!0,label:"Generating locally",detail:x});try{const l=(n=(await N.chat.completions.create({messages:[{role:"system",content:Ze()},{role:"user",content:Xe({model:e,prompt:t})}],max_tokens:nr,temperature:.2,top_p:.9})).choices[0])==null?void 0:n.message.content;if(!l)return{message:"The local model returned an empty response.",promptOutput:""};try{const d=et(Ye(l),t);return JSON.parse(d)}catch{return{message:"The local model returned text that could not be parsed as JSON.",promptOutput:l}}}finally{r==null||r({available:!0,label:"WebLLM ready",detail:x})}}async function lr(e){if(N)return N.setInitProgressCallback(r=>{e==null||e({available:!0,label:"Loading local model",detail:Ue(r)})}),await N.reload(x),N;const{CreateMLCEngine:t}=await Qe(async()=>{const{CreateMLCEngine:r}=await import("./index-D9gteTdx.js");return{CreateMLCEngine:r}},[]);return t(x,{initProgressCallback:r=>{e==null||e({available:!0,label:"Loading local model",detail:Ue(r)})}})}function Ue(e){return`${Math.round(e.progress*100)}% ${e.text}`}function Ze(){return`You are Mocklane, a focused mock HTTP API response generator.
|
|
102
|
+
|
|
103
|
+
Rules:
|
|
104
|
+
- Only generate mock HTTP API JSON responses.
|
|
105
|
+
- Always return one raw valid JSON object.
|
|
106
|
+
- Do not use markdown, comments, explanations, or code fences.
|
|
107
|
+
- Do not include <think> blocks, hidden reasoning, or analysis.
|
|
108
|
+
- Do not wrap the JSON in a string field such as "promptOutput".
|
|
109
|
+
- Keep the response compact.
|
|
110
|
+
- Use realistic but fake values.
|
|
111
|
+
- Never include real secrets, real personal data, or explanatory text.
|
|
112
|
+
|
|
113
|
+
If the request is unrelated to mock APIs, mock endpoints, mock responses, or mock data, return exactly:
|
|
114
|
+
{"message":"My job is to make mock APIs. Drop a model or structure, then ask me for an endpoint response and I can help you."}
|
|
115
|
+
|
|
116
|
+
For mock API requests, return this object shape:
|
|
117
|
+
{"method":"GET","path":"/api/resource","status":200,"headers":{"content-type":"application/json"},"body":[{"resourcePlural":[...items]}]}
|
|
118
|
+
|
|
119
|
+
Response rules:
|
|
120
|
+
- If the user asks for N items, generate exactly N items. Never generate fewer. Never generate more.
|
|
121
|
+
- Infer body fields from the supplied model, schema, example, or structure.
|
|
122
|
+
- Infer method, path, status, count, and data theme from the user request.
|
|
123
|
+
- Default to method "GET" and status 200 unless the request clearly implies another method or status.
|
|
124
|
+
- If count is not specified, generate 3 items.
|
|
125
|
+
- The body must always be an array containing exactly one object.
|
|
126
|
+
- That one object must have exactly one plural lower-camel-case key for the resource collection, such as "products", "customers", "orders", or "supportTickets".
|
|
127
|
+
- The value of that plural key must be an array of generated objects.
|
|
128
|
+
- Preserve sensible data types from the supplied model.
|
|
129
|
+
- Use ISO-like date strings when generating dates.
|
|
130
|
+
- Use integer cents for fields ending in "Cents", such as "priceCents": 4999.
|
|
131
|
+
|
|
132
|
+
Example body shape:
|
|
133
|
+
{"body":[{"products":[{"id":"101","sku":"ABC-123","name":"Product A","category":"Electronics","priceCents":4999,"currency":"USD","inventoryCount":10,"rating":5,"tags":["Electronics","Tech"]}]}]}`}function Xe({model:e,prompt:t}){return`Model / Structure:
|
|
134
|
+
${e}
|
|
135
|
+
|
|
136
|
+
Prompt:
|
|
137
|
+
${t}`}function or(e){const t=e.trim();if(t.startsWith("{")&&t.endsWith("}"))return t;const r=t.indexOf("{"),n=t.lastIndexOf("}");if(r===-1||n===-1||n<=r)throw new Error("Local model did not return a JSON object.");return t.slice(r,n+1)}function Ye(e){const r=e.replace(/<think>[\s\S]*?<\/think>/gi,"").trim().replace(/^```(?:json)?\s*/i,"").replace(/\s*```$/i,"").trim();return cr(r)??or(r)}function cr(e){const t=ze(e,"{","}");if(t)return ee(t);const r=ze(e,"[","]");return r?ee(r):null}function ze(e,t,r){const n=e.indexOf(t);if(n===-1)return null;let i=0,l=!1,d=!1;for(let o=n;o<e.length;o+=1){const u=e[o];if(l){d?d=!1:u==="\\"?d=!0:u==='"'&&(l=!1);continue}if(u==='"')l=!0;else if(u===t)i+=1;else if(u===r&&(i-=1,i===0))return e.slice(n,o+1)}return null}function ee(e){try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}function et(e,t){const r=dr(t);if(!r||!/product/i.test(t))return e;try{const n=JSON.parse(e),i=ur(n);if(i.length===r)return ee(JSON.stringify(Fe(i)));const l=i[0]??pr(n),d=Array.from({length:r},(o,u)=>fr(l,u+1));return ee(JSON.stringify(Fe(d)))}catch{return e}}function dr(e){const t=e.match(/id\s+(\d+)\s*(?:to|-)\s*(\d+)/i);if(t){const i=Number(t[1]),l=Number(t[2]);if(Number.isFinite(i)&&Number.isFinite(l)&&l>=i)return l-i+1}const r=e.match(/(?:exactly\s+)?(\d+)\s+(?:productmodel\s+)?items?/i);if(!r)return null;const n=Number(r[1]);return Number.isFinite(n)&&n>0?n:null}function ur(e){if(!C(e))return[];if(Array.isArray(e.products))return e.products.filter(C);const t=Array.isArray(e.body)?e.body[0]:null;return C(t)&&Array.isArray(t.products)?t.products.filter(C):Array.isArray(e.body)?e.body.filter(te):te(e)?[e]:[]}function pr(e){if(!C(e))return null;const t=Array.isArray(e.body)?e.body[0]:null;return te(t)?t:te(e)?e:null}function Fe(e){return{method:"GET",path:"/api/products",status:200,headers:{"content-type":"application/json"},body:[{products:e}]}}function fr(e,t){var l;const r=["electronics","home","apparel","books"],n=["Laptop","Desk Lamp","Cotton Hoodie","Notebook Set","Wireless Mouse","Ceramic Mug","Running Shirt","Cookbook","Bluetooth Speaker","Storage Basket"],i=r[(t-1)%r.length];return{id:String(t),sku:`SKU-${String(t).padStart(3,"0")}`,name:n[t-1]??`Product ${t}`,category:i,priceCents:we(e==null?void 0:e.priceCents,1999)+(t-1)*250,currency:"USD",inventoryCount:Math.max(0,we(e==null?void 0:e.inventoryCount,100)-(t-1)*3),rating:Math.min(5,Math.round((4.1+t%5*.2)*10)/10),tags:[i,((l=n[t-1])==null?void 0:l.toLowerCase().replaceAll(" ","-"))??`product-${t}`],dimensions:{widthCm:be(e,"widthCm",20+t),heightCm:be(e,"heightCm",10+t),depthCm:be(e,"depthCm",5+t)},createdAt:`2023-04-${String(t).padStart(2,"0")}T00:00:00Z`}}function we(e,t){return typeof e=="number"&&Number.isFinite(e)?e:t}function be(e,t,r){const n=C(e==null?void 0:e.dimensions)?e.dimensions:null;return we(n==null?void 0:n[t],r)}function te(e){return C(e)&&"id"in e&&"sku"in e&&"name"in e&&"priceCents"in e&&"dimensions"in e}function C(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function mr(){return tt()?{available:!0,label:"Native Browser AI available",detail:"Gemini Nano"}:{available:!1,label:"Native Browser AI unavailable",detail:"The LanguageModel API is unavailable in this browser."}}async function br({model:e,prompt:t,onStatus:r}){var d;const n=tt();if(!n)return null;r==null||r({available:!0,label:"Native Browser AI preparing",detail:"Checking Gemini Nano availability..."});const i=Ze();let l;try{if((n.factory.availability?await n.factory.availability():"available")==="unavailable")throw new Error("The browser reports that Gemini Nano is unavailable.");l=await n.factory.create({...n.kind==="current"?{initialPrompts:[{role:"system",content:i}]}:{systemPrompt:i},monitor(u){u.addEventListener("downloadprogress",p=>{r==null||r({available:!0,label:"Native Browser AI preparing",detail:`Downloading Gemini Nano: ${Math.round(p.loaded*100)}%`})})}})}catch(o){throw r==null||r({available:!0,label:"Native Browser AI available",detail:o instanceof Error?o.message:"Gemini Nano failed to start."}),o}r==null||r({available:!0,label:"Generating with Native Browser AI",detail:"Gemini Nano"});try{const o=await l.prompt(Xe({model:e,prompt:t})),u=Ye(o),p=et(hr(u),t);try{return JSON.parse(p)}catch{return{message:"Native Browser AI returned text that could not be parsed as JSON.",promptOutput:o}}}finally{(d=l.destroy)==null||d.call(l),r==null||r({available:!0,label:"Native Browser AI available",detail:"Gemini Nano"})}}function hr(e){const t=e.trim(),r=[];let n=!1,i=!1;for(const d of t){if(n){i?i=!1:d==="\\"?i=!0:d==='"'&&(n=!1);continue}if(d==='"')n=!0;else if(d==="{")r.push("}");else if(d==="[")r.push("]");else if(d==="}"||d==="]"){if(r.at(-1)!==d)return e;r.pop()}}if(n||r.length===0)return e;const l=`${t}${r.reverse().join("")}`;try{return JSON.parse(l),l}catch{return e}}function tt(){var t;if(typeof window>"u")return null;const e=window;return e.LanguageModel?{factory:e.LanguageModel,kind:"current"}:(t=e.ai)!=null&&t.languageModel?{factory:e.ai.languageModel,kind:"legacy"}:null}const P=[{id:"onnx-community/Qwen3-0.6B-ONNX",label:"Qwen3 0.6B",detail:"Current baseline",dtype:"q4f16"},{id:"onnx-community/gemma-3-1b-it-ONNX-GQA",label:"Gemma 3 1B Instruct",detail:"Google alternative",dtype:"q4"}],je=P[0].id,yr=5e4,gr=`You are Mocklane, a JSON-only mock HTTP API response generator.
|
|
138
|
+
Return exactly one raw valid JSON object.
|
|
139
|
+
Do not include markdown, code fences, comments, explanations, analysis, or <think> blocks.
|
|
140
|
+
Do not reveal chain-of-thought or hidden reasoning.
|
|
141
|
+
|
|
142
|
+
For mock API requests, always return this response shape:
|
|
143
|
+
{"method":"GET","path":"/api/products","status":200,"headers":{"content-type":"application/json"},"body":[{"products":[]}]}
|
|
144
|
+
|
|
145
|
+
Rules:
|
|
146
|
+
- If the user asks for N items, generate exactly N items.
|
|
147
|
+
- If the user gives an id range, include every id in that range exactly once.
|
|
148
|
+
- For GET all product requests, body must be an array containing one object with a plural collection array.
|
|
149
|
+
- Preserve field names and sensible data types from the supplied model.
|
|
150
|
+
- Use string ids.
|
|
151
|
+
- Use integer cents for fields ending in Cents.
|
|
152
|
+
- Use ISO-like strings for date fields.
|
|
153
|
+
- Do not return a single item object unless the user explicitly asks for one item.`;let I=null,L=null,xe=!1,G=null,X=null;function Z(e=je){return typeof navigator>"u"?{available:!1,label:"Transformers.js unavailable"}:"gpu"in navigator?L&&G===e?{available:!0,label:"Transformers.js ready",detail:e}:I?{available:!0,label:"Transformers.js warming up",detail:X??e}:xe?{available:!1,label:"Transformers.js unavailable",detail:"Transformers.js failed to load."}:{available:!0,label:"Transformers.js available",detail:e}:{available:!1,label:"Transformers.js unavailable",detail:"WebGPU is unavailable in this browser."}}function kr(e,t={}){const r=Nr(t.modelId);if(typeof navigator>"u"||!("gpu"in navigator)||I)return;if(L&&G===r.id&&!t.reload){e==null||e({available:!0,label:"Transformers.js ready",detail:r.id});return}e==null||e({available:!0,label:"Transformers.js warming up",detail:r.id}),xe=!1,X=r.id;const n=L;L=null,G=null,I=xr(r.id).then(i=>wr(n,r,i,e)).then(i=>(L=i,G=r.id,X=null,I=null,e==null||e({available:!0,label:"Transformers.js ready",detail:r.id}),i)),I.catch(i=>{xe=!0,I=null,X=null,e==null||e({available:!1,label:"Transformers.js unavailable",detail:i instanceof Error?i.message:"Transformers.js failed to load."})})}async function vr({model:e,prompt:t,modelId:r=je,onStatus:n}){if(!L||G!==r)return null;n==null||n({available:!0,label:"Generating with Transformers.js",detail:r});try{const i=await L([{role:"system",content:gr},{role:"user",content:jr({model:e,prompt:t})}],{max_new_tokens:yr,do_sample:!1,return_full_text:!1,tokenizer_encode_kwargs:{enable_thinking:!1}}),l=Ar(Cr(i),t);try{return JSON.parse(l)}catch{return{message:"Transformers.js returned text that could not be parsed as JSON.",promptOutput:l}}}finally{n==null||n({available:!0,label:"Transformers.js ready",detail:r})}}async function wr(e,t,r,n){e&&await e.dispose();const{pipeline:i}=await Qe(async()=>{const{pipeline:l}=await import("./transformers.web-CjIQtwg9.js");return{pipeline:l}},[]);return i("text-generation",t.id,{device:"webgpu",dtype:t.dtype,progress_callback:l=>{n==null||n({available:!0,label:"Loading Transformers.js",detail:`${Mr(l)} - ${r?"Cache Load":"First Load"}`})}})}async function xr(e){if(!("caches"in globalThis))return!1;const t=e.split("/").at(-1),r=await caches.keys();for(const n of r)if((await(await caches.open(n)).keys()).some(l=>l.url.includes(e)||l.url.includes(t??e)))return!0;return!1}function Nr(e){return P.find(t=>t.id===e)??P[0]}function jr({model:e,prompt:t}){return`Model / Structure:
|
|
154
|
+
${e}
|
|
155
|
+
|
|
156
|
+
Prompt:
|
|
157
|
+
${t}`}function Mr(e){if(!e||typeof e!="object")return"Loading Transformers.js model";const t=e;return typeof t.progress=="number"?`${Math.round(t.progress)}% ${t.file??t.name??"model file"}`:typeof t.loaded=="number"&&typeof t.total=="number"?`${Math.round(t.loaded/t.total*100)}% ${t.file??t.name??"model file"}`:t.status??"Loading Transformers.js model"}function Cr(e){const t=Array.isArray(e)?e[0]:null;if(!t||typeof t!="object"||!("generated_text"in t))return JSON.stringify(e,null,2);const r=t.generated_text;if(typeof r=="string")return he(r);if(Array.isArray(r)){const n=r.at(-1);if(n&&typeof n=="object"&&"content"in n)return he(String(n.content??""))}return he(JSON.stringify(r,null,2))}function he(e){const r=e.replace(/<think>[\s\S]*?<\/think>/gi,"").trim().replace(/^```(?:json)?\s*/i,"").replace(/\s*```$/i,"").trim();return Lr(r)??r}function Lr(e){const t=qe(e,"{","}");if(t)return re(t);const r=qe(e,"[","]");return r?re(r):null}function qe(e,t,r){const n=e.indexOf(t);if(n===-1)return null;let i=0,l=!1,d=!1;for(let o=n;o<e.length;o+=1){const u=e[o];if(l){d?d=!1:u==="\\"?d=!0:u==='"'&&(l=!1);continue}if(u==='"')l=!0;else if(u===t)i+=1;else if(u===r&&(i-=1,i===0))return e.slice(n,o+1)}return null}function re(e){try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}function Ar(e,t){const r=Tr(t);if(!r||!/product/i.test(t))return e;try{const n=JSON.parse(e),i=Or(n);if(i.length===r)return re(JSON.stringify(He(i)));const l=i[0]??Er(n),d=Array.from({length:r},(o,u)=>Ir(l,u+1));return re(JSON.stringify(He(d)))}catch{return e}}function Tr(e){const t=e.match(/id\s+(\d+)\s*(?:to|-)\s*(\d+)/i);if(t){const i=Number(t[1]),l=Number(t[2]);if(Number.isFinite(i)&&Number.isFinite(l)&&l>=i)return l-i+1}const r=e.match(/(?:exactly\s+)?(\d+)\s+(?:productmodel\s+)?items?/i);if(!r)return null;const n=Number(r[1]);return Number.isFinite(n)&&n>0?n:null}function Or(e){if(!A(e))return[];if(Array.isArray(e.products))return e.products.filter(A);const t=Array.isArray(e.body)?e.body[0]:null;return A(t)&&Array.isArray(t.products)?t.products.filter(A):Array.isArray(e.body)?e.body.filter(ae):ae(e)?[e]:[]}function Er(e){if(!A(e))return null;const t=Array.isArray(e.body)?e.body[0]:null;return ae(t)?t:ae(e)?e:null}function He(e){return{method:"GET",path:"/api/products",status:200,headers:{"content-type":"application/json"},body:[{products:e}]}}function Ir(e,t){var l;const r=["electronics","home","apparel","books"],n=["Laptop","Desk Lamp","Cotton Hoodie","Notebook Set","Wireless Mouse","Ceramic Mug","Running Shirt","Cookbook","Bluetooth Speaker","Storage Basket"],i=r[(t-1)%r.length];return{id:String(t),sku:`SKU-${String(t).padStart(3,"0")}`,name:n[t-1]??`Product ${t}`,category:i,priceCents:Ne(e==null?void 0:e.priceCents,1999)+(t-1)*250,currency:"USD",inventoryCount:Math.max(0,Ne(e==null?void 0:e.inventoryCount,100)-(t-1)*3),rating:Math.min(5,Math.round((4.1+t%5*.2)*10)/10),tags:[i,((l=n[t-1])==null?void 0:l.toLowerCase().replaceAll(" ","-"))??`product-${t}`],dimensions:{widthCm:ye(e,"widthCm",20+t),heightCm:ye(e,"heightCm",10+t),depthCm:ye(e,"depthCm",5+t)},createdAt:`2023-04-${String(t).padStart(2,"0")}T00:00:00Z`}}function Ne(e,t){return typeof e=="number"&&Number.isFinite(e)?e:t}function ye(e,t,r){const n=A(e==null?void 0:e.dimensions)?e.dimensions:null;return Ne(n==null?void 0:n[t],r)}function ae(e){return A(e)&&"id"in e&&"sku"in e&&"name"in e&&"priceCents"in e&&"dimensions"in e}function A(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}const rt="/__mocklane/mocks";let Y=null;async function Pr(e){const t=await fetch(rt,{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify(e)});await at(t),Y=e}async function ge(){if(!Y)return;const e=await fetch(rt,{method:"DELETE",headers:{"content-type":"application/json"},body:JSON.stringify(Y)});await at(e),Y=null}function O(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;const t=e;return typeof t.method=="string"&&typeof t.path=="string"&&typeof t.status=="number"&&!!t.headers&&typeof t.headers=="object"&&!Array.isArray(t.headers)&&"body"in t}async function at(e){if(e.ok)return;const t=await e.json().catch(()=>null);throw new Error((t==null?void 0:t.error)??"Mocklane local CLI is unavailable.")}const _r="My job is to make mock APIs. Drop a model or structure, then ask me for an endpoint response and I can help you.",$r="The selected local model is still warming up or unavailable. Mocklane will not manually fabricate this response; try again when the model is ready.",Rr="The local model responded, but Mocklane could not turn it into a valid mock API JSON response. Try a smaller request or ask for fewer items.";async function Sr({model:e,prompt:t,provider:r="webllm",transformersModelId:n,onStatus:i}){if(!e.trim()||!t.trim())return{message:_r};try{const l=r==="transformers"?await vr({model:e,prompt:t,modelId:n,onStatus:i}):r==="native"?await br({model:e,prompt:t,onStatus:i}):await ir({model:e,prompt:t,onStatus:i});if(l)return Jr(l)}catch{return{message:Rr}}return i==null||i({available:!1,label:"Local model not ready",detail:"No manual generation is active."}),{message:$r}}function Jr(e){if("message"in e)return e;const t=e.body??[];return{method:String(e.method||"GET").toUpperCase(),path:String(e.path||"/api/mock"),status:Number(e.status||200),headers:{"content-type":"application/json",...e.headers||{}},body:t}}const Dr=[{label:"Go struct detected",test:/^\s*package\s+\w+|\btype\s+\w+\s+struct\b|\bconst\s*\([^)]*\b\w+\s+\w+\s*=/is},{label:"TypeScript model detected",test:/\binterface\s+\w+\s*\{|\btype\s+\w+\s*=\s*(?:\{|"[^"]|[A-Z]\w*\s*[|&])/i},{label:"Python model detected",test:/\bclass\s+\w+|BaseModel|pydantic|:\s*(str|int|float|bool)\b/i},{label:"Java model detected",test:/\b(public\s+)?class\s+\w+|private\s+(String|Integer|Long|Double|Boolean)\b/i},{label:"Prisma model detected",test:/\bmodel\s+\w+\s*\{|@id|@default/i},{label:"SQL schema detected",test:/\bcreate\s+table\b|\b(varchar|uuid|timestamp|boolean)\b/i},{label:"JSON shape detected",test:/^\s*[\[{]/}];function Gr(e){return Dr.find(r=>r.test.test(e))??{label:e.trim()?"Structure detected":"Waiting for model"}}function Ve(e){return JSON.stringify(e,null,2)??""}function Wr(e){try{return JSON.parse(e)}catch{return null}}const Br={method:"GET",path:"/api/products",status:200,headers:{"content-type":"application/json"},body:[]},nt=[{id:"transformers",label:"Transformers.js models",detail:"Qwen3 0.6B ONNX",available:!1},{id:"webllm",label:"WebLLM models",detail:"Qwen2.5 0.5B Instruct",available:!1},{id:"native",label:"Native browser AI",detail:"window.ai / LanguageModel",available:!1}],Ur=`Make a GET all products response.
|
|
158
|
+
Return 10 ProductModel items.
|
|
159
|
+
The products array must contain exactly 10 items.
|
|
160
|
+
Use id values "1" through "10".`,zr=`export type ProductCategory = "electronics" | "home" | "apparel" | "books";
|
|
161
|
+
|
|
162
|
+
export interface ProductModel {
|
|
163
|
+
id: string;
|
|
164
|
+
sku: string;
|
|
165
|
+
name: string;
|
|
166
|
+
category: ProductCategory;
|
|
167
|
+
priceCents: number;
|
|
168
|
+
currency: "USD";
|
|
169
|
+
inventoryCount: number;
|
|
170
|
+
rating: number;
|
|
171
|
+
tags: string[];
|
|
172
|
+
dimensions: {
|
|
173
|
+
widthCm: number;
|
|
174
|
+
heightCm: number;
|
|
175
|
+
depthCm: number;
|
|
176
|
+
};
|
|
177
|
+
createdAt: string;
|
|
178
|
+
}`;function Zr(){return[{title:"Mocklane"},{name:"description",content:"Generate JSON HTTP mock API responses from pasted models."}]}const Xr=Mt(function(){const[t,r]=c.useState(zr),[n,i]=c.useState(Ur),[l,d]=c.useState(Br),[o,u]=c.useState({available:!1,label:"Checking local model"}),[p,y]=c.useState("light"),[h,g]=c.useState(!1),[b,j]=c.useState(!1),[se,W]=c.useState(!1),[B,U]=c.useState(!1),[Me,z]=c.useState(""),[ie,T]=c.useState(null),[F,le]=c.useState(""),[Ce,Le]=c.useState(!1),[Ae,Te]=c.useState(!1),[Oe,st]=c.useState(4e3),[_,q]=c.useState(!1),[Ee,oe]=c.useState(null),[it,H]=c.useState(null),[ce,lt]=c.useState(nt),[Ie,ot]=c.useState("transformers"),[de,ct]=c.useState(je),[ue,V]=c.useState(!1),[Pe,$]=c.useState(!1),R=c.useRef(0),S=c.useRef(null),_e=c.useRef(null),$e=c.useRef(null),dt=c.useMemo(()=>Gr(t),[t]),J=c.useMemo(()=>Ve(l),[l]),k=ce.find(s=>s.id===Ie)??ce[0],M=P.find(s=>s.id===de)??P[0],pe=qr(k),Re=Vr({option:k,capabilityAvailable:pe.available,modelStatus:o,isLoadingProvider:_}),K=Kr({option:k,modelStatus:o}),ut=Hr(k,o),pt=h?`${it??0}ms`:Ee===null?"Not run yet":`${Ee}ms`,ft=`http://localhost:${Oe}/${D(F)}`;c.useEffect(()=>{u(Z(de)),lt(Fr())},[de]),c.useEffect(()=>{let s=!1;async function m(){const f=await fetch("/__mocklane/health").catch(()=>null);if(!(f!=null&&f.ok))return;const w=await f.json().catch(()=>null);!s&&typeof(w==null?void 0:w.proxyPort)=="number"&&st(w.proxyPort)}return m(),()=>{s=!0}},[]),c.useEffect(()=>{function s(m){var f,w;(f=_e.current)!=null&&f.contains(m.target)||V(!1),(w=$e.current)!=null&&w.contains(m.target)||$(!1)}return document.addEventListener("pointerdown",s),()=>document.removeEventListener("pointerdown",s)},[]),c.useEffect(()=>{const s=window.localStorage.getItem("mocklane-theme");if(s==="light"||s==="dark"){y(s);return}window.matchMedia("(prefers-color-scheme: dark)").matches&&y("dark")},[]),c.useEffect(()=>{document.documentElement.dataset.theme=p,window.localStorage.setItem("mocklane-theme",p)},[p]),c.useEffect(()=>{if(!h||S.current===null)return;const s=()=>{S.current!==null&&H(Math.round(performance.now()-S.current))};s();const m=window.setInterval(s,100);return()=>window.clearInterval(m)},[h]);async function mt(){if(!K)return;const s=R.current+1,m=performance.now();R.current=s,S.current=m,H(0),oe(null),g(!0);try{const f=await Sr({model:t,prompt:n,provider:k.id,transformersModelId:M.id,onStatus:Q=>{R.current===s&&u(Q)}});if(R.current!==s)return;d(f),U(!1),T(null),W(O(f)),O(f)&&le(D(f.path));const w=Math.round(performance.now()-m);H(w),oe(w),j(!1),await ge()}finally{R.current===s&&(S.current=null,g(!1))}}async function bt(){await navigator.clipboard.writeText(J),Le(!0),window.setTimeout(()=>Le(!1),1100)}async function Se(){await navigator.clipboard.writeText(ft),Te(!0),window.setTimeout(()=>Te(!1),1100)}function ht(){z(J),T(null),U(!0)}function yt(){z(""),T(null),U(!1)}async function gt(){let s;try{s=JSON.parse(Me)}catch(f){T(f instanceof SyntaxError?f.message:"Invalid JSON.");return}b&&(await ge(),j(!1)),d(s);const m=O(s);W(m),O(s)&&le(D(s.path)),z(Ve(s)),T(null),U(!1)}function kt(){const s=Wr(J),f=`${(s&&typeof s=="object"&&"path"in s?String(s.path).replaceAll("/","_"):"mock_api").replace(/^_/,"")||"mock_api"}.json`,w=new Blob([J],{type:"application/json"}),Q=URL.createObjectURL(w),fe=document.createElement("a");fe.href=Q,fe.download=f,fe.click(),URL.revokeObjectURL(Q)}function vt(){y(s=>s==="dark"?"light":"dark")}async function wt(){if(b){await ge(),j(!1);return}O(l)&&(await Pr({...l,path:`/${D(F)}`}),j(!0))}function xt(s){s.available&&(ot(s.id),s.id==="transformers"?u(Z(M.id)):s.id==="webllm"?u(ve()):s.id==="native"&&u(mr()),V(!1),$(!1))}function Nt(s){if(s===M.id||_||h){$(!1);return}ct(s),u(Z(s)),$(!1),oe(null),H(null)}function jt(){if(!pe.available)return;if(k.id==="transformers"){const m=Z(M.id);u(m),q(!0),kr(f=>{u(f),ne(f)||q(!1)},{reload:m.label==="Transformers.js ready",modelId:M.id});return}if(k.id!=="webllm")return;const s=ve();u(s),q(!0),sr(m=>{u(m),ne(m)||q(!1)},{reload:s.label==="WebLLM ready"})}return a.jsxs("main",{className:"app-shell",children:[a.jsx("header",{className:"topbar",children:a.jsxs("div",{className:"topbar-inner",children:[a.jsxs("div",{className:"title-line",children:[a.jsxs("div",{className:"brand-logo","aria-label":"Mocklane",children:[a.jsx("span",{children:"MOCK"}),a.jsx("span",{children:"LANE"})]}),a.jsx("h1",{children:"Mock API response generator"})]}),a.jsx("div",{className:"topbar-actions",children:a.jsx("button",{className:"icon-button",type:"button",onClick:vt,"aria-label":p==="dark"?"Switch to light mode":"Switch to dark mode",title:p==="dark"?"Light mode":"Dark mode",children:p==="dark"?a.jsx(Zt,{size:17,"aria-hidden":"true"}):a.jsx(Bt,{size:17,"aria-hidden":"true"})})})]})}),a.jsxs("section",{className:"workspace","aria-label":"Mocklane mock API generator",children:[a.jsx("div",{className:"workspace-summary",children:a.jsxs("div",{className:"model-stat-grid","aria-label":"Local model runtime status",children:[a.jsxs("div",{className:"provider-stat",ref:_e,children:[a.jsxs("div",{className:"provider-stat-card",children:[a.jsx("button",{className:"provider-dropdown-trigger",type:"button",onClick:()=>V(s=>!s),"aria-haspopup":"listbox","aria-expanded":ue,children:a.jsxs("span",{className:"provider-copy",children:[a.jsx("span",{children:"Provider"}),a.jsx("strong",{children:k.label})]})}),a.jsx("div",{className:"provider-status-wrap",children:a.jsxs("span",{className:"provider-status",children:[a.jsx("span",{className:`provider-status-dot ${Re.tone}`,"aria-hidden":"true"}),a.jsx("span",{children:Re.label})]})}),a.jsx("button",{className:"provider-chevron-button",type:"button",onClick:()=>V(s=>!s),"aria-label":"Choose provider","aria-haspopup":"listbox","aria-expanded":ue,children:a.jsx(De,{size:16,"aria-hidden":"true"})})]}),ue?a.jsx("div",{className:"model-menu provider-menu",role:"listbox","aria-label":"Model provider",children:ce.map(s=>a.jsxs("button",{className:"model-menu-item",type:"button",role:"option",disabled:!s.available,"aria-selected":s.id===Ie,onClick:()=>xt(s),children:[a.jsxs("span",{children:[a.jsx("span",{className:"model-option-label",children:s.label}),a.jsx("span",{className:"model-option-detail",children:s.detail})]}),s.available?null:a.jsx("span",{className:"model-unavailable",children:"not available"})]},s.id))}):null]}),a.jsxs("div",{className:k.id==="transformers"?"model-stat-dropdown":void 0,ref:k.id==="transformers"?$e:void 0,children:[a.jsx("span",{children:"Model"}),k.id==="transformers"?a.jsxs(a.Fragment,{children:[a.jsxs("button",{className:"model-stat-trigger",type:"button",onClick:()=>$(s=>!s),disabled:_||h,"aria-haspopup":"listbox","aria-expanded":Pe,children:[a.jsx("strong",{children:M.label}),a.jsx(De,{size:15,"aria-hidden":"true"})]}),Pe?a.jsx("div",{className:"model-menu transformer-model-menu",role:"listbox","aria-label":"Transformers.js model",children:P.map(s=>a.jsxs("button",{className:"model-menu-item",type:"button",role:"option","aria-selected":s.id===M.id,onClick:()=>Nt(s.id),children:[a.jsxs("span",{children:[a.jsx("span",{className:"model-option-label",children:s.label}),a.jsx("span",{className:"model-option-detail",children:s.detail})]}),s.id===M.id?a.jsx(Pt,{size:16,"aria-hidden":"true"}):null]},s.id))}):null]}):a.jsx("strong",{children:k.detail})]}),a.jsxs("div",{children:[a.jsx("span",{children:"Elapsed"}),a.jsx("strong",{children:pt})]})]})}),a.jsxs("div",{className:"panels",children:[a.jsxs("section",{className:"input-panel","aria-label":"Mock API inputs",children:[a.jsx(We,{id:"promptInput",label:"Prompt",meta:"Always outputs JSON HTTP responses",value:n,onChange:i,placeholder:"Example: Make me a GET /api/products response with 10 cyberpunk e-commerce items.",variant:"compact"}),a.jsx(We,{id:"modelInput",label:"Model / Structure",meta:dt.label,value:t,onChange:r,spellCheck:!1,placeholder:"Drop a TypeScript interface, Python/Pydantic class, Go struct, Java DTO, Prisma model, OpenAPI schema, SQL table, or example JSON object."}),a.jsxs("div",{className:"actions",children:[a.jsxs("span",{className:`generate-control ${K?"":"needs-model"}`,tabIndex:K?-1:0,children:[a.jsxs("button",{type:"button",onClick:mt,disabled:h||!K,children:[a.jsx(Yt,{size:17,"aria-hidden":"true"}),h?"Generating":"Generate"]}),a.jsx("span",{className:"tooltip-bubble",children:"Load model first"})]}),k.id!=="native"?a.jsxs("button",{className:"load-provider-action",type:"button",onClick:jt,disabled:_||!pe.available,children:[_?a.jsx(Gt,{className:"spin-icon",size:16,"aria-hidden":"true"}):a.jsx(Ge,{size:16,"aria-hidden":"true"}),ut]}):null]}),o.detail?a.jsx("p",{className:"provider-progress-text",children:o.detail}):null]}),a.jsxs("section",{className:"output-panel","aria-label":"Generated mock API response",children:[a.jsx("div",{className:"output-head",children:a.jsx("p",{className:"eyebrow",children:"HTTP JSON"})}),a.jsxs("div",{className:"code-wrap",children:[a.jsx("div",{className:"code-actions","aria-label":"JSON output actions",children:B?a.jsxs(a.Fragment,{children:[a.jsxs("button",{className:"code-icon-button",type:"button",onClick:gt,"aria-label":"Save JSON",title:"Save JSON",children:[a.jsx(Kt,{size:18,"aria-hidden":"true"}),a.jsx("span",{className:"tooltip-bubble",children:"Save changes"})]}),a.jsxs("button",{className:"code-icon-button",type:"button",onClick:yt,"aria-label":"Cancel editing",title:"Cancel editing",children:[a.jsx(tr,{size:18,"aria-hidden":"true"}),a.jsx("span",{className:"tooltip-bubble",children:"Cancel editing"})]})]}):a.jsxs(a.Fragment,{children:[a.jsxs("button",{className:"code-icon-button",type:"button",onClick:ht,disabled:h,"aria-label":"Edit JSON",title:"Edit JSON",children:[a.jsx(zt,{size:18,"aria-hidden":"true"}),a.jsx("span",{className:"tooltip-bubble",children:"Click to edit"})]}),a.jsxs("button",{className:`code-icon-button copy-control ${Ce?"copied":""}`,type:"button",onClick:bt,"aria-label":"Copy JSON",children:[a.jsx(Rt,{size:18,"aria-hidden":"true"}),a.jsx("span",{className:"tooltip-bubble",children:Ce?"Copied!":"Click to copy"})]}),a.jsxs("button",{className:"code-icon-button",type:"button",onClick:kt,"aria-label":"Download JSON",title:"Download JSON",children:[a.jsx(Jt,{size:18,"aria-hidden":"true"}),a.jsx("span",{className:"tooltip-bubble",children:"Click to download"})]})]})}),B?a.jsxs("div",{className:"json-editor-shell",children:[a.jsx("textarea",{className:"json-editor",value:Me,onChange:s=>{z(s.target.value),ie&&T(null)},"aria-label":"Edit JSON response",spellCheck:!1,autoFocus:!0}),ie?a.jsxs("p",{className:"json-editor-error",role:"alert",children:["Invalid JSON: ",ie]}):null]}):a.jsx("pre",{tabIndex:0,children:a.jsx("code",{children:J})})]}),a.jsxs("div",{className:"mock-footer",children:[a.jsxs("div",{className:`mock-endpoint ${b?"copy-control mock-endpoint-locked":""} ${Ae?"copied":""}`,onClick:b?Se:void 0,onKeyDown:s=>{!b||s.key!=="Enter"&&s.key!==" "||(s.preventDefault(),Se())},role:b?"button":void 0,tabIndex:b?0:void 0,"aria-label":b?"Copy mock API URL":void 0,children:[a.jsxs("span",{className:"mock-endpoint-prefix",children:["localhost:",Oe,"/"]}),a.jsx("input",{type:"text",value:F,onChange:s=>le(s.target.value),placeholder:"api/products","aria-label":"Mock API path",disabled:b||B,spellCheck:!1}),b?a.jsx("span",{className:"tooltip-bubble",children:Ae?"Copied!":"Click to copy"}):null]}),a.jsxs("button",{className:b?"mock-active":"secondary",type:"button",onClick:wt,disabled:B||!se||!O(l)||!D(F),children:[b?a.jsx(qt,{size:16,"aria-hidden":"true"}):a.jsx(Ge,{size:16,"aria-hidden":"true"}),b?"Unmock API":"Mock API"]})]})]})]})]})]})});function D(e){return e.trim().replace(/^\/+/,"")}function Fr(){var n;const e=typeof navigator<"u"&&"gpu"in navigator,t=typeof navigator<"u"&&"gpu"in navigator,r=typeof window<"u"&&!!((n=window.ai)!=null&&n.languageModel||window.LanguageModel);return nt.map(i=>i.id==="webllm"?{...i,available:e}:i.id==="transformers"?{...i,available:t}:i.id==="native"?{...i,available:r}:i)}function qr(e){return e.id==="webllm"?{label:"WebGPU",available:typeof navigator<"u"&&"gpu"in navigator}:e.id==="native"?{label:"Browser AI",available:e.available}:{label:"Transformers.js",available:e.available}}function Hr(e,t){return e.id==="webllm"?t.label==="WebLLM ready"?"Reload WebLLM":"Load WebLLM":e.id==="transformers"?t.label==="Transformers.js ready"?"Reload Transformers.js":"Load Transformers.js":"Load Browser AI"}function Vr({option:e,capabilityAvailable:t,modelStatus:r,isLoadingProvider:n}){if(!t)return{label:"not available",tone:"missing"};if(e.id==="webllm"){if(n||ne(r))return{label:"loading",tone:"loading"};if(r.label==="Generating locally")return{label:"running",tone:"running"};if(r.label==="WebLLM ready")return{label:"ready",tone:"ready"}}if(e.id==="transformers"){if(n||ne(r))return{label:"loading",tone:"loading"};if(r.label==="Generating with Transformers.js")return{label:"running",tone:"running"};if(r.label==="Transformers.js ready")return{label:"ready",tone:"ready"}}return e.id==="native"?r.label==="Native Browser AI preparing"?{label:"loading",tone:"loading"}:r.label==="Generating with Native Browser AI"?{label:"running",tone:"running"}:{label:"available",tone:"available"}:{label:"available",tone:"available"}}function ne(e){return e.label==="WebLLM warming up"||e.label==="Loading local model"||e.label==="Transformers.js warming up"||e.label==="Loading Transformers.js"}function Kr({option:e,modelStatus:t}){return e.id==="webllm"?t.label==="WebLLM ready":e.id==="transformers"?t.label==="Transformers.js ready":e.id==="native"?e.available:!1}export{Xr as default,Zr as meta};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
window.__reactRouterManifest={"entry":{"module":"/assets/entry.client-Cw45cONA.js","imports":["/assets/jsx-runtime-BZbza59V.js"],"css":[]},"routes":{"root":{"id":"root","path":"","hasAction":false,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasClientMiddleware":false,"hasDefaultExport":true,"hasErrorBoundary":false,"module":"/assets/root-
|
|
1
|
+
window.__reactRouterManifest={"entry":{"module":"/assets/entry.client-Cw45cONA.js","imports":["/assets/jsx-runtime-BZbza59V.js"],"css":[]},"routes":{"root":{"id":"root","path":"","hasAction":false,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasClientMiddleware":false,"hasDefaultExport":true,"hasErrorBoundary":false,"module":"/assets/root-BlLsNrT5.js","imports":["/assets/jsx-runtime-BZbza59V.js"],"css":["/assets/root-C9U4kG7U.css"]},"routes/home":{"id":"routes/home","parentId":"root","index":true,"hasAction":false,"hasLoader":false,"hasClientAction":false,"hasClientLoader":false,"hasClientMiddleware":false,"hasDefaultExport":true,"hasErrorBoundary":false,"module":"/assets/home-BctYtJJe.js","imports":["/assets/jsx-runtime-BZbza59V.js"],"css":[]}},"url":"/assets/manifest-cfa23094.js","version":"cfa23094"};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{color-scheme:light;--bg: #f6f7f9;--panel: #ffffff;--panel-soft: #fbfcfe;--ink: #15181f;--muted: #657080;--line: #d9dee7;--line-strong: #bcc5d2;--primary: #1663d9;--primary-dark: #0f4ca7;--code: #111827;--code-ink: #d6e2ff;--brand-ink: #152b3f;--brand-blue: #1597df;--hover-soft: #eef2f7;--ok: #16825d;--warn: #ad5b00;--ready-line: #a7dbc8;--warn-line: #f3cf9c;--focus-ring: rgba(22, 99, 217, .12);font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}[data-theme=dark]{color-scheme:dark;--bg: #0c1118;--panel: #111821;--panel-soft: #0f151e;--ink: #edf3fb;--muted: #92a0b2;--line: #263241;--line-strong: #3a485a;--primary: #2f9ff0;--primary-dark: #1b84d2;--code: #070b12;--code-ink: #d8e7ff;--brand-ink: #f2f7fd;--brand-blue: #39aaf4;--hover-soft: #1a2431;--ok: #68d6ae;--warn: #ffb75d;--ready-line: #2f735d;--warn-line: #7a5427;--focus-ring: rgba(47, 159, 240, .22)}*{box-sizing:border-box}body{margin:0;min-height:100vh;background:var(--bg);color:var(--ink)}button,textarea{font:inherit}.app-shell{height:100vh;overflow:hidden;padding:0 24px 24px}.workspace{display:flex;height:calc(100vh - 92px);min-height:0;flex-direction:column;max-width:1440px;margin:0 auto}.workspace-summary{display:block;margin-bottom:18px}.product-description{max-width:760px;margin:0;color:var(--muted);font-size:14px;line-height:1.5}.topbar{width:calc(100% + 48px);display:flex;align-items:center;justify-content:space-between;gap:16px;margin:0 -24px 18px;border-top:1px solid #55bca9;padding:12px 24px;background:#2d3e50;color:#f6f8fb}.topbar-inner{display:flex;width:100%;max-width:1440px;margin:0 auto;align-items:center;justify-content:space-between;gap:16px}.title-line{display:flex;min-width:0;align-items:baseline;gap:16px}.topbar-actions{display:flex;align-items:center;gap:10px}.eyebrow{margin:0 0 5px;color:var(--primary-dark);font-size:12px;font-weight:700;letter-spacing:0;text-transform:uppercase}.brand-logo{display:inline-flex;align-items:baseline;flex:0 0 auto;margin-bottom:0;font-size:clamp(18px,1.8vw,24px);font-weight:900;line-height:1;letter-spacing:0}.brand-logo span:first-child{color:#f6f8fb}.brand-logo span:last-child{color:#42d0b6}h1,h2{margin:0;letter-spacing:0}h1{font-size:15px;font-weight:400;line-height:1.25;color:#c8d4df}h2{font-size:20px}.status-pill{display:inline-flex;flex:0 0 auto;align-items:center;gap:7px;border:1px solid var(--line);border-radius:999px;padding:8px 12px;background:#ffffff0a;color:#d8e2eb;font-size:13px;font-weight:650}.status-pill.ready{border-color:var(--ready-line);color:var(--ok)}.status-pill.fallback{border-color:var(--warn-line);color:var(--warn)}.panels{display:grid;min-height:0;flex:1;grid-template-columns:minmax(360px,.8fr) minmax(420px,1.2fr);gap:18px;align-items:stretch}.input-panel,.output-panel{min-width:0;min-height:0;border:1px solid var(--line);border-radius:8px;background:var(--panel)}.input-panel{display:flex;flex-direction:column;gap:16px;overflow:hidden;padding:18px}.field-group{display:flex;min-height:0;flex:1;flex-direction:column;gap:8px}.prompt-group{min-height:140px;flex:0 0 210px}.field-heading,.output-head{display:flex;align-items:center;justify-content:space-between;gap:12px}label{font-weight:760}.field-heading span{color:var(--muted);font-size:12px;font-weight:650;text-align:right}textarea{width:100%;min-height:0;flex:1;resize:none;border:1px solid var(--line-strong);border-radius:8px;padding:13px;color:var(--ink);background:var(--panel-soft);line-height:1.45;outline:none}textarea:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--focus-ring)}.actions{display:flex;gap:10px;flex-wrap:wrap}button{display:inline-flex;min-height:38px;align-items:center;justify-content:center;gap:7px;border:1px solid transparent;border-radius:8px;padding:0 14px;background:var(--primary);color:#fff;cursor:pointer;font-weight:760}button:hover{background:var(--primary-dark)}button:disabled{cursor:wait;opacity:.68}button.secondary{border-color:var(--line-strong);background:var(--panel);color:var(--ink)}button.secondary:hover{border-color:var(--primary);color:var(--primary-dark)}button.mock-active{border-color:var(--ready-line);background:var(--ok);color:#fff}button.mock-active:hover{border-color:var(--ready-line);background:var(--ok)}button.ghost{background:transparent;color:var(--muted)}button.ghost:hover{background:var(--hover-soft);color:var(--ink)}button.load-provider-action{border-color:var(--line-strong);background:var(--panel);color:var(--ink)}button.load-provider-action:hover{border-color:var(--primary);background:var(--hover-soft);color:var(--primary-dark)}button.load-provider-action:disabled{background:transparent;color:var(--muted);cursor:not-allowed;opacity:.72}.provider-progress-text{min-height:18px;margin:-6px 0 0;color:var(--muted);font-size:12px;font-weight:650;line-height:1.4}.spin-icon{animation:spin .9s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}button.icon-button{width:38px;padding:0;border-color:#ffffff2e;background:#ffffff0a;color:#d8e2eb}button.icon-button:hover{border-color:#42d0b6;background:#42d0b61f;color:#42d0b6}.output-panel{display:flex;min-height:0;overflow:visible;flex-direction:column;padding:18px}.output-head{margin-bottom:14px}.model-picker{position:relative;flex:0 0 auto}.model-select{min-width:260px;justify-content:space-between;border-color:var(--line-strong);background:var(--panel);color:var(--ink)}.model-select:hover{border-color:var(--primary);background:var(--panel);color:var(--primary-dark)}.model-select>span,.model-menu-item>span:first-child{display:grid;min-width:0;text-align:left}.model-select-label,.model-option-label{overflow:hidden;font-size:13px;font-weight:800;line-height:1.15;text-overflow:ellipsis;white-space:nowrap}.model-select-detail,.model-option-detail{overflow:hidden;color:var(--muted);font-size:11px;font-weight:650;line-height:1.25;text-overflow:ellipsis;white-space:nowrap}.model-menu{position:absolute;top:calc(100% + 8px);right:0;z-index:5;width:min(360px,calc(100vw - 48px));overflow:hidden;border:1px solid var(--line);border-radius:8px;background:var(--panel);box-shadow:0 18px 48px #1118272e}.model-menu-item{width:100%;min-height:52px;justify-content:space-between;gap:16px;border:0;border-radius:0;padding:9px 12px;background:var(--panel);color:var(--ink)}.model-menu-item:hover{background:var(--hover-soft);color:var(--ink)}.model-menu-item[aria-selected=true]{background:#1663d914}.model-menu-item:disabled{cursor:not-allowed;opacity:1}.model-menu-item:disabled .model-option-label,.model-menu-item:disabled .model-option-detail{color:var(--muted);opacity:.62}.model-unavailable{flex:0 0 auto;color:var(--muted);font-size:10px;font-weight:750;line-height:1;opacity:.7}.code-wrap{position:relative;display:grid;min-height:0;flex:1;overflow:visible;border-radius:8px;background:var(--code)}.code-actions{position:absolute;top:12px;right:26px;z-index:1000;display:flex;gap:8px}.code-icon-button{position:relative;width:36px;min-height:36px;padding:0;border-color:#d8e2eb33;background:#2d3e50db;color:#d8e2eb;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.code-icon-button:hover{border-color:#42d0b6;background:#2d3e50;color:#42d0b6}.code-icon-button.copied{border-color:var(--ready-line);background:var(--ok);color:#fff}.json-editor-shell{display:flex;min-width:0;min-height:0;flex:1;flex-direction:column}.json-editor{width:100%;min-height:0;flex:1;resize:none;border:0;border-radius:8px;outline:none;padding:18px 112px 18px 18px;background:transparent;color:var(--code-ink);font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,ui-monospace,monospace;font-size:13px;line-height:1.55;white-space:pre}.json-editor:focus{box-shadow:inset 0 0 0 1px #42d0b6a6}.json-editor-error{margin:0;border-top:1px solid var(--warn-line);padding:9px 14px;background:#ad5b0021;color:var(--warn);font-size:12px;font-weight:700;line-height:1.4}.tooltip-bubble{position:absolute;z-index:1001;right:50%;bottom:calc(100% + 10px);transform:translate(50%);visibility:hidden;opacity:0;pointer-events:none;white-space:nowrap;border-radius:6px;padding:7px 9px;background:#2d3e50;color:#f6f8fb;font-size:12px;font-weight:700;transition:opacity .16s ease,visibility .16s ease}.tooltip-bubble:after{position:absolute;top:100%;left:50%;width:0;height:0;border:6px solid transparent;border-top-color:#2d3e50;content:"";transform:translate(-50%)}.copy-control:hover .tooltip-bubble,.copy-control:focus-visible .tooltip-bubble,.copy-control.copied .tooltip-bubble,.generate-control.needs-model:hover .tooltip-bubble,.generate-control.needs-model:focus-visible .tooltip-bubble,.generate-control.needs-model:focus-within .tooltip-bubble{visibility:visible;opacity:1}.copy-control.copied .tooltip-bubble{background:var(--ok)}.copy-control.copied .tooltip-bubble:after{border-top-color:var(--ok)}.generate-control{position:relative;display:inline-flex;border-radius:8px;outline:none}.generate-control:focus-visible{box-shadow:0 0 0 3px var(--focus-ring)}pre{min-height:0;overflow:auto;margin:0;border-radius:0;padding:18px 112px 18px 18px;background:transparent;color:var(--code-ink);font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,ui-monospace,monospace;font-size:13px;line-height:1.55;white-space:pre}.mock-footer{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:14px}.mock-endpoint{display:flex;width:min(600px,100%);min-width:0;height:38px;align-items:center;overflow:hidden;border:1px solid var(--line-strong);border-radius:8px;background:var(--panel);color:var(--muted);font-size:13px;font-weight:700}.mock-endpoint>span{padding-left:12px;white-space:nowrap}.mock-endpoint input{width:100%;min-width:100px;height:100%;border:0;outline:none;padding:0 12px 0 0;background:transparent;color:var(--ink);font:inherit}.mock-endpoint:focus-within{border-color:var(--primary);box-shadow:0 0 0 3px var(--focus-ring)}.mock-endpoint input:disabled{color:var(--muted);cursor:not-allowed}.mock-endpoint input::placeholder{color:var(--muted);opacity:.72}.model-stat-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}.model-stat-grid{grid-template-columns:repeat(3,minmax(120px,1fr));gap:8px}.model-stat-grid>div{display:grid;min-width:0;gap:5px;border:1px solid var(--line);border-radius:8px;padding:10px;background:var(--panel-soft)}.model-stat-grid>div{gap:4px;min-height:52px;padding:7px 10px}.model-stat-dropdown{position:relative}.model-stat-trigger{width:100%;min-height:22px;justify-content:space-between;border:0;border-radius:4px;padding:0;background:transparent;color:var(--ink)}.model-stat-trigger:hover{background:transparent;color:var(--primary-dark)}.model-stat-trigger:disabled{background:transparent;color:var(--muted);cursor:wait}.model-stat-trigger strong{max-width:calc(100% - 24px)}.transformer-model-menu{top:calc(100% + 8px);right:0;left:0;width:auto}.provider-stat{display:flex;position:relative;padding:0}.provider-stat:hover{background:var(--hover-soft)}.provider-stat-card{display:grid;align-items:center;grid-template-columns:minmax(0,1fr) auto auto;column-gap:10px;height:100%;width:100%;min-height:42px;background:transparent;color:var(--ink)}.provider-dropdown-trigger{width:100%;min-height:42px;justify-content:flex-start;border:0;border-radius:0;padding:0 0 0 12px;background:transparent;color:var(--ink)}.provider-chevron-button{width:30px;min-height:42px;border:0;border-radius:0;padding:0 10px 0 0;background:transparent;color:var(--muted)}.provider-chevron-button:hover,.provider-dropdown-trigger:hover{background:transparent;color:var(--muted)}.provider-stat:hover .provider-copy span,.provider-stat:hover .provider-copy strong,.provider-stat:hover .provider-status,.provider-dropdown-trigger:hover .provider-copy span,.provider-dropdown-trigger:hover .provider-copy strong,.provider-dropdown-trigger:hover .provider-status{color:var(--muted)}.provider-copy{display:grid;min-width:0;gap:4px;text-align:left}.provider-copy span{color:var(--muted);font-size:11px;font-weight:750}.provider-copy strong{overflow:hidden;font-size:12px;line-height:1.3;text-overflow:ellipsis;white-space:nowrap}.provider-status{display:inline-flex;flex:0 0 auto;align-items:center;gap:6px;color:var(--muted);font-size:11px;font-weight:800;white-space:nowrap}.provider-status-wrap{display:grid;justify-items:end}.provider-status-dot{width:9px;height:9px;border:0;border-radius:999px;background:var(--muted)}.provider-status-dot.ready{background:var(--ok)}.provider-status-dot.available{background:var(--primary)}.provider-status-dot.loading{background:var(--warn)}.provider-status-dot.running{background:var(--ok)}.provider-status-dot.missing{background:var(--muted)}.provider-menu{left:0;right:auto;width:min(360px,calc(100vw - 48px))}.model-stat-grid span{color:var(--muted);font-size:12px;font-weight:750}.model-stat-grid span{font-size:11px}.model-stat-grid strong{overflow:hidden;font-size:13px;line-height:1.3;text-overflow:ellipsis;white-space:nowrap}.model-stat-grid strong{font-size:12px}.model-stat-grid .provider-copy span,.model-stat-grid .provider-status{font-size:11px}.model-stat-grid .provider-status span{color:inherit;font-size:inherit;font-weight:inherit}@media(max-width:980px){.app-shell{height:auto;overflow:visible;padding:0 16px 16px}.workspace{height:auto}.workspace-summary{grid-template-columns:1fr}.topbar{width:calc(100% + 32px);margin:0 -16px 18px;padding:12px 16px}.topbar-inner{align-items:flex-start;flex-direction:column}.title-line{flex-direction:column;gap:4px}.panels{grid-template-columns:1fr}.input-panel{overflow:visible}.field-group{min-height:250px}.prompt-group{min-height:160px;flex:.65}.output-panel{min-height:520px}.model-stat-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(max-width:560px){.app-shell{padding:0 10px 10px}.topbar{width:calc(100% + 20px);margin:0 -10px 14px;padding:12px 10px}.input-panel,.output-panel{padding:12px}.workspace-summary{gap:12px;margin-bottom:14px}.field-heading,.output-head{align-items:flex-start;flex-direction:column}.model-picker,.model-select,.actions,.mock-footer{width:100%}.mock-footer{align-items:stretch;flex-direction:column}.mock-endpoint,.mock-endpoint input{width:100%}button{flex:1 1 120px}.model-stat-grid{grid-template-columns:1fr}}
|
|
1
|
+
:root{color-scheme:light;--bg: #f6f7f9;--panel: #ffffff;--panel-soft: #fbfcfe;--ink: #15181f;--muted: #657080;--line: #d9dee7;--line-strong: #bcc5d2;--primary: #1663d9;--primary-dark: #0f4ca7;--code: #111827;--code-ink: #d6e2ff;--brand-ink: #152b3f;--brand-blue: #1597df;--hover-soft: #eef2f7;--ok: #16825d;--warn: #ad5b00;--ready-line: #a7dbc8;--warn-line: #f3cf9c;--focus-ring: rgba(22, 99, 217, .12);font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}[data-theme=dark]{color-scheme:dark;--bg: #0c1118;--panel: #111821;--panel-soft: #0f151e;--ink: #edf3fb;--muted: #92a0b2;--line: #263241;--line-strong: #3a485a;--primary: #2f9ff0;--primary-dark: #1b84d2;--code: #070b12;--code-ink: #d8e7ff;--brand-ink: #f2f7fd;--brand-blue: #39aaf4;--hover-soft: #1a2431;--ok: #68d6ae;--warn: #ffb75d;--ready-line: #2f735d;--warn-line: #7a5427;--focus-ring: rgba(47, 159, 240, .22)}*{box-sizing:border-box}body{margin:0;min-height:100vh;background:var(--bg);color:var(--ink)}button,textarea{font:inherit}.app-shell{height:100vh;overflow:hidden;padding:0 24px 24px}.workspace{display:flex;height:calc(100vh - 92px);min-height:0;flex-direction:column;max-width:1440px;margin:0 auto}.workspace-summary{display:block;margin-bottom:18px}.product-description{max-width:760px;margin:0;color:var(--muted);font-size:14px;line-height:1.5}.topbar{width:calc(100% + 48px);display:flex;align-items:center;justify-content:space-between;gap:16px;margin:0 -24px 18px;border-top:1px solid #55bca9;padding:12px 24px;background:#2d3e50;color:#f6f8fb}.topbar-inner{display:flex;width:100%;max-width:1440px;margin:0 auto;align-items:center;justify-content:space-between;gap:16px}.title-line{display:flex;min-width:0;align-items:baseline;gap:16px}.topbar-actions{display:flex;align-items:center;gap:10px}.eyebrow{margin:0 0 5px;color:var(--primary-dark);font-size:12px;font-weight:700;letter-spacing:0;text-transform:uppercase}.brand-logo{display:inline-flex;align-items:baseline;flex:0 0 auto;margin-bottom:0;font-size:clamp(18px,1.8vw,24px);font-weight:900;line-height:1;letter-spacing:0}.brand-logo span:first-child{color:#f6f8fb}.brand-logo span:last-child{color:#42d0b6}h1,h2{margin:0;letter-spacing:0}h1{font-size:15px;font-weight:400;line-height:1.25;color:#c8d4df}h2{font-size:20px}.status-pill{display:inline-flex;flex:0 0 auto;align-items:center;gap:7px;border:1px solid var(--line);border-radius:999px;padding:8px 12px;background:#ffffff0a;color:#d8e2eb;font-size:13px;font-weight:650}.status-pill.ready{border-color:var(--ready-line);color:var(--ok)}.status-pill.fallback{border-color:var(--warn-line);color:var(--warn)}.panels{display:grid;min-height:0;flex:1;grid-template-columns:minmax(360px,.8fr) minmax(420px,1.2fr);gap:18px;align-items:stretch}.input-panel,.output-panel{min-width:0;min-height:0;border:1px solid var(--line);border-radius:8px;background:var(--panel)}.input-panel{display:flex;flex-direction:column;gap:16px;overflow:hidden;padding:18px}.field-group{display:flex;min-height:0;flex:1;flex-direction:column;gap:8px}.prompt-group{min-height:140px;flex:0 0 210px}.field-heading,.output-head{display:flex;align-items:center;justify-content:space-between;gap:12px}label{font-weight:760}.field-heading span{color:var(--muted);font-size:12px;font-weight:650;text-align:right}textarea{width:100%;min-height:0;flex:1;resize:none;border:1px solid var(--line-strong);border-radius:8px;padding:13px;color:var(--ink);background:var(--panel-soft);line-height:1.45;outline:none}textarea:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--focus-ring)}.actions{display:flex;gap:10px;flex-wrap:wrap}button{display:inline-flex;min-height:38px;align-items:center;justify-content:center;gap:7px;border:1px solid transparent;border-radius:8px;padding:0 14px;background:var(--primary);color:#fff;cursor:pointer;font-weight:760}button:hover{background:var(--primary-dark)}button:disabled{cursor:wait;opacity:.68}button.secondary{border-color:var(--line-strong);background:var(--panel);color:var(--ink)}button.secondary:hover{border-color:var(--primary);color:var(--primary-dark)}button.mock-active{border-color:var(--ready-line);background:var(--ok);color:#fff}button.mock-active:hover{border-color:var(--ready-line);background:var(--ok)}button.ghost{background:transparent;color:var(--muted)}button.ghost:hover{background:var(--hover-soft);color:var(--ink)}button.load-provider-action{border-color:var(--line-strong);background:var(--panel);color:var(--ink)}button.load-provider-action:hover{border-color:var(--primary);background:var(--hover-soft);color:var(--primary-dark)}button.load-provider-action:disabled{background:transparent;color:var(--muted);cursor:not-allowed;opacity:.72}.provider-progress-text{min-height:18px;margin:-6px 0 0;color:var(--muted);font-size:12px;font-weight:650;line-height:1.4}.spin-icon{animation:spin .9s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}button.icon-button{width:38px;padding:0;border-color:#ffffff2e;background:#ffffff0a;color:#d8e2eb}button.icon-button:hover{border-color:#42d0b6;background:#42d0b61f;color:#42d0b6}.output-panel{display:flex;min-height:0;overflow:visible;flex-direction:column;padding:18px}.output-head{margin-bottom:14px}.model-picker{position:relative;flex:0 0 auto}.model-select{min-width:260px;justify-content:space-between;border-color:var(--line-strong);background:var(--panel);color:var(--ink)}.model-select:hover{border-color:var(--primary);background:var(--panel);color:var(--primary-dark)}.model-select>span,.model-menu-item>span:first-child{display:grid;min-width:0;text-align:left}.model-select-label,.model-option-label{overflow:hidden;font-size:13px;font-weight:800;line-height:1.15;text-overflow:ellipsis;white-space:nowrap}.model-select-detail,.model-option-detail{overflow:hidden;color:var(--muted);font-size:11px;font-weight:650;line-height:1.25;text-overflow:ellipsis;white-space:nowrap}.model-menu{position:absolute;top:calc(100% + 8px);right:0;z-index:5;width:min(360px,calc(100vw - 48px));overflow:hidden;border:1px solid var(--line);border-radius:8px;background:var(--panel);box-shadow:0 18px 48px #1118272e}.model-menu-item{width:100%;min-height:52px;justify-content:space-between;gap:16px;border:0;border-radius:0;padding:9px 12px;background:var(--panel);color:var(--ink)}.model-menu-item:hover{background:var(--hover-soft);color:var(--ink)}.model-menu-item[aria-selected=true]{background:#1663d914}.model-menu-item:disabled{cursor:not-allowed;opacity:1}.model-menu-item:disabled .model-option-label,.model-menu-item:disabled .model-option-detail{color:var(--muted);opacity:.62}.model-unavailable{flex:0 0 auto;color:var(--muted);font-size:10px;font-weight:750;line-height:1;opacity:.7}.code-wrap{position:relative;display:grid;min-height:0;flex:1;overflow:visible;border-radius:8px;background:var(--code)}.code-actions{position:absolute;top:12px;right:26px;z-index:1000;display:flex;gap:8px}.code-icon-button{position:relative;width:36px;min-height:36px;padding:0;border-color:#d8e2eb33;background:#2d3e50db;color:#d8e2eb;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.code-icon-button:hover{border-color:#42d0b6;background:#2d3e50;color:#42d0b6}.code-icon-button.copied{border-color:var(--ready-line);background:var(--ok);color:#fff}.json-editor-shell{display:flex;min-width:0;min-height:0;flex:1;flex-direction:column}.json-editor{width:100%;min-height:0;flex:1;resize:none;border:0;border-radius:8px;outline:none;padding:18px 112px 18px 18px;background:transparent;color:var(--code-ink);font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,ui-monospace,monospace;font-size:13px;line-height:1.55;white-space:pre}.json-editor:focus{box-shadow:inset 0 0 0 1px #42d0b6a6}.json-editor-error{margin:0;border-top:1px solid var(--warn-line);padding:9px 14px;background:#ad5b0021;color:var(--warn);font-size:12px;font-weight:700;line-height:1.4}.tooltip-bubble{position:absolute;z-index:1001;right:50%;bottom:calc(100% + 10px);transform:translate(50%);visibility:hidden;opacity:0;pointer-events:none;white-space:nowrap;border-radius:6px;padding:7px 9px;background:#2d3e50;color:#f6f8fb;font-size:12px;font-weight:700;transition:opacity .16s ease,visibility .16s ease}.tooltip-bubble:after{position:absolute;top:100%;left:50%;width:0;height:0;border:6px solid transparent;border-top-color:#2d3e50;content:"";transform:translate(-50%)}.copy-control:hover .tooltip-bubble,.copy-control:focus-visible .tooltip-bubble,.copy-control.copied .tooltip-bubble,.generate-control.needs-model:hover .tooltip-bubble,.generate-control.needs-model:focus-visible .tooltip-bubble,.generate-control.needs-model:focus-within .tooltip-bubble{visibility:visible;opacity:1}.copy-control.copied .tooltip-bubble{background:var(--ok)}.copy-control.copied .tooltip-bubble:after{border-top-color:var(--ok)}.generate-control{position:relative;display:inline-flex;border-radius:8px;outline:none}.generate-control:focus-visible{box-shadow:0 0 0 3px var(--focus-ring)}pre{min-height:0;overflow:auto;margin:0;border-radius:0;padding:18px 112px 18px 18px;background:transparent;color:var(--code-ink);font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,ui-monospace,monospace;font-size:13px;line-height:1.55;white-space:pre}.mock-footer{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:14px}.mock-endpoint{position:relative;display:flex;width:min(600px,100%);min-width:0;height:38px;align-items:center;overflow:visible;border:1px solid var(--line-strong);border-radius:8px;background:var(--panel);color:var(--muted);font-size:13px;font-weight:700}.mock-endpoint-prefix{flex:0 0 auto;padding:0 0 0 12px;color:var(--muted);white-space:nowrap}.mock-endpoint-locked{cursor:pointer}.mock-endpoint-locked:hover,.mock-endpoint-locked:focus-visible{border-color:var(--primary);box-shadow:0 0 0 3px var(--focus-ring);outline:none}.mock-endpoint input{width:100%;min-width:100px;height:100%;border:0;outline:none;padding:0 12px 0 0;background:transparent;color:var(--ink);font:inherit}.mock-endpoint:focus-within{border-color:var(--primary);box-shadow:0 0 0 3px var(--focus-ring)}.mock-endpoint input:disabled{color:var(--muted);cursor:pointer;pointer-events:none}.mock-endpoint input::placeholder{color:var(--muted);opacity:.72}.model-stat-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}.model-stat-grid{grid-template-columns:repeat(3,minmax(120px,1fr));gap:8px}.model-stat-grid>div{display:grid;min-width:0;gap:5px;border:1px solid var(--line);border-radius:8px;padding:10px;background:var(--panel-soft)}.model-stat-grid>div{gap:4px;min-height:52px;padding:7px 10px}.model-stat-dropdown{position:relative}.model-stat-trigger{width:100%;min-height:22px;justify-content:space-between;border:0;border-radius:4px;padding:0;background:transparent;color:var(--ink)}.model-stat-trigger:hover{background:transparent;color:var(--primary-dark)}.model-stat-trigger:disabled{background:transparent;color:var(--muted);cursor:wait}.model-stat-trigger strong{max-width:calc(100% - 24px)}.transformer-model-menu{top:calc(100% + 8px);right:0;left:0;width:auto}.provider-stat{display:flex;position:relative;padding:0}.provider-stat:hover{background:var(--hover-soft)}.provider-stat-card{display:grid;align-items:center;grid-template-columns:minmax(0,1fr) auto auto;column-gap:10px;height:100%;width:100%;min-height:42px;background:transparent;color:var(--ink)}.provider-dropdown-trigger{width:100%;min-height:42px;justify-content:flex-start;border:0;border-radius:0;padding:0 0 0 12px;background:transparent;color:var(--ink)}.provider-chevron-button{width:30px;min-height:42px;border:0;border-radius:0;padding:0 10px 0 0;background:transparent;color:var(--muted)}.provider-chevron-button:hover,.provider-dropdown-trigger:hover{background:transparent;color:var(--muted)}.provider-stat:hover .provider-copy span,.provider-stat:hover .provider-copy strong,.provider-stat:hover .provider-status,.provider-dropdown-trigger:hover .provider-copy span,.provider-dropdown-trigger:hover .provider-copy strong,.provider-dropdown-trigger:hover .provider-status{color:var(--muted)}.provider-copy{display:grid;min-width:0;gap:4px;text-align:left}.provider-copy span{color:var(--muted);font-size:11px;font-weight:750}.provider-copy strong{overflow:hidden;font-size:12px;line-height:1.3;text-overflow:ellipsis;white-space:nowrap}.provider-status{display:inline-flex;flex:0 0 auto;align-items:center;gap:6px;color:var(--muted);font-size:11px;font-weight:800;white-space:nowrap}.provider-status-wrap{display:grid;justify-items:end}.provider-status-dot{width:9px;height:9px;border:0;border-radius:999px;background:var(--muted)}.provider-status-dot.ready{background:var(--ok)}.provider-status-dot.available{background:var(--primary)}.provider-status-dot.loading{background:var(--warn)}.provider-status-dot.running{background:var(--ok)}.provider-status-dot.missing{background:var(--muted)}.provider-menu{left:0;right:auto;width:min(360px,calc(100vw - 48px))}.model-stat-grid span{color:var(--muted);font-size:12px;font-weight:750}.model-stat-grid span{font-size:11px}.model-stat-grid strong{overflow:hidden;font-size:13px;line-height:1.3;text-overflow:ellipsis;white-space:nowrap}.model-stat-grid strong{font-size:12px}.model-stat-grid .provider-copy span,.model-stat-grid .provider-status{font-size:11px}.model-stat-grid .provider-status span{color:inherit;font-size:inherit;font-weight:inherit}@media(max-width:980px){.app-shell{height:auto;overflow:visible;padding:0 16px 16px}.workspace{height:auto}.workspace-summary{grid-template-columns:1fr}.topbar{width:calc(100% + 32px);margin:0 -16px 18px;padding:12px 16px}.topbar-inner{align-items:flex-start;flex-direction:column}.title-line{flex-direction:column;gap:4px}.panels{grid-template-columns:1fr}.input-panel{overflow:visible}.field-group{min-height:250px}.prompt-group{min-height:160px;flex:.65}.output-panel{min-height:520px}.model-stat-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(max-width:560px){.app-shell{padding:0 10px 10px}.topbar{width:calc(100% + 20px);margin:0 -10px 14px;padding:12px 10px}.input-panel,.output-panel{padding:12px}.workspace-summary{gap:12px;margin-bottom:14px}.field-heading,.output-head{align-items:flex-start;flex-direction:column}.model-picker,.model-select,.actions,.mock-footer{width:100%}.mock-footer{align-items:stretch;flex-direction:column}.mock-endpoint,.mock-endpoint input{width:100%}button{flex:1 1 120px}.model-stat-grid{grid-template-columns:1fr}}
|
package/build/client/index.html
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="modulepreload" href="/assets/manifest-
|
|
1
|
+
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="modulepreload" href="/assets/manifest-cfa23094.js"/><link rel="modulepreload" href="/assets/entry.client-Cw45cONA.js"/><link rel="modulepreload" href="/assets/jsx-runtime-BZbza59V.js"/><link rel="modulepreload" href="/assets/root-BlLsNrT5.js"/><link rel="stylesheet" href="/assets/root-C9U4kG7U.css"/></head><body><script>
|
|
2
2
|
console.log(
|
|
3
3
|
"💿 Hey developer 👋. You can provide a way better UX than this " +
|
|
4
4
|
"when your app is loading JS modules and/or running `clientLoader` " +
|
|
5
5
|
"functions. Check out https://reactrouter.com/start/framework/route-module#hydratefallback " +
|
|
6
6
|
"for more information."
|
|
7
7
|
);
|
|
8
|
-
</script><script>window.__reactRouterContext = {"basename":"/","future":{"unstable_optimizeDeps":false,"v8_passThroughRequests":false,"v8_trailingSlashAwareDataRequests":false,"unstable_previewServerPrerendering":false,"v8_middleware":false,"v8_splitRouteModules":false,"v8_viteEnvironmentApi":false},"routeDiscovery":{"mode":"initial"},"ssr":false,"isSpaMode":true};window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());</script><script type="module" async="">import "/assets/manifest-
|
|
9
|
-
import * as route0 from "/assets/root-
|
|
8
|
+
</script><script>window.__reactRouterContext = {"basename":"/","future":{"unstable_optimizeDeps":false,"v8_passThroughRequests":false,"v8_trailingSlashAwareDataRequests":false,"unstable_previewServerPrerendering":false,"v8_middleware":false,"v8_splitRouteModules":false,"v8_viteEnvironmentApi":false},"routeDiscovery":{"mode":"initial"},"ssr":false,"isSpaMode":true};window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());</script><script type="module" async="">import "/assets/manifest-cfa23094.js";
|
|
9
|
+
import * as route0 from "/assets/root-BlLsNrT5.js";
|
|
10
10
|
|
|
11
11
|
window.__reactRouterRouteModules = {"root":route0};
|
|
12
12
|
|
package/package.json
CHANGED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import{r as d,j as a,w as vt}from"./jsx-runtime-BZbza59V.js";/**
|
|
2
|
-
* @license lucide-react v1.17.0 - ISC
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the ISC license.
|
|
5
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const Fe=(...e)=>e.filter((t,r,n)=>!!t&&t.trim()!==""&&n.indexOf(t)===r).join(" ").trim();/**
|
|
7
|
-
* @license lucide-react v1.17.0 - ISC
|
|
8
|
-
*
|
|
9
|
-
* This source code is licensed under the ISC license.
|
|
10
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
-
*/const kt=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase();/**
|
|
12
|
-
* @license lucide-react v1.17.0 - ISC
|
|
13
|
-
*
|
|
14
|
-
* This source code is licensed under the ISC license.
|
|
15
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
-
*/const wt=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(t,r,n)=>n?n.toUpperCase():r.toLowerCase());/**
|
|
17
|
-
* @license lucide-react v1.17.0 - ISC
|
|
18
|
-
*
|
|
19
|
-
* This source code is licensed under the ISC license.
|
|
20
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
21
|
-
*/const Pe=e=>{const t=wt(e);return t.charAt(0).toUpperCase()+t.slice(1)};/**
|
|
22
|
-
* @license lucide-react v1.17.0 - ISC
|
|
23
|
-
*
|
|
24
|
-
* This source code is licensed under the ISC license.
|
|
25
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
26
|
-
*/var pe={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};/**
|
|
27
|
-
* @license lucide-react v1.17.0 - ISC
|
|
28
|
-
*
|
|
29
|
-
* This source code is licensed under the ISC license.
|
|
30
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
31
|
-
*/const xt=e=>{for(const t in e)if(t.startsWith("aria-")||t==="role"||t==="title")return!0;return!1},Nt=d.createContext({}),jt=()=>d.useContext(Nt),Mt=d.forwardRef(({color:e,size:t,strokeWidth:r,absoluteStrokeWidth:n,className:s="",children:l,iconNode:c,...o},u)=>{const{size:m=24,strokeWidth:h=2,absoluteStrokeWidth:f=!1,color:y="currentColor",className:k=""}=jt()??{},N=n??f?Number(r??h)*24/Number(t??m):r??h;return d.createElement("svg",{ref:u,...pe,width:t??m??pe.width,height:t??m??pe.height,stroke:e??y,strokeWidth:N,className:Fe("lucide",k,s),...!l&&!xt(o)&&{"aria-hidden":"true"},...o},[...c.map(([ne,D])=>d.createElement(ne,D)),...Array.isArray(l)?l:[l]])});/**
|
|
32
|
-
* @license lucide-react v1.17.0 - ISC
|
|
33
|
-
*
|
|
34
|
-
* This source code is licensed under the ISC license.
|
|
35
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
36
|
-
*/const v=(e,t)=>{const r=d.forwardRef(({className:n,...s},l)=>d.createElement(Mt,{ref:l,iconNode:t,className:Fe(`lucide-${kt(Pe(e))}`,`lucide-${e}`,n),...s}));return r.displayName=Pe(e),r};/**
|
|
37
|
-
* @license lucide-react v1.17.0 - ISC
|
|
38
|
-
*
|
|
39
|
-
* This source code is licensed under the ISC license.
|
|
40
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
41
|
-
*/const Lt=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],Ct=v("check",Lt);/**
|
|
42
|
-
* @license lucide-react v1.17.0 - ISC
|
|
43
|
-
*
|
|
44
|
-
* This source code is licensed under the ISC license.
|
|
45
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
46
|
-
*/const At=[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]],$e=v("chevron-down",At);/**
|
|
47
|
-
* @license lucide-react v1.17.0 - ISC
|
|
48
|
-
*
|
|
49
|
-
* This source code is licensed under the ISC license.
|
|
50
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
51
|
-
*/const Tt=[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]],Ot=v("copy",Tt);/**
|
|
52
|
-
* @license lucide-react v1.17.0 - ISC
|
|
53
|
-
*
|
|
54
|
-
* This source code is licensed under the ISC license.
|
|
55
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
56
|
-
*/const Et=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],It=v("download",Et);/**
|
|
57
|
-
* @license lucide-react v1.17.0 - ISC
|
|
58
|
-
*
|
|
59
|
-
* This source code is licensed under the ISC license.
|
|
60
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
61
|
-
*/const _t=[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]],Pt=v("loader-circle",_t);/**
|
|
62
|
-
* @license lucide-react v1.17.0 - ISC
|
|
63
|
-
*
|
|
64
|
-
* This source code is licensed under the ISC license.
|
|
65
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
66
|
-
*/const $t=[["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]],Rt=v("moon",$t);/**
|
|
67
|
-
* @license lucide-react v1.17.0 - ISC
|
|
68
|
-
*
|
|
69
|
-
* This source code is licensed under the ISC license.
|
|
70
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
71
|
-
*/const St=[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]],Jt=v("pencil",St);/**
|
|
72
|
-
* @license lucide-react v1.17.0 - ISC
|
|
73
|
-
*
|
|
74
|
-
* This source code is licensed under the ISC license.
|
|
75
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
76
|
-
*/const Gt=[["path",{d:"M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z",key:"goz73y"}],["path",{d:"m2 22 3-3",key:"19mgm9"}],["path",{d:"M7.5 13.5 10 11",key:"7xgeeb"}],["path",{d:"M10.5 16.5 13 14",key:"10btkg"}],["path",{d:"m18 3-4 4h6l-4 4",key:"16psg9"}]],Dt=v("plug-zap",Gt);/**
|
|
77
|
-
* @license lucide-react v1.17.0 - ISC
|
|
78
|
-
*
|
|
79
|
-
* This source code is licensed under the ISC license.
|
|
80
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
81
|
-
*/const Wt=[["path",{d:"M12 22v-5",key:"1ega77"}],["path",{d:"M15 8V2",key:"18g5xt"}],["path",{d:"M17 8a1 1 0 0 1 1 1v4a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V9a1 1 0 0 1 1-1z",key:"1xoxul"}],["path",{d:"M9 8V2",key:"14iosj"}]],Re=v("plug",Wt);/**
|
|
82
|
-
* @license lucide-react v1.17.0 - ISC
|
|
83
|
-
*
|
|
84
|
-
* This source code is licensed under the ISC license.
|
|
85
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
86
|
-
*/const Bt=[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]],zt=v("save",Bt);/**
|
|
87
|
-
* @license lucide-react v1.17.0 - ISC
|
|
88
|
-
*
|
|
89
|
-
* This source code is licensed under the ISC license.
|
|
90
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
91
|
-
*/const Ut=[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"m4.93 4.93 1.41 1.41",key:"149t6j"}],["path",{d:"m17.66 17.66 1.41 1.41",key:"ptbguv"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"m6.34 17.66-1.41 1.41",key:"1m8zz5"}],["path",{d:"m19.07 4.93-1.41 1.41",key:"1shlcs"}]],Ft=v("sun",Ut);/**
|
|
92
|
-
* @license lucide-react v1.17.0 - ISC
|
|
93
|
-
*
|
|
94
|
-
* This source code is licensed under the ISC license.
|
|
95
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
96
|
-
*/const qt=[["path",{d:"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72",key:"ul74o6"}],["path",{d:"m14 7 3 3",key:"1r5n42"}],["path",{d:"M5 6v4",key:"ilb8ba"}],["path",{d:"M19 14v4",key:"blhpug"}],["path",{d:"M10 2v2",key:"7u0qdc"}],["path",{d:"M7 8H3",key:"zfb6yr"}],["path",{d:"M21 16h-4",key:"1cnmox"}],["path",{d:"M11 3H9",key:"1obp7u"}]],Ht=v("wand-sparkles",qt);/**
|
|
97
|
-
* @license lucide-react v1.17.0 - ISC
|
|
98
|
-
*
|
|
99
|
-
* This source code is licensed under the ISC license.
|
|
100
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
101
|
-
*/const Vt=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],Kt=v("x",Vt);function Se({id:e,label:t,meta:r,value:n,onChange:s,placeholder:l,spellCheck:c=!0,variant:o="default"}){return a.jsxs("div",{className:`field-group ${o==="compact"?"prompt-group":""}`,children:[a.jsxs("div",{className:"field-heading",children:[a.jsx("label",{htmlFor:e,children:t}),a.jsx("span",{children:r})]}),a.jsx("textarea",{id:e,value:n,spellCheck:c,placeholder:l,onChange:u=>s(u.target.value)})]})}const Qt="modulepreload",Zt=function(e){return"/"+e},Je={},qe=function(t,r,n){let s=Promise.resolve();if(r&&r.length>0){let c=function(m){return Promise.all(m.map(h=>Promise.resolve(h).then(f=>({status:"fulfilled",value:f}),f=>({status:"rejected",reason:f}))))};document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),u=(o==null?void 0:o.nonce)||(o==null?void 0:o.getAttribute("nonce"));s=c(r.map(m=>{if(m=Zt(m),m in Je)return;Je[m]=!0;const h=m.endsWith(".css"),f=h?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${m}"]${f}`))return;const y=document.createElement("link");if(y.rel=h?"stylesheet":Qt,h||(y.as="script"),y.crossOrigin="",y.href=m,u&&y.setAttribute("nonce",u),document.head.appendChild(y),h)return new Promise((k,N)=>{y.addEventListener("load",k),y.addEventListener("error",()=>N(new Error(`Unable to preload CSS for ${m}`)))})}))}function l(c){const o=new Event("vite:preloadError",{cancelable:!0});if(o.payload=c,window.dispatchEvent(o),!o.defaultPrevented)throw c}return s.then(c=>{for(const o of c||[])o.status==="rejected"&&l(o.reason);return t().catch(l)})},w="Qwen2.5-0.5B-Instruct-q4f16_1-MLC",Xt=5e4;let E=null,x=null,ve=!1;function ke(){return typeof navigator>"u"?{available:!1,label:"WebLLM unavailable"}:"gpu"in navigator?x?{available:!0,label:"WebLLM ready",detail:w}:E?{available:!0,label:"WebLLM warming up",detail:w}:ve?{available:!1,label:"WebLLM unavailable",detail:"WebLLM failed to load."}:{available:!0,label:"WebLLM available",detail:w}:{available:!1,label:"WebLLM unavailable",detail:"WebGPU is unavailable in this browser."}}function Yt(e,t={}){if(!(!ke().available||E)){if(x&&!t.reload){e==null||e({available:!0,label:"WebLLM ready",detail:w});return}e==null||e({available:!0,label:"WebLLM warming up",detail:w}),ve=!1,E=tr(e).then(r=>(x=r,E=null,e==null||e({available:!0,label:"WebLLM ready",detail:w}),r)),E.catch(r=>{ve=!0,E=null,e==null||e({available:!1,label:"WebLLM unavailable",detail:r instanceof Error?r.message:"WebLLM failed to load."})})}}async function er({model:e,prompt:t,onStatus:r}){var n;if(!x)return null;r==null||r({available:!0,label:"Generating locally",detail:w});try{const l=(n=(await x.chat.completions.create({messages:[{role:"system",content:He()},{role:"user",content:Ve({model:e,prompt:t})}],max_tokens:Xt,temperature:.2,top_p:.9})).choices[0])==null?void 0:n.message.content;if(!l)return{message:"The local model returned an empty response.",promptOutput:""};try{const c=Qe(Ke(l),t);return JSON.parse(c)}catch{return{message:"The local model returned text that could not be parsed as JSON.",promptOutput:l}}}finally{r==null||r({available:!0,label:"WebLLM ready",detail:w})}}async function tr(e){if(x)return x.setInitProgressCallback(r=>{e==null||e({available:!0,label:"Loading local model",detail:Ge(r)})}),await x.reload(w),x;const{CreateMLCEngine:t}=await qe(async()=>{const{CreateMLCEngine:r}=await import("./index-D9gteTdx.js");return{CreateMLCEngine:r}},[]);return t(w,{initProgressCallback:r=>{e==null||e({available:!0,label:"Loading local model",detail:Ge(r)})}})}function Ge(e){return`${Math.round(e.progress*100)}% ${e.text}`}function He(){return`You are Mocklane, a focused mock HTTP API response generator.
|
|
102
|
-
|
|
103
|
-
Rules:
|
|
104
|
-
- Only generate mock HTTP API JSON responses.
|
|
105
|
-
- Always return one raw valid JSON object.
|
|
106
|
-
- Do not use markdown, comments, explanations, or code fences.
|
|
107
|
-
- Do not include <think> blocks, hidden reasoning, or analysis.
|
|
108
|
-
- Do not wrap the JSON in a string field such as "promptOutput".
|
|
109
|
-
- Keep the response compact.
|
|
110
|
-
- Use realistic but fake values.
|
|
111
|
-
- Never include real secrets, real personal data, or explanatory text.
|
|
112
|
-
|
|
113
|
-
If the request is unrelated to mock APIs, mock endpoints, mock responses, or mock data, return exactly:
|
|
114
|
-
{"message":"My job is to make mock APIs. Drop a model or structure, then ask me for an endpoint response and I can help you."}
|
|
115
|
-
|
|
116
|
-
For mock API requests, return this object shape:
|
|
117
|
-
{"method":"GET","path":"/api/resource","status":200,"headers":{"content-type":"application/json"},"body":[{"resourcePlural":[...items]}]}
|
|
118
|
-
|
|
119
|
-
Response rules:
|
|
120
|
-
- If the user asks for N items, generate exactly N items. Never generate fewer. Never generate more.
|
|
121
|
-
- Infer body fields from the supplied model, schema, example, or structure.
|
|
122
|
-
- Infer method, path, status, count, and data theme from the user request.
|
|
123
|
-
- Default to method "GET" and status 200 unless the request clearly implies another method or status.
|
|
124
|
-
- If count is not specified, generate 3 items.
|
|
125
|
-
- The body must always be an array containing exactly one object.
|
|
126
|
-
- That one object must have exactly one plural lower-camel-case key for the resource collection, such as "products", "customers", "orders", or "supportTickets".
|
|
127
|
-
- The value of that plural key must be an array of generated objects.
|
|
128
|
-
- Preserve sensible data types from the supplied model.
|
|
129
|
-
- Use ISO-like date strings when generating dates.
|
|
130
|
-
- Use integer cents for fields ending in "Cents", such as "priceCents": 4999.
|
|
131
|
-
|
|
132
|
-
Example body shape:
|
|
133
|
-
{"body":[{"products":[{"id":"101","sku":"ABC-123","name":"Product A","category":"Electronics","priceCents":4999,"currency":"USD","inventoryCount":10,"rating":5,"tags":["Electronics","Tech"]}]}]}`}function Ve({model:e,prompt:t}){return`Model / Structure:
|
|
134
|
-
${e}
|
|
135
|
-
|
|
136
|
-
Prompt:
|
|
137
|
-
${t}`}function rr(e){const t=e.trim();if(t.startsWith("{")&&t.endsWith("}"))return t;const r=t.indexOf("{"),n=t.lastIndexOf("}");if(r===-1||n===-1||n<=r)throw new Error("Local model did not return a JSON object.");return t.slice(r,n+1)}function Ke(e){const r=e.replace(/<think>[\s\S]*?<\/think>/gi,"").trim().replace(/^```(?:json)?\s*/i,"").replace(/\s*```$/i,"").trim();return ar(r)??rr(r)}function ar(e){const t=De(e,"{","}");if(t)return Y(t);const r=De(e,"[","]");return r?Y(r):null}function De(e,t,r){const n=e.indexOf(t);if(n===-1)return null;let s=0,l=!1,c=!1;for(let o=n;o<e.length;o+=1){const u=e[o];if(l){c?c=!1:u==="\\"?c=!0:u==='"'&&(l=!1);continue}if(u==='"')l=!0;else if(u===t)s+=1;else if(u===r&&(s-=1,s===0))return e.slice(n,o+1)}return null}function Y(e){try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}function Qe(e,t){const r=nr(t);if(!r||!/product/i.test(t))return e;try{const n=JSON.parse(e),s=sr(n);if(s.length===r)return Y(JSON.stringify(We(s)));const l=s[0]??ir(n),c=Array.from({length:r},(o,u)=>lr(l,u+1));return Y(JSON.stringify(We(c)))}catch{return e}}function nr(e){const t=e.match(/id\s+(\d+)\s*(?:to|-)\s*(\d+)/i);if(t){const s=Number(t[1]),l=Number(t[2]);if(Number.isFinite(s)&&Number.isFinite(l)&&l>=s)return l-s+1}const r=e.match(/(?:exactly\s+)?(\d+)\s+(?:productmodel\s+)?items?/i);if(!r)return null;const n=Number(r[1]);return Number.isFinite(n)&&n>0?n:null}function sr(e){if(!L(e))return[];if(Array.isArray(e.products))return e.products.filter(L);const t=Array.isArray(e.body)?e.body[0]:null;return L(t)&&Array.isArray(t.products)?t.products.filter(L):Array.isArray(e.body)?e.body.filter(ee):ee(e)?[e]:[]}function ir(e){if(!L(e))return null;const t=Array.isArray(e.body)?e.body[0]:null;return ee(t)?t:ee(e)?e:null}function We(e){return{method:"GET",path:"/api/products",status:200,headers:{"content-type":"application/json"},body:[{products:e}]}}function lr(e,t){var l;const r=["electronics","home","apparel","books"],n=["Laptop","Desk Lamp","Cotton Hoodie","Notebook Set","Wireless Mouse","Ceramic Mug","Running Shirt","Cookbook","Bluetooth Speaker","Storage Basket"],s=r[(t-1)%r.length];return{id:String(t),sku:`SKU-${String(t).padStart(3,"0")}`,name:n[t-1]??`Product ${t}`,category:s,priceCents:we(e==null?void 0:e.priceCents,1999)+(t-1)*250,currency:"USD",inventoryCount:Math.max(0,we(e==null?void 0:e.inventoryCount,100)-(t-1)*3),rating:Math.min(5,Math.round((4.1+t%5*.2)*10)/10),tags:[s,((l=n[t-1])==null?void 0:l.toLowerCase().replaceAll(" ","-"))??`product-${t}`],dimensions:{widthCm:be(e,"widthCm",20+t),heightCm:be(e,"heightCm",10+t),depthCm:be(e,"depthCm",5+t)},createdAt:`2023-04-${String(t).padStart(2,"0")}T00:00:00Z`}}function we(e,t){return typeof e=="number"&&Number.isFinite(e)?e:t}function be(e,t,r){const n=L(e==null?void 0:e.dimensions)?e.dimensions:null;return we(n==null?void 0:n[t],r)}function ee(e){return L(e)&&"id"in e&&"sku"in e&&"name"in e&&"priceCents"in e&&"dimensions"in e}function L(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function or(){return Ze()?{available:!0,label:"Native Browser AI available",detail:"Gemini Nano"}:{available:!1,label:"Native Browser AI unavailable",detail:"The LanguageModel API is unavailable in this browser."}}async function cr({model:e,prompt:t,onStatus:r}){var c;const n=Ze();if(!n)return null;r==null||r({available:!0,label:"Native Browser AI preparing",detail:"Checking Gemini Nano availability..."});const s=He();let l;try{if((n.factory.availability?await n.factory.availability():"available")==="unavailable")throw new Error("The browser reports that Gemini Nano is unavailable.");l=await n.factory.create({...n.kind==="current"?{initialPrompts:[{role:"system",content:s}]}:{systemPrompt:s},monitor(u){u.addEventListener("downloadprogress",m=>{r==null||r({available:!0,label:"Native Browser AI preparing",detail:`Downloading Gemini Nano: ${Math.round(m.loaded*100)}%`})})}})}catch(o){throw r==null||r({available:!0,label:"Native Browser AI available",detail:o instanceof Error?o.message:"Gemini Nano failed to start."}),o}r==null||r({available:!0,label:"Generating with Native Browser AI",detail:"Gemini Nano"});try{const o=await l.prompt(Ve({model:e,prompt:t})),u=Ke(o),m=Qe(dr(u),t);try{return JSON.parse(m)}catch{return{message:"Native Browser AI returned text that could not be parsed as JSON.",promptOutput:o}}}finally{(c=l.destroy)==null||c.call(l),r==null||r({available:!0,label:"Native Browser AI available",detail:"Gemini Nano"})}}function dr(e){const t=e.trim(),r=[];let n=!1,s=!1;for(const c of t){if(n){s?s=!1:c==="\\"?s=!0:c==='"'&&(n=!1);continue}if(c==='"')n=!0;else if(c==="{")r.push("}");else if(c==="[")r.push("]");else if(c==="}"||c==="]"){if(r.at(-1)!==c)return e;r.pop()}}if(n||r.length===0)return e;const l=`${t}${r.reverse().join("")}`;try{return JSON.parse(l),l}catch{return e}}function Ze(){var t;if(typeof window>"u")return null;const e=window;return e.LanguageModel?{factory:e.LanguageModel,kind:"current"}:(t=e.ai)!=null&&t.languageModel?{factory:e.ai.languageModel,kind:"legacy"}:null}const _=[{id:"onnx-community/Qwen3-0.6B-ONNX",label:"Qwen3 0.6B",detail:"Current baseline",dtype:"q4f16"},{id:"onnx-community/gemma-3-1b-it-ONNX-GQA",label:"Gemma 3 1B Instruct",detail:"Google alternative",dtype:"q4"}],je=_[0].id,ur=5e4,mr=`You are Mocklane, a JSON-only mock HTTP API response generator.
|
|
138
|
-
Return exactly one raw valid JSON object.
|
|
139
|
-
Do not include markdown, code fences, comments, explanations, analysis, or <think> blocks.
|
|
140
|
-
Do not reveal chain-of-thought or hidden reasoning.
|
|
141
|
-
|
|
142
|
-
For mock API requests, always return this response shape:
|
|
143
|
-
{"method":"GET","path":"/api/products","status":200,"headers":{"content-type":"application/json"},"body":[{"products":[]}]}
|
|
144
|
-
|
|
145
|
-
Rules:
|
|
146
|
-
- If the user asks for N items, generate exactly N items.
|
|
147
|
-
- If the user gives an id range, include every id in that range exactly once.
|
|
148
|
-
- For GET all product requests, body must be an array containing one object with a plural collection array.
|
|
149
|
-
- Preserve field names and sensible data types from the supplied model.
|
|
150
|
-
- Use string ids.
|
|
151
|
-
- Use integer cents for fields ending in Cents.
|
|
152
|
-
- Use ISO-like strings for date fields.
|
|
153
|
-
- Do not return a single item object unless the user explicitly asks for one item.`;let I=null,C=null,xe=!1,G=null,Z=null;function K(e=je){return typeof navigator>"u"?{available:!1,label:"Transformers.js unavailable"}:"gpu"in navigator?C&&G===e?{available:!0,label:"Transformers.js ready",detail:e}:I?{available:!0,label:"Transformers.js warming up",detail:Z??e}:xe?{available:!1,label:"Transformers.js unavailable",detail:"Transformers.js failed to load."}:{available:!0,label:"Transformers.js available",detail:e}:{available:!1,label:"Transformers.js unavailable",detail:"WebGPU is unavailable in this browser."}}function fr(e,t={}){const r=yr(t.modelId);if(typeof navigator>"u"||!("gpu"in navigator)||I)return;if(C&&G===r.id&&!t.reload){e==null||e({available:!0,label:"Transformers.js ready",detail:r.id});return}e==null||e({available:!0,label:"Transformers.js warming up",detail:r.id}),xe=!1,Z=r.id;const n=C;C=null,G=null,I=hr(r.id).then(s=>br(n,r,s,e)).then(s=>(C=s,G=r.id,Z=null,I=null,e==null||e({available:!0,label:"Transformers.js ready",detail:r.id}),s)),I.catch(s=>{xe=!0,I=null,Z=null,e==null||e({available:!1,label:"Transformers.js unavailable",detail:s instanceof Error?s.message:"Transformers.js failed to load."})})}async function pr({model:e,prompt:t,modelId:r=je,onStatus:n}){if(!C||G!==r)return null;n==null||n({available:!0,label:"Generating with Transformers.js",detail:r});try{const s=await C([{role:"system",content:mr},{role:"user",content:gr({model:e,prompt:t})}],{max_new_tokens:ur,do_sample:!1,return_full_text:!1,tokenizer_encode_kwargs:{enable_thinking:!1}}),l=xr(kr(s),t);try{return JSON.parse(l)}catch{return{message:"Transformers.js returned text that could not be parsed as JSON.",promptOutput:l}}}finally{n==null||n({available:!0,label:"Transformers.js ready",detail:r})}}async function br(e,t,r,n){e&&await e.dispose();const{pipeline:s}=await qe(async()=>{const{pipeline:l}=await import("./transformers.web-CjIQtwg9.js");return{pipeline:l}},[]);return s("text-generation",t.id,{device:"webgpu",dtype:t.dtype,progress_callback:l=>{n==null||n({available:!0,label:"Loading Transformers.js",detail:`${vr(l)} - ${r?"Cache Load":"First Load"}`})}})}async function hr(e){if(!("caches"in globalThis))return!1;const t=e.split("/").at(-1),r=await caches.keys();for(const n of r)if((await(await caches.open(n)).keys()).some(l=>l.url.includes(e)||l.url.includes(t??e)))return!0;return!1}function yr(e){return _.find(t=>t.id===e)??_[0]}function gr({model:e,prompt:t}){return`Model / Structure:
|
|
154
|
-
${e}
|
|
155
|
-
|
|
156
|
-
Prompt:
|
|
157
|
-
${t}`}function vr(e){if(!e||typeof e!="object")return"Loading Transformers.js model";const t=e;return typeof t.progress=="number"?`${Math.round(t.progress)}% ${t.file??t.name??"model file"}`:typeof t.loaded=="number"&&typeof t.total=="number"?`${Math.round(t.loaded/t.total*100)}% ${t.file??t.name??"model file"}`:t.status??"Loading Transformers.js model"}function kr(e){const t=Array.isArray(e)?e[0]:null;if(!t||typeof t!="object"||!("generated_text"in t))return JSON.stringify(e,null,2);const r=t.generated_text;if(typeof r=="string")return he(r);if(Array.isArray(r)){const n=r.at(-1);if(n&&typeof n=="object"&&"content"in n)return he(String(n.content??""))}return he(JSON.stringify(r,null,2))}function he(e){const r=e.replace(/<think>[\s\S]*?<\/think>/gi,"").trim().replace(/^```(?:json)?\s*/i,"").replace(/\s*```$/i,"").trim();return wr(r)??r}function wr(e){const t=Be(e,"{","}");if(t)return te(t);const r=Be(e,"[","]");return r?te(r):null}function Be(e,t,r){const n=e.indexOf(t);if(n===-1)return null;let s=0,l=!1,c=!1;for(let o=n;o<e.length;o+=1){const u=e[o];if(l){c?c=!1:u==="\\"?c=!0:u==='"'&&(l=!1);continue}if(u==='"')l=!0;else if(u===t)s+=1;else if(u===r&&(s-=1,s===0))return e.slice(n,o+1)}return null}function te(e){try{return JSON.stringify(JSON.parse(e),null,2)}catch{return e}}function xr(e,t){const r=Nr(t);if(!r||!/product/i.test(t))return e;try{const n=JSON.parse(e),s=jr(n);if(s.length===r)return te(JSON.stringify(ze(s)));const l=s[0]??Mr(n),c=Array.from({length:r},(o,u)=>Lr(l,u+1));return te(JSON.stringify(ze(c)))}catch{return e}}function Nr(e){const t=e.match(/id\s+(\d+)\s*(?:to|-)\s*(\d+)/i);if(t){const s=Number(t[1]),l=Number(t[2]);if(Number.isFinite(s)&&Number.isFinite(l)&&l>=s)return l-s+1}const r=e.match(/(?:exactly\s+)?(\d+)\s+(?:productmodel\s+)?items?/i);if(!r)return null;const n=Number(r[1]);return Number.isFinite(n)&&n>0?n:null}function jr(e){if(!A(e))return[];if(Array.isArray(e.products))return e.products.filter(A);const t=Array.isArray(e.body)?e.body[0]:null;return A(t)&&Array.isArray(t.products)?t.products.filter(A):Array.isArray(e.body)?e.body.filter(re):re(e)?[e]:[]}function Mr(e){if(!A(e))return null;const t=Array.isArray(e.body)?e.body[0]:null;return re(t)?t:re(e)?e:null}function ze(e){return{method:"GET",path:"/api/products",status:200,headers:{"content-type":"application/json"},body:[{products:e}]}}function Lr(e,t){var l;const r=["electronics","home","apparel","books"],n=["Laptop","Desk Lamp","Cotton Hoodie","Notebook Set","Wireless Mouse","Ceramic Mug","Running Shirt","Cookbook","Bluetooth Speaker","Storage Basket"],s=r[(t-1)%r.length];return{id:String(t),sku:`SKU-${String(t).padStart(3,"0")}`,name:n[t-1]??`Product ${t}`,category:s,priceCents:Ne(e==null?void 0:e.priceCents,1999)+(t-1)*250,currency:"USD",inventoryCount:Math.max(0,Ne(e==null?void 0:e.inventoryCount,100)-(t-1)*3),rating:Math.min(5,Math.round((4.1+t%5*.2)*10)/10),tags:[s,((l=n[t-1])==null?void 0:l.toLowerCase().replaceAll(" ","-"))??`product-${t}`],dimensions:{widthCm:ye(e,"widthCm",20+t),heightCm:ye(e,"heightCm",10+t),depthCm:ye(e,"depthCm",5+t)},createdAt:`2023-04-${String(t).padStart(2,"0")}T00:00:00Z`}}function Ne(e,t){return typeof e=="number"&&Number.isFinite(e)?e:t}function ye(e,t,r){const n=A(e==null?void 0:e.dimensions)?e.dimensions:null;return Ne(n==null?void 0:n[t],r)}function re(e){return A(e)&&"id"in e&&"sku"in e&&"name"in e&&"priceCents"in e&&"dimensions"in e}function A(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}const Xe="/__mocklane/mocks";let X=null;async function Cr(e){const t=await fetch(Xe,{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify(e)});await Ye(t),X=e}async function ge(){if(!X)return;const e=await fetch(Xe,{method:"DELETE",headers:{"content-type":"application/json"},body:JSON.stringify(X)});await Ye(e),X=null}function O(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;const t=e;return typeof t.method=="string"&&typeof t.path=="string"&&typeof t.status=="number"&&!!t.headers&&typeof t.headers=="object"&&!Array.isArray(t.headers)&&"body"in t}async function Ye(e){if(e.ok)return;const t=await e.json().catch(()=>null);throw new Error((t==null?void 0:t.error)??"Mocklane local CLI is unavailable.")}const Ar="My job is to make mock APIs. Drop a model or structure, then ask me for an endpoint response and I can help you.",Tr="The selected local model is still warming up or unavailable. Mocklane will not manually fabricate this response; try again when the model is ready.",Or="The local model responded, but Mocklane could not turn it into a valid mock API JSON response. Try a smaller request or ask for fewer items.";async function Er({model:e,prompt:t,provider:r="webllm",transformersModelId:n,onStatus:s}){if(!e.trim()||!t.trim())return{message:Ar};try{const l=r==="transformers"?await pr({model:e,prompt:t,modelId:n,onStatus:s}):r==="native"?await cr({model:e,prompt:t,onStatus:s}):await er({model:e,prompt:t,onStatus:s});if(l)return Ir(l)}catch{return{message:Or}}return s==null||s({available:!1,label:"Local model not ready",detail:"No manual generation is active."}),{message:Tr}}function Ir(e){if("message"in e)return e;const t=e.body??[];return{method:String(e.method||"GET").toUpperCase(),path:String(e.path||"/api/mock"),status:Number(e.status||200),headers:{"content-type":"application/json",...e.headers||{}},body:t}}const _r=[{label:"Go struct detected",test:/^\s*package\s+\w+|\btype\s+\w+\s+struct\b|\bconst\s*\([^)]*\b\w+\s+\w+\s*=/is},{label:"TypeScript model detected",test:/\binterface\s+\w+\s*\{|\btype\s+\w+\s*=\s*(?:\{|"[^"]|[A-Z]\w*\s*[|&])/i},{label:"Python model detected",test:/\bclass\s+\w+|BaseModel|pydantic|:\s*(str|int|float|bool)\b/i},{label:"Java model detected",test:/\b(public\s+)?class\s+\w+|private\s+(String|Integer|Long|Double|Boolean)\b/i},{label:"Prisma model detected",test:/\bmodel\s+\w+\s*\{|@id|@default/i},{label:"SQL schema detected",test:/\bcreate\s+table\b|\b(varchar|uuid|timestamp|boolean)\b/i},{label:"JSON shape detected",test:/^\s*[\[{]/}];function Pr(e){return _r.find(r=>r.test.test(e))??{label:e.trim()?"Structure detected":"Waiting for model"}}function Ue(e){return JSON.stringify(e,null,2)??""}function $r(e){try{return JSON.parse(e)}catch{return null}}const Rr={method:"GET",path:"/api/products",status:200,headers:{"content-type":"application/json"},body:[]},et=[{id:"transformers",label:"Transformers.js models",detail:"Qwen3 0.6B ONNX",available:!1},{id:"webllm",label:"WebLLM models",detail:"Qwen2.5 0.5B Instruct",available:!1},{id:"native",label:"Native browser AI",detail:"window.ai / LanguageModel",available:!1}],Sr=`Make a GET all products response.
|
|
158
|
-
Return 10 ProductModel items.
|
|
159
|
-
The products array must contain exactly 10 items.
|
|
160
|
-
Use id values "1" through "10".`,Jr=`export type ProductCategory = "electronics" | "home" | "apparel" | "books";
|
|
161
|
-
|
|
162
|
-
export interface ProductModel {
|
|
163
|
-
id: string;
|
|
164
|
-
sku: string;
|
|
165
|
-
name: string;
|
|
166
|
-
category: ProductCategory;
|
|
167
|
-
priceCents: number;
|
|
168
|
-
currency: "USD";
|
|
169
|
-
inventoryCount: number;
|
|
170
|
-
rating: number;
|
|
171
|
-
tags: string[];
|
|
172
|
-
dimensions: {
|
|
173
|
-
widthCm: number;
|
|
174
|
-
heightCm: number;
|
|
175
|
-
depthCm: number;
|
|
176
|
-
};
|
|
177
|
-
createdAt: string;
|
|
178
|
-
}`;function Fr(){return[{title:"Mocklane"},{name:"description",content:"Generate JSON HTTP mock API responses from pasted models."}]}const qr=vt(function(){const[t,r]=d.useState(Jr),[n,s]=d.useState(Sr),[l,c]=d.useState(Rr),[o,u]=d.useState({available:!1,label:"Checking local model"}),[m,h]=d.useState("light"),[f,y]=d.useState(!1),[k,N]=d.useState(!1),[ne,D]=d.useState(!1),[W,B]=d.useState(!1),[Me,z]=d.useState(""),[se,T]=d.useState(null),[ie,le]=d.useState(""),[Le,Ce]=d.useState(!1),[P,U]=d.useState(!1),[Ae,oe]=d.useState(null),[tt,F]=d.useState(null),[ce,rt]=d.useState(et),[Te,at]=d.useState("transformers"),[de,nt]=d.useState(je),[ue,q]=d.useState(!1),[Oe,$]=d.useState(!1),R=d.useRef(0),S=d.useRef(null),Ee=d.useRef(null),Ie=d.useRef(null),st=d.useMemo(()=>Pr(t),[t]),J=d.useMemo(()=>Ue(l),[l]),g=ce.find(i=>i.id===Te)??ce[0],j=_.find(i=>i.id===de)??_[0],me=Dr(g),_e=Br({option:g,capabilityAvailable:me.available,modelStatus:o,isLoadingProvider:P}),H=zr({option:g,modelStatus:o}),it=Wr(g,o),lt=f?`${tt??0}ms`:Ae===null?"Not run yet":`${Ae}ms`;d.useEffect(()=>{u(K(de)),rt(Gr())},[de]),d.useEffect(()=>{function i(p){var b,M;(b=Ee.current)!=null&&b.contains(p.target)||q(!1),(M=Ie.current)!=null&&M.contains(p.target)||$(!1)}return document.addEventListener("pointerdown",i),()=>document.removeEventListener("pointerdown",i)},[]),d.useEffect(()=>{const i=window.localStorage.getItem("mocklane-theme");if(i==="light"||i==="dark"){h(i);return}window.matchMedia("(prefers-color-scheme: dark)").matches&&h("dark")},[]),d.useEffect(()=>{document.documentElement.dataset.theme=m,window.localStorage.setItem("mocklane-theme",m)},[m]),d.useEffect(()=>{if(!f||S.current===null)return;const i=()=>{S.current!==null&&F(Math.round(performance.now()-S.current))};i();const p=window.setInterval(i,100);return()=>window.clearInterval(p)},[f]);async function ot(){if(!H)return;const i=R.current+1,p=performance.now();R.current=i,S.current=p,F(0),oe(null),y(!0);try{const b=await Er({model:t,prompt:n,provider:g.id,transformersModelId:j.id,onStatus:V=>{R.current===i&&u(V)}});if(R.current!==i)return;c(b),B(!1),T(null),D(O(b)),O(b)&&le(Q(b.path));const M=Math.round(performance.now()-p);F(M),oe(M),N(!1),await ge()}finally{R.current===i&&(S.current=null,y(!1))}}async function ct(){await navigator.clipboard.writeText(J),Ce(!0),window.setTimeout(()=>Ce(!1),1100)}function dt(){z(J),T(null),B(!0)}function ut(){z(""),T(null),B(!1)}async function mt(){let i;try{i=JSON.parse(Me)}catch(b){T(b instanceof SyntaxError?b.message:"Invalid JSON.");return}k&&(await ge(),N(!1)),c(i);const p=O(i);D(p),O(i)&&le(Q(i.path)),z(Ue(i)),T(null),B(!1)}function ft(){const i=$r(J),b=`${(i&&typeof i=="object"&&"path"in i?String(i.path).replaceAll("/","_"):"mock_api").replace(/^_/,"")||"mock_api"}.json`,M=new Blob([J],{type:"application/json"}),V=URL.createObjectURL(M),fe=document.createElement("a");fe.href=V,fe.download=b,fe.click(),URL.revokeObjectURL(V)}function pt(){h(i=>i==="dark"?"light":"dark")}async function bt(){if(k){await ge(),N(!1);return}O(l)&&(await Cr({...l,path:`/${Q(ie)}`}),N(!0))}function ht(i){i.available&&(at(i.id),i.id==="transformers"?u(K(j.id)):i.id==="webllm"?u(ke()):i.id==="native"&&u(or()),q(!1),$(!1))}function yt(i){if(i===j.id||P||f){$(!1);return}nt(i),u(K(i)),$(!1),oe(null),F(null)}function gt(){if(!me.available)return;if(g.id==="transformers"){const p=K(j.id);u(p),U(!0),fr(b=>{u(b),ae(b)||U(!1)},{reload:p.label==="Transformers.js ready",modelId:j.id});return}if(g.id!=="webllm")return;const i=ke();u(i),U(!0),Yt(p=>{u(p),ae(p)||U(!1)},{reload:i.label==="WebLLM ready"})}return a.jsxs("main",{className:"app-shell",children:[a.jsx("header",{className:"topbar",children:a.jsxs("div",{className:"topbar-inner",children:[a.jsxs("div",{className:"title-line",children:[a.jsxs("div",{className:"brand-logo","aria-label":"Mocklane",children:[a.jsx("span",{children:"MOCK"}),a.jsx("span",{children:"LANE"})]}),a.jsx("h1",{children:"Mock API response generator"})]}),a.jsx("div",{className:"topbar-actions",children:a.jsx("button",{className:"icon-button",type:"button",onClick:pt,"aria-label":m==="dark"?"Switch to light mode":"Switch to dark mode",title:m==="dark"?"Light mode":"Dark mode",children:m==="dark"?a.jsx(Ft,{size:17,"aria-hidden":"true"}):a.jsx(Rt,{size:17,"aria-hidden":"true"})})})]})}),a.jsxs("section",{className:"workspace","aria-label":"Mocklane mock API generator",children:[a.jsx("div",{className:"workspace-summary",children:a.jsxs("div",{className:"model-stat-grid","aria-label":"Local model runtime status",children:[a.jsxs("div",{className:"provider-stat",ref:Ee,children:[a.jsxs("div",{className:"provider-stat-card",children:[a.jsx("button",{className:"provider-dropdown-trigger",type:"button",onClick:()=>q(i=>!i),"aria-haspopup":"listbox","aria-expanded":ue,children:a.jsxs("span",{className:"provider-copy",children:[a.jsx("span",{children:"Provider"}),a.jsx("strong",{children:g.label})]})}),a.jsx("div",{className:"provider-status-wrap",children:a.jsxs("span",{className:"provider-status",children:[a.jsx("span",{className:`provider-status-dot ${_e.tone}`,"aria-hidden":"true"}),a.jsx("span",{children:_e.label})]})}),a.jsx("button",{className:"provider-chevron-button",type:"button",onClick:()=>q(i=>!i),"aria-label":"Choose provider","aria-haspopup":"listbox","aria-expanded":ue,children:a.jsx($e,{size:16,"aria-hidden":"true"})})]}),ue?a.jsx("div",{className:"model-menu provider-menu",role:"listbox","aria-label":"Model provider",children:ce.map(i=>a.jsxs("button",{className:"model-menu-item",type:"button",role:"option",disabled:!i.available,"aria-selected":i.id===Te,onClick:()=>ht(i),children:[a.jsxs("span",{children:[a.jsx("span",{className:"model-option-label",children:i.label}),a.jsx("span",{className:"model-option-detail",children:i.detail})]}),i.available?null:a.jsx("span",{className:"model-unavailable",children:"not available"})]},i.id))}):null]}),a.jsxs("div",{className:g.id==="transformers"?"model-stat-dropdown":void 0,ref:g.id==="transformers"?Ie:void 0,children:[a.jsx("span",{children:"Model"}),g.id==="transformers"?a.jsxs(a.Fragment,{children:[a.jsxs("button",{className:"model-stat-trigger",type:"button",onClick:()=>$(i=>!i),disabled:P||f,"aria-haspopup":"listbox","aria-expanded":Oe,children:[a.jsx("strong",{children:j.label}),a.jsx($e,{size:15,"aria-hidden":"true"})]}),Oe?a.jsx("div",{className:"model-menu transformer-model-menu",role:"listbox","aria-label":"Transformers.js model",children:_.map(i=>a.jsxs("button",{className:"model-menu-item",type:"button",role:"option","aria-selected":i.id===j.id,onClick:()=>yt(i.id),children:[a.jsxs("span",{children:[a.jsx("span",{className:"model-option-label",children:i.label}),a.jsx("span",{className:"model-option-detail",children:i.detail})]}),i.id===j.id?a.jsx(Ct,{size:16,"aria-hidden":"true"}):null]},i.id))}):null]}):a.jsx("strong",{children:g.detail})]}),a.jsxs("div",{children:[a.jsx("span",{children:"Elapsed"}),a.jsx("strong",{children:lt})]})]})}),a.jsxs("div",{className:"panels",children:[a.jsxs("section",{className:"input-panel","aria-label":"Mock API inputs",children:[a.jsx(Se,{id:"promptInput",label:"Prompt",meta:"Always outputs JSON HTTP responses",value:n,onChange:s,placeholder:"Example: Make me a GET /api/products response with 10 cyberpunk e-commerce items.",variant:"compact"}),a.jsx(Se,{id:"modelInput",label:"Model / Structure",meta:st.label,value:t,onChange:r,spellCheck:!1,placeholder:"Drop a TypeScript interface, Python/Pydantic class, Go struct, Java DTO, Prisma model, OpenAPI schema, SQL table, or example JSON object."}),a.jsxs("div",{className:"actions",children:[a.jsxs("span",{className:`generate-control ${H?"":"needs-model"}`,tabIndex:H?-1:0,children:[a.jsxs("button",{type:"button",onClick:ot,disabled:f||!H,children:[a.jsx(Ht,{size:17,"aria-hidden":"true"}),f?"Generating":"Generate"]}),a.jsx("span",{className:"tooltip-bubble",children:"Load model first"})]}),g.id!=="native"?a.jsxs("button",{className:"load-provider-action",type:"button",onClick:gt,disabled:P||!me.available,children:[P?a.jsx(Pt,{className:"spin-icon",size:16,"aria-hidden":"true"}):a.jsx(Re,{size:16,"aria-hidden":"true"}),it]}):null]}),o.detail?a.jsx("p",{className:"provider-progress-text",children:o.detail}):null]}),a.jsxs("section",{className:"output-panel","aria-label":"Generated mock API response",children:[a.jsx("div",{className:"output-head",children:a.jsx("p",{className:"eyebrow",children:"HTTP JSON"})}),a.jsxs("div",{className:"code-wrap",children:[a.jsx("div",{className:"code-actions","aria-label":"JSON output actions",children:W?a.jsxs(a.Fragment,{children:[a.jsxs("button",{className:"code-icon-button",type:"button",onClick:mt,"aria-label":"Save JSON",title:"Save JSON",children:[a.jsx(zt,{size:18,"aria-hidden":"true"}),a.jsx("span",{className:"tooltip-bubble",children:"Save changes"})]}),a.jsxs("button",{className:"code-icon-button",type:"button",onClick:ut,"aria-label":"Cancel editing",title:"Cancel editing",children:[a.jsx(Kt,{size:18,"aria-hidden":"true"}),a.jsx("span",{className:"tooltip-bubble",children:"Cancel editing"})]})]}):a.jsxs(a.Fragment,{children:[a.jsxs("button",{className:"code-icon-button",type:"button",onClick:dt,disabled:f,"aria-label":"Edit JSON",title:"Edit JSON",children:[a.jsx(Jt,{size:18,"aria-hidden":"true"}),a.jsx("span",{className:"tooltip-bubble",children:"Click to edit"})]}),a.jsxs("button",{className:`code-icon-button copy-control ${Le?"copied":""}`,type:"button",onClick:ct,"aria-label":"Copy JSON",children:[a.jsx(Ot,{size:18,"aria-hidden":"true"}),a.jsx("span",{className:"tooltip-bubble",children:Le?"Copied!":"Click to copy"})]}),a.jsxs("button",{className:"code-icon-button",type:"button",onClick:ft,"aria-label":"Download JSON",title:"Download JSON",children:[a.jsx(It,{size:18,"aria-hidden":"true"}),a.jsx("span",{className:"tooltip-bubble",children:"Click to download"})]})]})}),W?a.jsxs("div",{className:"json-editor-shell",children:[a.jsx("textarea",{className:"json-editor",value:Me,onChange:i=>{z(i.target.value),se&&T(null)},"aria-label":"Edit JSON response",spellCheck:!1,autoFocus:!0}),se?a.jsxs("p",{className:"json-editor-error",role:"alert",children:["Invalid JSON: ",se]}):null]}):a.jsx("pre",{tabIndex:0,children:a.jsx("code",{children:J})})]}),a.jsxs("div",{className:"mock-footer",children:[a.jsxs("label",{className:"mock-endpoint",children:[a.jsx("span",{children:"localhost:4000/"}),a.jsx("input",{type:"text",value:ie,onChange:i=>le(i.target.value),placeholder:"api/products","aria-label":"Mock API path",disabled:k||W,spellCheck:!1})]}),a.jsxs("button",{className:k?"mock-active":"secondary",type:"button",onClick:bt,disabled:W||!ne||!O(l)||!Q(ie),children:[k?a.jsx(Dt,{size:16,"aria-hidden":"true"}):a.jsx(Re,{size:16,"aria-hidden":"true"}),k?"Unmock API":"Mock API"]})]})]})]})]})]})});function Q(e){return e.trim().replace(/^\/+/,"")}function Gr(){var n;const e=typeof navigator<"u"&&"gpu"in navigator,t=typeof navigator<"u"&&"gpu"in navigator,r=typeof window<"u"&&!!((n=window.ai)!=null&&n.languageModel||window.LanguageModel);return et.map(s=>s.id==="webllm"?{...s,available:e}:s.id==="transformers"?{...s,available:t}:s.id==="native"?{...s,available:r}:s)}function Dr(e){return e.id==="webllm"?{label:"WebGPU",available:typeof navigator<"u"&&"gpu"in navigator}:e.id==="native"?{label:"Browser AI",available:e.available}:{label:"Transformers.js",available:e.available}}function Wr(e,t){return e.id==="webllm"?t.label==="WebLLM ready"?"Reload WebLLM":"Load WebLLM":e.id==="transformers"?t.label==="Transformers.js ready"?"Reload Transformers.js":"Load Transformers.js":"Load Browser AI"}function Br({option:e,capabilityAvailable:t,modelStatus:r,isLoadingProvider:n}){if(!t)return{label:"not available",tone:"missing"};if(e.id==="webllm"){if(n||ae(r))return{label:"loading",tone:"loading"};if(r.label==="Generating locally")return{label:"running",tone:"running"};if(r.label==="WebLLM ready")return{label:"ready",tone:"ready"}}if(e.id==="transformers"){if(n||ae(r))return{label:"loading",tone:"loading"};if(r.label==="Generating with Transformers.js")return{label:"running",tone:"running"};if(r.label==="Transformers.js ready")return{label:"ready",tone:"ready"}}return e.id==="native"?r.label==="Native Browser AI preparing"?{label:"loading",tone:"loading"}:r.label==="Generating with Native Browser AI"?{label:"running",tone:"running"}:{label:"available",tone:"available"}:{label:"available",tone:"available"}}function ae(e){return e.label==="WebLLM warming up"||e.label==="Loading local model"||e.label==="Transformers.js warming up"||e.label==="Loading Transformers.js"}function zr({option:e,modelStatus:t}){return e.id==="webllm"?t.label==="WebLLM ready":e.id==="transformers"?t.label==="Transformers.js ready":e.id==="native"?e.available:!1}export{qr as default,Fr as meta};
|
|
File without changes
|