json-schema-builder-react 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Martin Arusalu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,410 @@
1
+ # JSON Schema Builder
2
+
3
+ A beautiful, interactive React component for building and editing JSON schemas visually. Built with TypeScript, Tailwind CSS, and Radix UI.
4
+
5
+ - 📖 [View demo](https://martin-arusalu.github.io/json-schema-editor)
6
+
7
+ ## Features
8
+
9
+ - 🎨 **Visual Editor** - Build JSON schemas with an intuitive drag-and-drop interface
10
+ - 📝 **Full JSON Schema Support** - Support for all JSON Schema types and constraints
11
+ - 🎯 **Type-Safe** - Written in TypeScript with full type definitions
12
+ - ✅ **Official JSON Schema Types** - Uses `@types/json-schema` for spec compliance
13
+ - 🎨 **Customizable** - Flexible API with extensive customization options
14
+ - 📦 **Headless Options** - Use just the hooks and utilities without UI
15
+ - 🌗 **Theme Support** - Built-in dark mode support
16
+ - ⚡ **Lightweight** - Tree-shakeable with minimal bundle size impact
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install json-schema-builder-react
22
+ # or
23
+ yarn add json-schema-builder-react
24
+ # or
25
+ pnpm add json-schema-builder-react
26
+ ```
27
+
28
+ ### Styling
29
+
30
+ This library uses Tailwind CSS utility classes. You'll need Tailwind CSS configured in your project.
31
+
32
+ #### 1. Install Tailwind CSS (if not already installed)
33
+
34
+ ```bash
35
+ npm install -D tailwindcss postcss autoprefixer
36
+ npx tailwindcss init -p
37
+ ```
38
+
39
+ #### 2. Configure Tailwind Content Paths
40
+
41
+ Add the library to your `tailwind.config.js`:
42
+
43
+ ```js
44
+ /** @type {import('tailwindcss').Config} */
45
+ module.exports = {
46
+ content: [
47
+ './src/**/*.{js,jsx,ts,tsx}',
48
+ './node_modules/json-schema-editor/**/*.{js,jsx}', // Add this line
49
+ ],
50
+ theme: {
51
+ extend: {},
52
+ },
53
+ plugins: [],
54
+ };
55
+ ```
56
+
57
+ #### 3. Configure PostCSS
58
+
59
+ Create or update `postcss.config.js` in your project root:
60
+
61
+ ```js
62
+ export default {
63
+ plugins: {
64
+ tailwindcss: {},
65
+ autoprefixer: {},
66
+ },
67
+ };
68
+ ```
69
+
70
+ #### 4. Import Tailwind in your CSS
71
+
72
+ Add to your main CSS file (e.g., `src/index.css`):
73
+
74
+ ```css
75
+ @tailwind base;
76
+ @tailwind components;
77
+ @tailwind utilities;
78
+ ```
79
+
80
+ **Note:** The library components will automatically use your project's Tailwind theme (colors, spacing, etc.).
81
+
82
+ ## Usage
83
+
84
+ ### Basic Example
85
+
86
+ ```tsx
87
+ import { JsonSchemaBuilder } from 'json-schema-builder-react';
88
+
89
+ function App() {
90
+ const handleSchemaChange = (schema) => {
91
+ console.log('Schema updated:', schema);
92
+ };
93
+
94
+ return (
95
+ <JsonSchemaBuilder
96
+ onSchemaChange={handleSchemaChange}
97
+ />
98
+ );
99
+ }
100
+ ```
101
+
102
+ ### With Initial Schema
103
+
104
+ ```tsx
105
+ import { JsonSchemaBuilder } from 'json-schema-builder-react';
106
+
107
+ const initialSchema = {
108
+ type: 'object',
109
+ properties: {
110
+ name: { type: 'string' },
111
+ age: { type: 'number' }
112
+ },
113
+ required: ['name']
114
+ };
115
+
116
+ function App() {
117
+ return (
118
+ <JsonSchemaBuilder
119
+ initialSchema={initialSchema}
120
+ onSchemaChange={(schema) => {
121
+ // Save to backend, localStorage, etc.
122
+ console.log(schema);
123
+ }}
124
+ />
125
+ );
126
+ }
127
+ ```
128
+
129
+ ### Customized Layout
130
+
131
+ ```tsx
132
+ import { JsonSchemaBuilder } from 'json-schema-builder-react';
133
+
134
+ function App() {
135
+ return (
136
+ <JsonSchemaBuilder
137
+ showMetadata={true}
138
+ showImport={false}
139
+ showClear={true}
140
+ showOutput={true}
141
+ className="h-[600px]"
142
+ typeLabels={{
143
+ string: 'Text',
144
+ boolean: 'Yes/No',
145
+ object: 'Form',
146
+ array: 'List',
147
+ }}
148
+ />
149
+ );
150
+ }
151
+ ```
152
+
153
+ ## API Reference
154
+
155
+ ### JsonSchemaBuilder Props
156
+
157
+ | Prop | Type | Default | Description |
158
+ |------|------|---------|-------------|
159
+ | `initialSchema` | `object` | `undefined` | Initial JSON schema to load |
160
+ | `onSchemaChange` | `(schema: any) => void` | `undefined` | Callback when schema changes |
161
+ | `showMetadata` | `boolean` | `true` | Show metadata fields (title, description, version) |
162
+ | `showImport` | `boolean` | `true` | Show import button |
163
+ | `showClear` | `boolean` | `true` | Show clear all button |
164
+ | `showOutput` | `boolean` | `true` | Show JSON output panel |
165
+ | `headerContent` | `ReactNode` | `undefined` | Custom header content |
166
+ | `className` | `string` | `"h-screen"` | Custom className for container |
167
+ | `typeLabels` | `TypeLabels` | Default labels | Custom labels for property types (e.g., `{ string: 'Text', boolean: 'Yes/No' }`) |
168
+ | `propertyLabel` | `{ singular: string, plural: string }` | `{ singular: 'property', plural: 'properties' }` | Custom labels for top-level properties (e.g., `{ singular: 'input', plural: 'inputs' }`) |
169
+
170
+ ### Customizing Type Labels
171
+
172
+ You can customize how property types are displayed to your users:
173
+
174
+ ```tsx
175
+ import { JsonSchemaBuilder } from 'json-schema-builder-react';
176
+ import type { TypeLabels } from 'json-schema-builder-react';
177
+
178
+ const customLabels: TypeLabels = {
179
+ string: 'Text',
180
+ number: 'Number',
181
+ integer: 'Whole Number',
182
+ boolean: 'Yes/No',
183
+ object: 'Form',
184
+ array: 'List',
185
+ null: 'Empty'
186
+ };
187
+
188
+ function App() {
189
+ return (
190
+ <JsonSchemaBuilder
191
+ typeLabels={customLabels}
192
+ onSchemaChange={(schema) => console.log(schema)}
193
+ />
194
+ );
195
+ }
196
+ ```
197
+
198
+ This affects:
199
+ - The type dropdown in the property editor
200
+ - Type labels shown in property cards
201
+ - Tooltips displaying type information
202
+
203
+ **Available types to customize:**
204
+ - `string` - Default: "String"
205
+ - `number` - Default: "Number"
206
+ - `integer` - Default: "Integer"
207
+ - `boolean` - Default: "Boolean"
208
+ - `object` - Default: "Object"
209
+ - `array` - Default: "Array"
210
+ - `null` - Default: "Null"
211
+
212
+ ## Headless Usage
213
+
214
+ Use just the hooks and utilities without the UI components:
215
+
216
+ ```tsx
217
+ import { useSchemaBuilder, generateSchema } from 'json-schema-builder-react';
218
+
219
+ function MyCustomEditor() {
220
+ const {
221
+ properties,
222
+ metadata,
223
+ schema,
224
+ addProperty,
225
+ updateProperty,
226
+ deleteProperty,
227
+ } = useSchemaBuilder(true);
228
+
229
+ return (
230
+ <div>
231
+ {/* Build your own custom UI */}
232
+ <button onClick={() => {
233
+ const newProp = addProperty();
234
+ updateProperty(newProp.id, {
235
+ ...newProp,
236
+ key: 'myProperty',
237
+ type: 'string'
238
+ });
239
+ }}>
240
+ Add Property
241
+ </button>
242
+
243
+ <pre>{JSON.stringify(schema, null, 2)}</pre>
244
+ </div>
245
+ );
246
+ }
247
+ ```
248
+
249
+ ## Available Exports
250
+
251
+ ### Components
252
+ - `JsonSchemaBuilder` - Main builder component
253
+ - `PropertyDocument` - Individual property card
254
+ - `PropertyEditDialog` - Property edit modal
255
+ - `JsonOutput` - JSON output display
256
+ - `SchemaMetadataComponent` - Schema metadata fields
257
+
258
+ ### Hooks
259
+ - `useSchemaBuilder` - Main schema builder logic
260
+ - `usePropertyEditor` - Property editing logic
261
+
262
+ ### Utilities
263
+ - `generateSchema` - Generate JSON schema from properties
264
+ - `parseSchema` - Parse JSON schema into properties
265
+ - `downloadJsonFile` - Download schema as JSON file
266
+ - `importJsonFile` - Import schema from file
267
+
268
+ ### Types
269
+ - `PropertyData` - Internal UI representation of a JSON Schema property (extends JSON Schema fields)
270
+ - `PropertyType` - JSON Schema type names (from `@types/json-schema`)
271
+ - `SchemaMetadata` - Schema metadata structure
272
+ - `JSONSchema7` - Official JSON Schema Draft 7 type (from `@types/json-schema`)
273
+ - `JSONSchema7TypeName` - JSON Schema type names (from `@types/json-schema`)
274
+
275
+ **Note**: This library uses official JSON Schema types from `@types/json-schema` to ensure compatibility with the JSON Schema specification.
276
+
277
+ ## Examples
278
+
279
+ ### Using Individual Components
280
+
281
+ ```tsx
282
+ import {
283
+ PropertyDocument,
284
+ useSchemaBuilder
285
+ } from 'json-schema-builder-react';
286
+
287
+ function CustomEditor() {
288
+ const { properties, updateProperty, deleteProperty } = useSchemaBuilder();
289
+
290
+ return (
291
+ <div>
292
+ {properties.map(property => (
293
+ <PropertyDocument
294
+ key={property.id}
295
+ property={property}
296
+ onUpdate={(updated) => updateProperty(property.id, updated)}
297
+ onDelete={() => deleteProperty(property.id)}
298
+ />
299
+ ))}
300
+ </div>
301
+ );
302
+ }
303
+ ```
304
+
305
+ ### Programmatic Schema Generation
306
+
307
+ ```tsx
308
+ import { generateSchema } from 'json-schema-builder-react';
309
+ import type { PropertyData } from 'json-schema-builder-react';
310
+
311
+ const properties: PropertyData[] = [
312
+ {
313
+ id: '1',
314
+ key: 'username',
315
+ type: 'string',
316
+ required: true,
317
+ constraints: {
318
+ minLength: 3,
319
+ maxLength: 20
320
+ }
321
+ },
322
+ {
323
+ id: '2',
324
+ key: 'email',
325
+ type: 'string',
326
+ required: true,
327
+ constraints: {
328
+ pattern: '^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$'
329
+ }
330
+ }
331
+ ];
332
+
333
+ const schema = generateSchema(
334
+ properties,
335
+ { title: 'User Schema', description: 'User registration', version: '1.0.0' },
336
+ true
337
+ );
338
+ ```
339
+
340
+ ## Development
341
+
342
+ ```bash
343
+ # Install dependencies
344
+ npm install
345
+
346
+ # Run demo app in development mode
347
+ npm run dev
348
+
349
+ # Build the library
350
+ npm run build:lib
351
+
352
+ # Build the demo app
353
+ npm run build
354
+
355
+ # Deploy demo to GitHub Pages
356
+ npm run deploy
357
+ ```
358
+
359
+ ## Troubleshooting
360
+
361
+ ### PostCSS Warning
362
+
363
+ If you see this warning:
364
+ ```
365
+ A PostCSS plugin did not pass the `from` option to `postcss.parse`
366
+ ```
367
+
368
+ **Solution:** Make sure you have a `postcss.config.js` file in your project root:
369
+
370
+ ```js
371
+ export default {
372
+ plugins: {
373
+ tailwindcss: {},
374
+ autoprefixer: {},
375
+ },
376
+ };
377
+ ```
378
+
379
+ And verify your `tailwind.config.js` includes the library path:
380
+
381
+ ```js
382
+ module.exports = {
383
+ content: [
384
+ './src/**/*.{js,jsx,ts,tsx}',
385
+ './node_modules/json-schema-editor/**/*.{js,jsx}',
386
+ ],
387
+ // ...
388
+ };
389
+ ```
390
+
391
+ ### Styles Not Appearing
392
+
393
+ Make sure you:
394
+ 1. Have Tailwind CSS installed and configured
395
+ 2. Added the library to your Tailwind content paths (see Styling section)
396
+ 3. Imported Tailwind CSS in your main CSS file
397
+
398
+ ## License
399
+
400
+ MIT © Martin Arusalu
401
+
402
+ ## Contributing
403
+
404
+ Contributions are welcome! Please feel free to submit a Pull Request.
405
+
406
+ ## Support
407
+
408
+ - 🐛 [Report a bug](https://github.com/martin-arusalu/json-schema-editor/issues)
409
+ - 💡 [Request a feature](https://github.com/martin-arusalu/json-schema-editor/issues)
410
+ - 📖 [View demo](https://martin-arusalu.github.io/json-schema-editor)
@@ -0,0 +1,6 @@
1
+ This favicon was generated using the following font:
2
+
3
+ - Font Title: Lato
4
+ - Font Author: undefined
5
+ - Font Source: https://fonts.gstatic.com/s/lato/v24/S6u9w4BMUTPHh50Xew-FGC_p9dw.ttf
6
+ - Font License: undefined)
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),I=require("react"),et=require("@radix-ui/react-slot"),b=require("lucide-react"),tt=require("@radix-ui/react-tooltip"),st=require("@radix-ui/react-dialog"),rt=require("@radix-ui/react-label"),nt=require("@radix-ui/react-select"),ot=require("@radix-ui/react-checkbox");function Z(e){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const s in e)if(s!=="default"){const o=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(r,s,o.get?o:{enumerable:!0,get:()=>e[s]})}}return r.default=e,Object.freeze(r)}const S=Z(I),se=Z(tt),B=Z(st),Ie=Z(rt),A=Z(nt),ie=Z(ot);function ze(e){var r,s,o="";if(typeof e=="string"||typeof e=="number")o+=e;else if(typeof e=="object")if(Array.isArray(e)){var n=e.length;for(r=0;r<n;r++)e[r]&&(s=ze(e[r]))&&(o&&(o+=" "),o+=s)}else for(s in e)e[s]&&(o&&(o+=" "),o+=s);return o}function Ae(){for(var e,r,s=0,o="",n=arguments.length;s<n;s++)(e=arguments[s])&&(r=ze(e))&&(o&&(o+=" "),o+=r);return o}const Ne=e=>typeof e=="boolean"?`${e}`:e===0?"0":e,Ce=Ae,Re=(e,r)=>s=>{var o;if((r==null?void 0:r.variants)==null)return Ce(e,s==null?void 0:s.class,s==null?void 0:s.className);const{variants:n,defaultVariants:a}=r,i=Object.keys(n).map(l=>{const h=s==null?void 0:s[l],N=a==null?void 0:a[l];if(h===null)return null;const y=Ne(h)||Ne(N);return n[l][y]}),d=s&&Object.entries(s).reduce((l,h)=>{let[N,y]=h;return y===void 0||(l[N]=y),l},{}),c=r==null||(o=r.compoundVariants)===null||o===void 0?void 0:o.reduce((l,h)=>{let{class:N,className:y,...P}=h;return Object.entries(P).every(g=>{let[m,p]=g;return Array.isArray(p)?p.includes({...a,...d}[m]):{...a,...d}[m]===p})?[...l,N,y]:l},[]);return Ce(e,i,c,s==null?void 0:s.class,s==null?void 0:s.className)},ge="-",at=e=>{const r=lt(e),{conflictingClassGroups:s,conflictingClassGroupModifiers:o}=e;return{getClassGroupId:i=>{const d=i.split(ge);return d[0]===""&&d.length!==1&&d.shift(),qe(d,r)||it(i)},getConflictingClassGroupIds:(i,d)=>{const c=s[i]||[];return d&&o[i]?[...c,...o[i]]:c}}},qe=(e,r)=>{var i;if(e.length===0)return r.classGroupId;const s=e[0],o=r.nextPart.get(s),n=o?qe(e.slice(1),o):void 0;if(n)return n;if(r.validators.length===0)return;const a=e.join(ge);return(i=r.validators.find(({validator:d})=>d(a)))==null?void 0:i.classGroupId},ke=/^\[(.+)\]$/,it=e=>{if(ke.test(e)){const r=ke.exec(e)[1],s=r==null?void 0:r.substring(0,r.indexOf(":"));if(s)return"arbitrary.."+s}},lt=e=>{const{theme:r,prefix:s}=e,o={nextPart:new Map,validators:[]};return ct(Object.entries(e.classGroups),s).forEach(([a,i])=>{le(i,o,a,r)}),o},le=(e,r,s,o)=>{e.forEach(n=>{if(typeof n=="string"){const a=n===""?r:Se(r,n);a.classGroupId=s;return}if(typeof n=="function"){if(dt(n)){le(n(o),r,s,o);return}r.validators.push({validator:n,classGroupId:s});return}Object.entries(n).forEach(([a,i])=>{le(i,Se(r,a),s,o)})})},Se=(e,r)=>{let s=e;return r.split(ge).forEach(o=>{s.nextPart.has(o)||s.nextPart.set(o,{nextPart:new Map,validators:[]}),s=s.nextPart.get(o)}),s},dt=e=>e.isThemeGetter,ct=(e,r)=>r?e.map(([s,o])=>{const n=o.map(a=>typeof a=="string"?r+a:typeof a=="object"?Object.fromEntries(Object.entries(a).map(([i,d])=>[r+i,d])):a);return[s,n]}):e,mt=e=>{if(e<1)return{get:()=>{},set:()=>{}};let r=0,s=new Map,o=new Map;const n=(a,i)=>{s.set(a,i),r++,r>e&&(r=0,o=s,s=new Map)};return{get(a){let i=s.get(a);if(i!==void 0)return i;if((i=o.get(a))!==void 0)return n(a,i),i},set(a,i){s.has(a)?s.set(a,i):n(a,i)}}},Ee="!",ut=e=>{const{separator:r,experimentalParseClassName:s}=e,o=r.length===1,n=r[0],a=r.length,i=d=>{const c=[];let l=0,h=0,N;for(let p=0;p<d.length;p++){let C=d[p];if(l===0){if(C===n&&(o||d.slice(p,p+a)===r)){c.push(d.slice(h,p)),h=p+a;continue}if(C==="/"){N=p;continue}}C==="["?l++:C==="]"&&l--}const y=c.length===0?d:d.substring(h),P=y.startsWith(Ee),g=P?y.substring(1):y,m=N&&N>h?N-h:void 0;return{modifiers:c,hasImportantModifier:P,baseClassName:g,maybePostfixModifierPosition:m}};return s?d=>s({className:d,parseClassName:i}):i},pt=e=>{if(e.length<=1)return e;const r=[];let s=[];return e.forEach(o=>{o[0]==="["?(r.push(...s.sort(),o),s=[]):s.push(o)}),r.push(...s.sort()),r},ht=e=>({cache:mt(e.cacheSize),parseClassName:ut(e),...at(e)}),ft=/\s+/,gt=(e,r)=>{const{parseClassName:s,getClassGroupId:o,getConflictingClassGroupIds:n}=r,a=[],i=e.trim().split(ft);let d="";for(let c=i.length-1;c>=0;c-=1){const l=i[c],{modifiers:h,hasImportantModifier:N,baseClassName:y,maybePostfixModifierPosition:P}=s(l);let g=!!P,m=o(g?y.substring(0,P):y);if(!m){if(!g){d=l+(d.length>0?" "+d:d);continue}if(m=o(y),!m){d=l+(d.length>0?" "+d:d);continue}g=!1}const p=pt(h).join(":"),C=N?p+Ee:p,j=C+m;if(a.includes(j))continue;a.push(j);const u=n(m,g);for(let R=0;R<u.length;++R){const D=u[R];a.push(C+D)}d=l+(d.length>0?" "+d:d)}return d};function xt(){let e=0,r,s,o="";for(;e<arguments.length;)(r=arguments[e++])&&(s=Le(r))&&(o&&(o+=" "),o+=s);return o}const Le=e=>{if(typeof e=="string")return e;let r,s="";for(let o=0;o<e.length;o++)e[o]&&(r=Le(e[o]))&&(s&&(s+=" "),s+=r);return s};function bt(e,...r){let s,o,n,a=i;function i(c){const l=r.reduce((h,N)=>N(h),e());return s=ht(l),o=s.cache.get,n=s.cache.set,a=d,d(c)}function d(c){const l=o(c);if(l)return l;const h=gt(c,s);return n(c,h),h}return function(){return a(xt.apply(null,arguments))}}const k=e=>{const r=s=>s[e]||[];return r.isThemeGetter=!0,r},Me=/^\[(?:([a-z-]+):)?(.+)\]$/i,yt=/^\d+\/\d+$/,vt=new Set(["px","full","screen"]),jt=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,wt=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,Nt=/^(rgba?|hsla?|hwb|(ok)?(lab|lch))\(.+\)$/,Ct=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,kt=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,U=e=>X(e)||vt.has(e)||yt.test(e),K=e=>Q(e,"length",qt),X=e=>!!e&&!Number.isNaN(Number(e)),ae=e=>Q(e,"number",X),ee=e=>!!e&&Number.isInteger(Number(e)),St=e=>e.endsWith("%")&&X(e.slice(0,-1)),f=e=>Me.test(e),H=e=>jt.test(e),Pt=new Set(["length","size","percentage"]),Tt=e=>Q(e,Pt,Oe),It=e=>Q(e,"position",Oe),zt=new Set(["image","url"]),At=e=>Q(e,zt,Lt),Rt=e=>Q(e,"",Et),te=()=>!0,Q=(e,r,s)=>{const o=Me.exec(e);return o?o[1]?typeof r=="string"?o[1]===r:r.has(o[1]):s(o[2]):!1},qt=e=>wt.test(e)&&!Nt.test(e),Oe=()=>!1,Et=e=>Ct.test(e),Lt=e=>kt.test(e),Mt=()=>{const e=k("colors"),r=k("spacing"),s=k("blur"),o=k("brightness"),n=k("borderColor"),a=k("borderRadius"),i=k("borderSpacing"),d=k("borderWidth"),c=k("contrast"),l=k("grayscale"),h=k("hueRotate"),N=k("invert"),y=k("gap"),P=k("gradientColorStops"),g=k("gradientColorStopPositions"),m=k("inset"),p=k("margin"),C=k("opacity"),j=k("padding"),u=k("saturate"),R=k("scale"),D=k("sepia"),W=k("skew"),O=k("space"),V=k("translate"),M=()=>["auto","contain","none"],$=()=>["auto","hidden","clip","visible","scroll"],G=()=>["auto",f,r],v=()=>[f,r],x=()=>["",U,K],F=()=>["auto",X,f],T=()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],_=()=>["solid","dashed","dotted","double","none"],je=()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],oe=()=>["start","end","center","between","around","evenly","stretch"],Y=()=>["","0",f],we=()=>["auto","avoid","all","avoid-page","page","left","right","column"],J=()=>[X,f];return{cacheSize:500,separator:":",theme:{colors:[te],spacing:[U,K],blur:["none","",H,f],brightness:J(),borderColor:[e],borderRadius:["none","","full",H,f],borderSpacing:v(),borderWidth:x(),contrast:J(),grayscale:Y(),hueRotate:J(),invert:Y(),gap:v(),gradientColorStops:[e],gradientColorStopPositions:[St,K],inset:G(),margin:G(),opacity:J(),padding:v(),saturate:J(),scale:J(),sepia:Y(),skew:J(),space:v(),translate:v()},classGroups:{aspect:[{aspect:["auto","square","video",f]}],container:["container"],columns:[{columns:[H]}],"break-after":[{"break-after":we()}],"break-before":[{"break-before":we()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...T(),f]}],overflow:[{overflow:$()}],"overflow-x":[{"overflow-x":$()}],"overflow-y":[{"overflow-y":$()}],overscroll:[{overscroll:M()}],"overscroll-x":[{"overscroll-x":M()}],"overscroll-y":[{"overscroll-y":M()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:[m]}],"inset-x":[{"inset-x":[m]}],"inset-y":[{"inset-y":[m]}],start:[{start:[m]}],end:[{end:[m]}],top:[{top:[m]}],right:[{right:[m]}],bottom:[{bottom:[m]}],left:[{left:[m]}],visibility:["visible","invisible","collapse"],z:[{z:["auto",ee,f]}],basis:[{basis:G()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",f]}],grow:[{grow:Y()}],shrink:[{shrink:Y()}],order:[{order:["first","last","none",ee,f]}],"grid-cols":[{"grid-cols":[te]}],"col-start-end":[{col:["auto",{span:["full",ee,f]},f]}],"col-start":[{"col-start":F()}],"col-end":[{"col-end":F()}],"grid-rows":[{"grid-rows":[te]}],"row-start-end":[{row:["auto",{span:[ee,f]},f]}],"row-start":[{"row-start":F()}],"row-end":[{"row-end":F()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",f]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",f]}],gap:[{gap:[y]}],"gap-x":[{"gap-x":[y]}],"gap-y":[{"gap-y":[y]}],"justify-content":[{justify:["normal",...oe()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...oe(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...oe(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[j]}],px:[{px:[j]}],py:[{py:[j]}],ps:[{ps:[j]}],pe:[{pe:[j]}],pt:[{pt:[j]}],pr:[{pr:[j]}],pb:[{pb:[j]}],pl:[{pl:[j]}],m:[{m:[p]}],mx:[{mx:[p]}],my:[{my:[p]}],ms:[{ms:[p]}],me:[{me:[p]}],mt:[{mt:[p]}],mr:[{mr:[p]}],mb:[{mb:[p]}],ml:[{ml:[p]}],"space-x":[{"space-x":[O]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[O]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",f,r]}],"min-w":[{"min-w":[f,r,"min","max","fit"]}],"max-w":[{"max-w":[f,r,"none","full","min","max","fit","prose",{screen:[H]},H]}],h:[{h:[f,r,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[f,r,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[f,r,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[f,r,"auto","min","max","fit"]}],"font-size":[{text:["base",H,K]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",ae]}],"font-family":[{font:[te]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:["tighter","tight","normal","wide","wider","widest",f]}],"line-clamp":[{"line-clamp":["none",X,ae]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",U,f]}],"list-image":[{"list-image":["none",f]}],"list-style-type":[{list:["none","disc","decimal",f]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[e]}],"placeholder-opacity":[{"placeholder-opacity":[C]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[e]}],"text-opacity":[{"text-opacity":[C]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[..._(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",U,K]}],"underline-offset":[{"underline-offset":["auto",U,f]}],"text-decoration-color":[{decoration:[e]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:v()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",f]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",f]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[C]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...T(),It]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",Tt]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},At]}],"bg-color":[{bg:[e]}],"gradient-from-pos":[{from:[g]}],"gradient-via-pos":[{via:[g]}],"gradient-to-pos":[{to:[g]}],"gradient-from":[{from:[P]}],"gradient-via":[{via:[P]}],"gradient-to":[{to:[P]}],rounded:[{rounded:[a]}],"rounded-s":[{"rounded-s":[a]}],"rounded-e":[{"rounded-e":[a]}],"rounded-t":[{"rounded-t":[a]}],"rounded-r":[{"rounded-r":[a]}],"rounded-b":[{"rounded-b":[a]}],"rounded-l":[{"rounded-l":[a]}],"rounded-ss":[{"rounded-ss":[a]}],"rounded-se":[{"rounded-se":[a]}],"rounded-ee":[{"rounded-ee":[a]}],"rounded-es":[{"rounded-es":[a]}],"rounded-tl":[{"rounded-tl":[a]}],"rounded-tr":[{"rounded-tr":[a]}],"rounded-br":[{"rounded-br":[a]}],"rounded-bl":[{"rounded-bl":[a]}],"border-w":[{border:[d]}],"border-w-x":[{"border-x":[d]}],"border-w-y":[{"border-y":[d]}],"border-w-s":[{"border-s":[d]}],"border-w-e":[{"border-e":[d]}],"border-w-t":[{"border-t":[d]}],"border-w-r":[{"border-r":[d]}],"border-w-b":[{"border-b":[d]}],"border-w-l":[{"border-l":[d]}],"border-opacity":[{"border-opacity":[C]}],"border-style":[{border:[..._(),"hidden"]}],"divide-x":[{"divide-x":[d]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[d]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[C]}],"divide-style":[{divide:_()}],"border-color":[{border:[n]}],"border-color-x":[{"border-x":[n]}],"border-color-y":[{"border-y":[n]}],"border-color-s":[{"border-s":[n]}],"border-color-e":[{"border-e":[n]}],"border-color-t":[{"border-t":[n]}],"border-color-r":[{"border-r":[n]}],"border-color-b":[{"border-b":[n]}],"border-color-l":[{"border-l":[n]}],"divide-color":[{divide:[n]}],"outline-style":[{outline:["",..._()]}],"outline-offset":[{"outline-offset":[U,f]}],"outline-w":[{outline:[U,K]}],"outline-color":[{outline:[e]}],"ring-w":[{ring:x()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[e]}],"ring-opacity":[{"ring-opacity":[C]}],"ring-offset-w":[{"ring-offset":[U,K]}],"ring-offset-color":[{"ring-offset":[e]}],shadow:[{shadow:["","inner","none",H,Rt]}],"shadow-color":[{shadow:[te]}],opacity:[{opacity:[C]}],"mix-blend":[{"mix-blend":[...je(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":je()}],filter:[{filter:["","none"]}],blur:[{blur:[s]}],brightness:[{brightness:[o]}],contrast:[{contrast:[c]}],"drop-shadow":[{"drop-shadow":["","none",H,f]}],grayscale:[{grayscale:[l]}],"hue-rotate":[{"hue-rotate":[h]}],invert:[{invert:[N]}],saturate:[{saturate:[u]}],sepia:[{sepia:[D]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[s]}],"backdrop-brightness":[{"backdrop-brightness":[o]}],"backdrop-contrast":[{"backdrop-contrast":[c]}],"backdrop-grayscale":[{"backdrop-grayscale":[l]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[h]}],"backdrop-invert":[{"backdrop-invert":[N]}],"backdrop-opacity":[{"backdrop-opacity":[C]}],"backdrop-saturate":[{"backdrop-saturate":[u]}],"backdrop-sepia":[{"backdrop-sepia":[D]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":[i]}],"border-spacing-x":[{"border-spacing-x":[i]}],"border-spacing-y":[{"border-spacing-y":[i]}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["none","all","","colors","opacity","shadow","transform",f]}],duration:[{duration:J()}],ease:[{ease:["linear","in","out","in-out",f]}],delay:[{delay:J()}],animate:[{animate:["none","spin","ping","pulse","bounce",f]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[R]}],"scale-x":[{"scale-x":[R]}],"scale-y":[{"scale-y":[R]}],rotate:[{rotate:[ee,f]}],"translate-x":[{"translate-x":[V]}],"translate-y":[{"translate-y":[V]}],"skew-x":[{"skew-x":[W]}],"skew-y":[{"skew-y":[W]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",f]}],accent:[{accent:["auto",e]}],appearance:[{appearance:["none","auto"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",f]}],"caret-color":[{caret:[e]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":v()}],"scroll-mx":[{"scroll-mx":v()}],"scroll-my":[{"scroll-my":v()}],"scroll-ms":[{"scroll-ms":v()}],"scroll-me":[{"scroll-me":v()}],"scroll-mt":[{"scroll-mt":v()}],"scroll-mr":[{"scroll-mr":v()}],"scroll-mb":[{"scroll-mb":v()}],"scroll-ml":[{"scroll-ml":v()}],"scroll-p":[{"scroll-p":v()}],"scroll-px":[{"scroll-px":v()}],"scroll-py":[{"scroll-py":v()}],"scroll-ps":[{"scroll-ps":v()}],"scroll-pe":[{"scroll-pe":v()}],"scroll-pt":[{"scroll-pt":v()}],"scroll-pr":[{"scroll-pr":v()}],"scroll-pb":[{"scroll-pb":v()}],"scroll-pl":[{"scroll-pl":v()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",f]}],fill:[{fill:[e,"none"]}],"stroke-w":[{stroke:[U,K,ae]}],stroke:[{stroke:[e,"none"]}],sr:["sr-only","not-sr-only"],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]}}},Ot=bt(Mt);function w(...e){return Ot(Ae(e))}const Ft=Re("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 hover-elevate active-elevate-2",{variants:{variant:{default:"bg-primary text-primary-foreground border border-primary-border",destructive:"bg-destructive text-destructive-foreground border border-destructive-border",outline:" border [border-color:var(--button-outline)] shadow-xs active:shadow-none ",secondary:"border bg-secondary text-secondary-foreground border border-secondary-border ",ghost:"border border-transparent"},size:{default:"min-h-9 px-4 py-2",sm:"min-h-8 rounded-md px-3 text-xs",lg:"min-h-10 rounded-md px-8",icon:"h-9 w-9"}},defaultVariants:{variant:"default",size:"default"}}),E=S.forwardRef(({className:e,variant:r,size:s,asChild:o=!1,...n},a)=>{const i=o?et.Slot:"button";return t.jsx(i,{className:w(Ft({variant:r,size:s,className:e})),ref:a,...n})});E.displayName="Button";const L=S.forwardRef(({className:e,type:r,...s},o)=>t.jsx("input",{type:r,className:w("flex h-9 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",e),ref:o,...s}));L.displayName="Input";const Dt=se.Provider,Vt=se.Root,_t=se.Trigger,Fe=S.forwardRef(({className:e,sideOffset:r=4,...s},o)=>t.jsx(se.Content,{ref:o,sideOffset:r,className:w("z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-tooltip-content-transform-origin]",e),...s}));Fe.displayName=se.Content.displayName;const Bt=B.Root,Gt=B.Portal,De=S.forwardRef(({className:e,...r},s)=>t.jsx(B.Overlay,{ref:s,className:w("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",e),...r}));De.displayName=B.Overlay.displayName;const Ve=S.forwardRef(({className:e,children:r,...s},o)=>t.jsxs(Gt,{children:[t.jsx(De,{}),t.jsxs(B.Content,{ref:o,className:w("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",e),...s,children:[r,t.jsxs(B.Close,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",children:[t.jsx(b.X,{className:"h-4 w-4"}),t.jsx("span",{className:"sr-only",children:"Close"})]})]})]}));Ve.displayName=B.Content.displayName;const _e=({className:e,...r})=>t.jsx("div",{className:w("flex flex-col space-y-1.5 text-center sm:text-left",e),...r});_e.displayName="DialogHeader";const Be=({className:e,...r})=>t.jsx("div",{className:w("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",e),...r});Be.displayName="DialogFooter";const Ge=S.forwardRef(({className:e,...r},s)=>t.jsx(B.Title,{ref:s,className:w("text-lg font-semibold leading-none tracking-tight",e),...r}));Ge.displayName=B.Title.displayName;const $t=S.forwardRef(({className:e,...r},s)=>t.jsx(B.Description,{ref:s,className:w("text-sm text-muted-foreground",e),...r}));$t.displayName=B.Description.displayName;const Jt=Re("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"),z=S.forwardRef(({className:e,...r},s)=>t.jsx(Ie.Root,{ref:s,className:w(Jt(),e),...r}));z.displayName=Ie.Root.displayName;const Pe=A.Root,Te=A.Value,de=S.forwardRef(({className:e,children:r,...s},o)=>t.jsxs(A.Trigger,{ref:o,className:w("flex h-9 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background data-[placeholder]:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",e),...s,children:[r,t.jsx(A.Icon,{asChild:!0,children:t.jsx(b.ChevronDown,{className:"h-4 w-4 opacity-50"})})]}));de.displayName=A.Trigger.displayName;const $e=S.forwardRef(({className:e,...r},s)=>t.jsx(A.ScrollUpButton,{ref:s,className:w("flex cursor-default items-center justify-center py-1",e),...r,children:t.jsx(b.ChevronUp,{className:"h-4 w-4"})}));$e.displayName=A.ScrollUpButton.displayName;const Je=S.forwardRef(({className:e,...r},s)=>t.jsx(A.ScrollDownButton,{ref:s,className:w("flex cursor-default items-center justify-center py-1",e),...r,children:t.jsx(b.ChevronDown,{className:"h-4 w-4"})}));Je.displayName=A.ScrollDownButton.displayName;const ce=S.forwardRef(({className:e,children:r,position:s="popper",...o},n)=>t.jsx(A.Portal,{children:t.jsxs(A.Content,{ref:n,className:w("relative z-50 max-h-[--radix-select-content-available-height] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-select-content-transform-origin]",s==="popper"&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",e),position:s,...o,children:[t.jsx($e,{}),t.jsx(A.Viewport,{className:w("p-1",s==="popper"&&"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),children:r}),t.jsx(Je,{})]})}));ce.displayName=A.Content.displayName;const Ut=S.forwardRef(({className:e,...r},s)=>t.jsx(A.Label,{ref:s,className:w("py-1.5 pl-8 pr-2 text-sm font-semibold",e),...r}));Ut.displayName=A.Label.displayName;const q=S.forwardRef(({className:e,children:r,...s},o)=>t.jsxs(A.Item,{ref:o,className:w("relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",e),...s,children:[t.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:t.jsx(A.ItemIndicator,{children:t.jsx(b.Check,{className:"h-4 w-4"})})}),t.jsx(A.ItemText,{children:r})]}));q.displayName=A.Item.displayName;const Wt=S.forwardRef(({className:e,...r},s)=>t.jsx(A.Separator,{ref:s,className:w("-mx-1 my-1 h-px bg-muted",e),...r}));Wt.displayName=A.Separator.displayName;const me=S.forwardRef(({className:e,...r},s)=>t.jsx(ie.Root,{ref:s,className:w("peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",e),...r,children:t.jsx(ie.Indicator,{className:w("flex items-center justify-center text-current"),children:t.jsx(b.Check,{className:"h-4 w-4"})})}));me.displayName=ie.Root.displayName;const xe=S.forwardRef(({className:e,...r},s)=>t.jsx("textarea",{className:w("flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",e),ref:s,...r}));xe.displayName="Textarea";const Kt=e=>e.trim().toLowerCase().replace(/[^\w\s]/g,"").replace(/\s+/g,"_"),Ue=(e,r,s=!1)=>{const o=(c,l)=>{r({...e,[c]:l})};return{handleTitleChange:c=>{o("title",c)},handleTitleBlur:()=>{if(s&&e.title){const c=Kt(e.title);o("key",c)}},handleKeyChange:c=>{s&&o("key",c)},handleFieldChange:o,handleConstraintChange:(c,l)=>{r({...e,[c]:l})}}},ue={string:"String",number:"Number",integer:"Integer",boolean:"Boolean",object:"Object",array:"Array",null:"Null",file:"File"},We=I.createContext({getTypeLabel:e=>ue[e],typeLabels:ue});function Ht({children:e,customLabels:r={}}){const s={...ue,...r},o=n=>s[n]||n;return t.jsx(We.Provider,{value:{getTypeLabel:o,typeLabels:s},children:e})}function Ke(){return I.useContext(We)}function re({property:e,open:r,onOpenChange:s,onUpdate:o,isArrayItem:n=!1,isNewProperty:a=!1,propertyLabel:i={singular:"Property",plural:"Properties"},showRegex:d=!1}){var j;const{typeLabels:c}=Ke(),[l,h]=I.useState(e);I.useEffect(()=>{r&&h(e)},[e,r]);const{handleTitleChange:N,handleTitleBlur:y,handleKeyChange:P,handleFieldChange:g,handleConstraintChange:m}=Ue(l,h,a),p=()=>{var u;(u=l.title)!=null&&u.trim()&&(o(l),s(!1))},C=()=>{h(e),s(!1)};return t.jsx(Bt,{open:r,onOpenChange:s,children:t.jsxs(Ve,{className:"max-w-2xl max-h-[80vh] flex flex-col gap-0 p-0","data-testid":"dialog-edit-property",children:[t.jsx(_e,{className:"px-6 pt-6 pb-4 shrink-0",children:t.jsx(Ge,{children:a?`Add ${i.singular}`:`Edit ${i.singular}`})}),t.jsxs("div",{className:"space-y-6 px-6 pb-4 overflow-y-auto flex-1 min-h-0",children:[t.jsxs("div",{className:"space-y-2",children:[t.jsxs(z,{className:"flex items-center gap-1.5",children:[t.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-red-500"}),"Type"]}),t.jsxs(Pe,{value:l.type,onValueChange:u=>g("type",u),"data-testid":"select-type-dialog",children:[t.jsx(de,{children:t.jsx(Te,{})}),t.jsxs(ce,{children:[t.jsx(q,{value:"string",children:c.string}),t.jsx(q,{value:"number",children:c.number}),t.jsx(q,{value:"integer",children:c.integer}),t.jsx(q,{value:"boolean",children:c.boolean}),t.jsx(q,{value:"object",children:c.object}),t.jsx(q,{value:"array",children:c.array}),t.jsx(q,{value:"file",children:c.file}),t.jsx(q,{value:"null",children:c.null})]})]})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsxs(z,{className:"flex items-center gap-1.5",children:[t.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-red-500"}),"Title"]}),t.jsx(L,{value:l.title||"",onChange:u=>N(u.target.value),onBlur:y,placeholder:"Property Title","data-testid":"input-title-dialog",required:!0}),!a&&l.key&&t.jsxs("p",{className:"text-xs text-muted-foreground font-mono",children:["Key: ",l.key]})]}),a&&t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{children:"Key"}),t.jsx(L,{value:l.key,onChange:u=>P(u.target.value),placeholder:"property_key","data-testid":"input-key-dialog"})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{children:"Description"}),t.jsx(xe,{placeholder:"Optional description",value:l.description||"",onChange:u=>g("description",u.target.value),rows:2,"data-testid":"input-edit-description"})]}),l.type==="array"&&t.jsxs("div",{className:"space-y-2 border-l-2 border-border pl-4 mt-2",children:[t.jsxs(z,{className:"font-semibold text-xs text-muted-foreground",children:[c.array," Items"]}),l.items?t.jsxs("div",{className:"bg-muted/40 p-2 rounded",children:[t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{children:"Item Type"}),t.jsxs(Pe,{value:l.items.type,onValueChange:u=>h({...l,items:{...l.items,type:u}}),children:[t.jsx(de,{children:t.jsx(Te,{})}),t.jsxs(ce,{children:[t.jsx(q,{value:"string",children:c.string}),t.jsx(q,{value:"number",children:c.number}),t.jsx(q,{value:"integer",children:c.integer}),t.jsx(q,{value:"boolean",children:c.boolean}),t.jsx(q,{value:"object",children:c.object}),t.jsx(q,{value:"array",children:c.array}),t.jsx(q,{value:"file",children:c.file}),t.jsx(q,{value:"null",children:c.null})]})]})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{children:"Item Title"}),t.jsx(L,{value:l.items.title||"",onChange:u=>h({...l,items:{...l.items,title:u.target.value}}),placeholder:"Item Title"})]}),t.jsxs(E,{variant:"ghost",size:"sm",className:"mt-2",onClick:()=>h({...l,items:void 0}),children:["Remove ",c.array," Item Schema"]})]}):t.jsxs(E,{variant:"outline",size:"sm",onClick:()=>{h({...l,items:{id:Date.now().toString()+Math.random(),key:"item",type:"string",required:!1}})},children:["Add ",c.array," Item Schema"]})]}),!n&&t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(me,{id:"prop-required",checked:l.required,onCheckedChange:u=>g("required",u),"data-testid":"checkbox-edit-required"}),t.jsx(z,{htmlFor:"prop-required",className:"cursor-pointer",children:"Required field"})]}),l.type==="string"&&t.jsxs("details",{className:"border rounded-md",children:[t.jsx("summary",{className:"p-4 cursor-pointer hover:bg-accent/50 transition-colors",children:t.jsxs("h4",{className:"text-sm font-medium inline",children:[c.string," Constraints"]})}),t.jsxs("div",{className:"space-y-4 p-4 pt-0",children:[t.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"min-length",children:"Minimum Length"}),t.jsx(L,{id:"min-length",type:"number",placeholder:"0",value:l.minLength||"",onChange:u=>m("minLength",u.target.value?parseInt(u.target.value):void 0),"data-testid":"input-edit-minlength"})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"max-length",children:"Maximum Length"}),t.jsx(L,{id:"max-length",type:"number",placeholder:"∞",value:l.maxLength||"",onChange:u=>m("maxLength",u.target.value?parseInt(u.target.value):void 0),"data-testid":"input-edit-maxlength"})]})]}),d&&t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"pattern",children:"Pattern (regex)"}),t.jsx(L,{id:"pattern",placeholder:"^[a-z]+$",value:l.pattern||"",onChange:u=>m("pattern",u.target.value),className:"font-mono text-sm","data-testid":"input-edit-pattern"})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{children:"Enum Values"}),t.jsx("div",{className:"space-y-2",children:[...l.enum||[],""].map((u,R)=>{var D;return t.jsx(L,{placeholder:R===(((D=l.enum)==null?void 0:D.length)||0)?"Add new value...":"Enum value",value:u,onChange:W=>{const O=W.target.value,V=l.enum||[];if(R===V.length)O.trim()&&m("enum",[...V,O.trim()]);else if(O.trim()){const M=[...V];M[R]=O.trim(),m("enum",M)}else{const M=V.filter(($,G)=>G!==R);m("enum",M.length>0?M:void 0)}},"data-testid":`input-edit-enum-${R}`},R)})}),t.jsx("p",{className:"text-xs text-muted-foreground",children:"Enter allowed values (empty fields will be removed)"})]})]})]}),(l.type==="number"||l.type==="integer")&&t.jsxs("details",{className:"border rounded-md",children:[t.jsx("summary",{className:"p-4 cursor-pointer hover:bg-accent/50 transition-colors",children:t.jsx("h4",{className:"text-sm font-medium inline",children:"Numeric Constraints"})}),t.jsx("div",{className:"space-y-4 p-4 pt-0",children:t.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"minimum",children:"Minimum Value"}),t.jsx(L,{id:"minimum",type:"number",placeholder:"-∞",value:l.minimum??"",onChange:u=>m("minimum",u.target.value?parseFloat(u.target.value):void 0),"data-testid":"input-edit-minimum"})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"maximum",children:"Maximum Value"}),t.jsx(L,{id:"maximum",type:"number",placeholder:"∞",value:l.maximum??"",onChange:u=>m("maximum",u.target.value?parseFloat(u.target.value):void 0),"data-testid":"input-edit-maximum"})]})]})})]}),l.type==="array"&&t.jsxs("details",{className:"border rounded-md",children:[t.jsx("summary",{className:"p-4 cursor-pointer hover:bg-accent/50 transition-colors",children:t.jsxs("h4",{className:"text-sm font-medium inline",children:[c.array," Constraints"]})}),t.jsxs("div",{className:"space-y-4 p-4 pt-0",children:[t.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"min-items",children:"Minimum Items"}),t.jsx(L,{id:"min-items",type:"number",placeholder:"0",value:l.minItems||"",onChange:u=>m("minItems",u.target.value?parseInt(u.target.value):void 0),"data-testid":"input-edit-minitems"})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"max-items",children:"Maximum Items"}),t.jsx(L,{id:"max-items",type:"number",placeholder:"∞",value:l.maxItems||"",onChange:u=>m("maxItems",u.target.value?parseInt(u.target.value):void 0),"data-testid":"input-edit-maxitems"})]})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(me,{id:"unique-items",checked:l.uniqueItems||!1,onCheckedChange:u=>m("uniqueItems",u),"data-testid":"checkbox-edit-unique"}),t.jsx(z,{htmlFor:"unique-items",className:"cursor-pointer",children:"All items must be unique"})]})]})]})]}),t.jsxs(Be,{className:"px-6 py-4 border-t bg-background shrink-0",children:[t.jsx(E,{variant:"outline",onClick:C,"data-testid":"button-cancel",children:"Cancel"}),t.jsx(E,{onClick:p,"data-testid":"button-save",disabled:!((j=l.title)!=null&&j.trim()),children:"Save Changes"})]})]})})}const be=()=>`${Date.now()}-${Math.random()}`;function ne({property:e,onUpdate:r,onDelete:s,level:o=1,isArrayItem:n=!1,showRegex:a=!1}){const{getTypeLabel:i}=Ke(),[d,c]=I.useState(!1),[l,h]=I.useState(null),[N,y]=I.useState(!1),[P,g]=I.useState(!1),[m,p]=I.useState(e.title||"");I.useEffect(()=>{P||p(e.title||"")},[e.title,P]);const C=`h${Math.min(o,6)}`,j=e.type==="object",u=j&&e.children&&e.children.length>0,R={1:"text-xl",2:"text-base",3:"text-base",4:"text-base",5:"text-sm",6:"text-sm"}[o]||"text-sm",D=(x,F)=>{const T=e.children.map(_=>_.id===x?F:_);r({...e,children:T})},W=x=>{const F=e.children.filter(T=>T.id!==x);r({...e,children:F})},O=()=>{const x={id:be(),key:"",type:"string",required:!1};h(x),y(!0)},V=x=>{r({...e,children:[...e.children||[],x]}),y(!1),h(null)},M=()=>{y(!1),h(null)},$=()=>{const x=e.title||e.key||"";p(x),g(!0)},G=()=>{const x=m.trim();if(!x){p(e.title||""),g(!1);return}x!==e.title&&r({...e,title:x}),g(!1)},v=x=>{x.key==="Enter"?G():x.key==="Escape"&&(p(e.title||""),g(!1))};return t.jsxs("div",{className:"group",children:[t.jsxs("div",{className:"flex gap-4 items-center rounded-md -mx-2 px-2 py-1 transition-colors hover:bg-accent/50",children:[t.jsx("div",{className:"flex-1 min-w-0",children:t.jsxs("div",{className:"flex items-start gap-3",children:[!n&&t.jsx("button",{onClick:()=>r({...e,required:!e.required}),className:"shrink-0 transition-all hover:scale-110 mt-0.5",title:e.required?"Required field - click to make optional":"Optional field - click to make required",children:e.required?t.jsx("span",{className:"block w-4 h-4 rounded-full bg-primary"}):t.jsx("span",{className:"block w-4 h-4 rounded-full border border-dashed border-gray-400"})}),P?t.jsx(L,{value:m,onChange:x=>p(x.target.value),onBlur:G,onKeyDown:v,autoFocus:!0,className:R,placeholder:"Enter title"}):t.jsxs("div",{className:"flex gap-2 flex-wrap",children:[t.jsxs("div",{className:"flex items-start gap-2",children:[t.jsx(C,{className:`${R} font-medium cursor-pointer hover:text-primary transition-colors leading-none`,onClick:$,children:e.title||e.key||t.jsx("span",{className:"text-muted-foreground italic",children:"unnamed"})}),t.jsx(Dt,{children:t.jsxs(Vt,{children:[t.jsx(_t,{asChild:!0,children:t.jsxs("span",{children:[e.type==="string"&&t.jsx(b.Type,{className:"w-5 h-5 text-muted-foreground"}),e.type==="number"&&t.jsx(b.Hash,{className:"w-5 h-5 text-muted-foreground"}),e.type==="integer"&&t.jsx(b.Hash,{className:"w-5 h-5 text-muted-foreground"}),e.type==="boolean"&&t.jsx(b.CheckSquare,{className:"w-5 h-5 text-muted-foreground"}),e.type==="object"&&t.jsx(b.Braces,{className:"w-5 h-5 text-muted-foreground"}),e.type==="array"&&t.jsx(b.List,{className:"w-5 h-5 text-muted-foreground"}),e.type==="file"&&t.jsx(b.FileText,{className:"w-5 h-5 text-muted-foreground"})]})}),t.jsxs(Fe,{side:"top",children:[i(e.type),e.type==="array"&&e.items?` of ${i(e.items.type)}`:""]})]})}),e.type==="object"&&t.jsx(E,{variant:"ghost",size:"icon",className:"opacity-0 group-hover:opacity-100 h-6 w-6",onClick:O,"data-testid":`button-add-child-${e.id}`,children:t.jsx(b.Plus,{className:"!w-5 !h-5"})})]}),e.description&&t.jsx("p",{className:"text-sm text-muted-foreground flex-1 min-w-[200px]","data-testid":`text-description-${e.id}`,children:e.description})]})]})}),t.jsxs("div",{className:"flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity shrink-0",children:[t.jsx(E,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:()=>c(!0),"data-testid":`button-edit-${e.id}`,children:t.jsx(b.Pencil,{className:"w-3 h-3"})}),j&&e.type!=="object"&&t.jsx(E,{variant:"ghost",size:"icon",className:"h-7 w-7",onClick:O,"data-testid":`button-add-child-${e.id}`,children:t.jsx(b.Plus,{className:"w-3 h-3"})}),t.jsx(E,{variant:"ghost",size:"icon",className:"h-7 w-7 text-muted-foreground hover:text-destructive",onClick:s,"data-testid":`button-delete-${e.id}`,children:t.jsx(b.Trash2,{className:"w-3 h-3"})})]})]}),u&&t.jsx("div",{className:o===1?"ml-6 mt-1 border-l-2 border-border pl-6":"ml-4 mt-1 border-l border-border pl-4",children:e.children.map(x=>t.jsx(ne,{property:x,onUpdate:F=>D(x.id,F),onDelete:()=>W(x.id),level:o+1,showRegex:a},x.id))}),e.type==="array"&&e.items&&t.jsxs("div",{className:o===1?"ml-6 mt-1 border-l-2 border-border pl-6":"ml-4 mt-1 border-l border-border pl-4",children:[t.jsxs("div",{className:"mb-2 text-xs text-muted-foreground font-semibold uppercase",children:[i("array")," Items"]}),t.jsx(ne,{property:e.items,onUpdate:x=>r({...e,items:x}),onDelete:()=>r({...e,items:void 0}),level:o+1,isArrayItem:!0,showRegex:a})]}),t.jsx(re,{property:e,open:d,onOpenChange:c,onUpdate:r,isArrayItem:n,isNewProperty:!1,showRegex:a}),N&&l&&t.jsx(re,{property:l,open:N,isNewProperty:!0,onOpenChange:x=>{x||M()},onUpdate:V,showRegex:a})]})}const ye=S.forwardRef(({className:e,...r},s)=>t.jsx("div",{ref:s,className:w("shadcn-card rounded-xl border bg-card border-card-border text-card-foreground shadow-sm",e),...r}));ye.displayName="Card";const Xt=S.forwardRef(({className:e,...r},s)=>t.jsx("div",{ref:s,className:w("flex flex-col space-y-1.5 p-6",e),...r}));Xt.displayName="CardHeader";const Zt=S.forwardRef(({className:e,...r},s)=>t.jsx("div",{ref:s,className:w("text-2xl font-semibold leading-none tracking-tight",e),...r}));Zt.displayName="CardTitle";const Qt=S.forwardRef(({className:e,...r},s)=>t.jsx("div",{ref:s,className:w("text-sm text-muted-foreground",e),...r}));Qt.displayName="CardDescription";const Yt=S.forwardRef(({className:e,...r},s)=>t.jsx("div",{ref:s,className:w("p-6 pt-0",e),...r}));Yt.displayName="CardContent";const es=S.forwardRef(({className:e,...r},s)=>t.jsx("div",{ref:s,className:w("flex items-center p-6 pt-0",e),...r}));es.displayName="CardFooter";const He=()=>new Promise((e,r)=>{const s=document.createElement("input");s.type="file",s.accept=".json",s.onchange=o=>{var i;const n=(i=o.target.files)==null?void 0:i[0];if(!n){r(new Error("No file selected"));return}const a=new FileReader;a.onload=d=>{var c;try{const l=JSON.parse((c=d.target)==null?void 0:c.result);e(l)}catch{r(new Error("Invalid JSON file"))}},a.onerror=()=>r(new Error("Failed to read file")),a.readAsText(n)},s.click()}),ve=(e,r="schema.json")=>{const s=JSON.stringify(e,null,2),o=new Blob([s],{type:"application/json"}),n=URL.createObjectURL(o),a=document.createElement("a");a.href=n,a.download=r,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(n)};function Xe({schema:e}){const[r,s]=I.useState(!1),o=JSON.stringify(e,null,2),n=async()=>{await navigator.clipboard.writeText(o),s(!0),setTimeout(()=>s(!1),2e3)},a=()=>{ve(e,"schema.json")};return t.jsxs("div",{className:"h-full flex flex-col",children:[t.jsxs("div",{className:"flex items-center justify-between p-4 border-b",children:[t.jsx("h2",{className:"text-sm font-medium",children:"JSON Schema Output"}),t.jsxs("div",{className:"flex gap-2",children:[t.jsx(E,{variant:"outline",size:"sm",onClick:n,"data-testid":"button-copy",children:r?t.jsx(b.CheckCircle2,{className:"w-4 h-4"}):t.jsx(b.Copy,{className:"w-4 h-4"})}),t.jsx(E,{variant:"outline",size:"sm",onClick:a,"data-testid":"button-download",children:t.jsx(b.Download,{className:"w-4 h-4"})})]})]}),t.jsx("div",{className:"flex-1 overflow-auto",children:t.jsx(ye,{className:"m-4 bg-muted/30",children:t.jsx("pre",{className:"p-6 text-xs font-mono overflow-auto","data-testid":"text-json-output",children:t.jsx("code",{children:o})})})})]})}function Ze({title:e,description:r,version:s,onUpdate:o}){const[n,a]=I.useState(!1);return t.jsxs(ye,{className:"p-4",children:[t.jsxs(E,{variant:"ghost",onClick:()=>a(!n),className:"w-full justify-between px-2 h-auto hover:bg-transparent","data-testid":"button-toggle-metadata",children:[t.jsx("h3",{className:"text-sm font-medium",children:"Schema Metadata"}),n?t.jsx(b.ChevronDown,{className:"w-4 h-4"}):t.jsx(b.ChevronRight,{className:"w-4 h-4"})]}),n&&t.jsxs("div",{className:"mt-4 space-y-4",children:[t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"schema-title",className:"text-xs text-muted-foreground",children:"Title"}),t.jsx(L,{id:"schema-title",placeholder:"My Schema",value:e,onChange:i=>o("title",i.target.value),"data-testid":"input-title"})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"schema-description",className:"text-xs text-muted-foreground",children:"Description"}),t.jsx(xe,{id:"schema-description",placeholder:"Describe your schema...",value:r,onChange:i=>o("description",i.target.value),className:"resize-none",rows:3,"data-testid":"input-schema-description"})]}),t.jsxs("div",{className:"space-y-2",children:[t.jsx(z,{htmlFor:"schema-version",className:"text-xs text-muted-foreground",children:"Version"}),t.jsx(L,{id:"schema-version",placeholder:"1.0.0",value:s,onChange:i=>o("version",i.target.value),"data-testid":"input-version"})]})]})]})}const Qe=(e,r,s=!0)=>{const o={type:"object"};s&&r&&(r.title&&(o.title=r.title),r.description&&(o.description=r.description));const n=pe(e);Object.keys(n).length>0&&(o.properties=n);const a=e.filter(i=>i.required&&i.key).map(i=>i.key);return a.length>0&&(o.required=a),o},pe=e=>{const r={};return e.forEach(s=>{if(!s.key)return;const n={type:s.type==="file"?"string":s.type};if(s.title&&(n.title=s.title),s.description&&(n.description=s.description),s.type==="file"&&(n.format="filename"),s.type==="string"&&(s.minLength!==void 0&&(n.minLength=s.minLength),s.maxLength!==void 0&&(n.maxLength=s.maxLength),s.pattern&&(n.pattern=s.pattern),s.enum&&s.enum.length>0&&(n.enum=s.enum)),(s.type==="number"||s.type==="integer")&&(s.minimum!==void 0&&(n.minimum=s.minimum),s.maximum!==void 0&&(n.maximum=s.maximum)),s.type==="array"&&(s.minItems!==void 0&&(n.minItems=s.minItems),s.maxItems!==void 0&&(n.maxItems=s.maxItems),s.uniqueItems&&(n.uniqueItems=s.uniqueItems),s.items&&(n.items=pe([s.items])[s.items.key]||{type:s.items.type})),s.type==="object"&&s.children&&s.children.length>0){n.properties=pe(s.children);const a=s.children.filter(i=>i.required&&i.key).map(i=>i.key);a.length>0&&(n.required=a)}r[s.key]=n}),r},he=e=>{const r={properties:[]};return(e.title||e.description)&&(r.metadata={title:typeof e.title=="string"?e.title:"",description:typeof e.description=="string"?e.description:"",version:"1.0.0"}),e.properties&&typeof e.properties=="object"&&(r.properties=fe(e.properties,Array.isArray(e.required)?e.required:[])),r},fe=(e,r=[])=>e?Object.entries(e).filter(([,s])=>typeof s=="object").map(([s,o])=>{const n=o;let a=typeof n.type=="string"?n.type:"string";a==="string"&&n.format==="filename"&&(a="file");const i={id:be(),key:s,title:typeof n.title=="string"?n.title:void 0,type:a,description:typeof n.description=="string"?n.description:void 0,required:r.includes(s)};return n.minLength!==void 0&&(i.minLength=n.minLength),n.maxLength!==void 0&&(i.maxLength=n.maxLength),n.pattern&&(i.pattern=n.pattern),n.enum&&Array.isArray(n.enum)&&(i.enum=n.enum),n.minimum!==void 0&&(i.minimum=n.minimum),n.maximum!==void 0&&(i.maximum=n.maximum),n.minItems!==void 0&&(i.minItems=n.minItems),n.maxItems!==void 0&&(i.maxItems=n.maxItems),n.uniqueItems&&(i.uniqueItems=n.uniqueItems),i.type==="array"&&n.items&&typeof n.items=="object"&&!Array.isArray(n.items)&&(i.items=fe({item:n.items},[]).find(d=>d.key==="item")),n.properties&&typeof n.properties=="object"&&(i.children=fe(n.properties,Array.isArray(n.required)?n.required:[])),i}):[],Ye=(e=!0)=>{const[r,s]=I.useState([]),[o,n]=I.useState({title:"",description:"",version:""}),a=I.useMemo(()=>Qe(r,o,e),[r,o,e]);return{properties:r,metadata:o,schema:a,addProperty:()=>({id:be(),key:"",type:"string",required:!1}),updateProperty:(g,m)=>{s(p=>p.some(j=>j.id===g)?p.map(j=>j.id===g?m:j):[...p,m])},deleteProperty:g=>{s(m=>m.filter(p=>p.id!==g))},clearAll:()=>{s([]),n({title:"",description:"",version:""})},updateMetadata:(g,m)=>{n(p=>({...p,[g]:m}))},importSchema:async()=>{const g=await He(),m=he(g);s(m.properties),m.metadata&&e&&n(m.metadata)},downloadSchema:()=>{ve(a,"schema.json")},loadSchema:g=>{const m=he(g);s(m.properties),m.metadata&&e&&n(m.metadata)}}};function ts(){const[e,r]=I.useState("light");I.useEffect(()=>{const n=localStorage.getItem("theme")||(window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light");r(n),document.documentElement.classList.toggle("dark",n==="dark")},[]);const s=()=>{const o=e==="light"?"dark":"light";r(o),localStorage.setItem("theme",o),document.documentElement.classList.toggle("dark",o==="dark")};return t.jsx(E,{variant:"ghost",size:"icon",onClick:s,"data-testid":"button-theme-toggle",children:e==="light"?t.jsx(b.Moon,{className:"w-4 h-4"}):t.jsx(b.Sun,{className:"w-4 h-4"})})}function ss({initialSchema:e,onSchemaChange:r,showMetadata:s=!1,showImport:o=!0,showClear:n=!0,showOutput:a=!0,showHeader:i=!0,className:d="h-screen",showSummary:c=!1,typeLabels:l,propertyLabel:h={singular:"property",plural:"properties"},showRegex:N=!1}){const[y,P]=I.useState(null),[g,m]=I.useState(!1),{properties:p,metadata:C,schema:j,addProperty:u,updateProperty:R,deleteProperty:D,clearAll:W,updateMetadata:O,importSchema:V,loadSchema:M}=Ye(s);I.useEffect(()=>{r&&r(j)},[j]),I.useEffect(()=>{e&&M(e)},[e]);const $=()=>{const T=u();P(T),m(!0)},G=T=>{R(T.id,T),m(!1),P(null)},v=()=>{m(!1),P(null)},x=()=>{W()},F=async()=>{await V()};return t.jsx(Ht,{customLabels:l,children:t.jsxs("div",{className:`${d} flex flex-col`,children:[i&&t.jsx("header",{className:"h-16 border-b flex items-center justify-between px-6",children:t.jsxs("div",{className:"flex items-center gap-3",children:[o&&t.jsx(E,{variant:"outline",size:"sm",onClick:F,"data-testid":"button-import",children:t.jsx(b.Upload,{className:"w-4 h-4"})}),n&&t.jsx(E,{variant:"outline",size:"sm",onClick:x,disabled:p.length===0,"data-testid":"button-clear",children:t.jsx(b.Trash2,{className:"w-4 h-4"})}),t.jsx(ts,{})]})}),t.jsxs("div",{className:"flex-1 flex overflow-hidden",children:[t.jsx("div",{className:a?"w-3/5 border-r":"w-full",children:t.jsxs("div",{className:"h-full overflow-auto p-6 space-y-4",children:[s&&t.jsx(Ze,{title:C.title,description:C.description,version:C.version,onUpdate:(T,_)=>O(T,_)}),p.length===0?t.jsxs("div",{className:"flex flex-col items-center justify-center py-16 text-center",children:[t.jsx("div",{className:"w-16 h-16 rounded-full bg-muted flex items-center justify-center mb-4",children:t.jsx(b.Plus,{className:"w-8 h-8 text-muted-foreground"})}),t.jsxs("h2",{className:"text-lg font-medium mb-2",children:["No ",h.plural," yet"]}),t.jsxs("p",{className:"text-sm text-muted-foreground mb-6 max-w-sm",children:["Start building your JSON schema by adding your first"," ",h.singular]}),t.jsxs(E,{onClick:$,"data-testid":"button-add-first",children:[t.jsx(b.Plus,{className:"w-4 h-4 mr-2"}),"Add ",h.singular]})]}):t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"space-y-1",children:p.map(T=>t.jsx(ne,{property:T,onUpdate:_=>R(T.id,_),onDelete:()=>D(T.id),showRegex:N},T.id))}),t.jsx("div",{className:"pt-6",children:t.jsxs(E,{onClick:$,className:"w-full",variant:"outline","data-testid":"button-add-property",children:[t.jsx(b.Plus,{className:"w-4 h-4 mr-2"}),"Add ",h.singular]})}),c&&t.jsxs("div",{className:"pt-4 border-t flex items-center justify-between text-sm text-muted-foreground",children:[t.jsxs("span",{children:[p.length," ",p.length===1?h.singular:h.plural]}),t.jsxs("span",{children:[p.filter(T=>T.required).length," required"]})]})]})]})}),a&&t.jsx("div",{className:"w-2/5",children:t.jsx(Xe,{schema:j})})]}),g&&y&&t.jsx(re,{property:y,open:g,isNewProperty:!0,onOpenChange:T=>{T||v()},propertyLabel:h,onUpdate:G,showRegex:N})]})})}exports.JsonOutput=Xe;exports.JsonSchemaBuilder=ss;exports.PropertyDocument=ne;exports.PropertyEditDialog=re;exports.SchemaMetadataComponent=Ze;exports.downloadJsonFile=ve;exports.generateSchema=Qe;exports.importJsonFile=He;exports.parseSchema=he;exports.usePropertyEditor=Ue;exports.useSchemaBuilder=Ye;
2
+ //# sourceMappingURL=index.cjs.map