diff --git a/.claude/skills/create-component/SKILL.md b/.claude/skills/create-component/SKILL.md
deleted file mode 100644
index cfca3edaf4..0000000000
--- a/.claude/skills/create-component/SKILL.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-name: create-component
-description: Scaffold a new Skeleton component.
----
-
-Inform the user this skill is not yet available.
diff --git a/.claude/skills/create-functional-component/SKILL.md b/.claude/skills/create-functional-component/SKILL.md
new file mode 100644
index 0000000000..c50d2a3ecd
--- /dev/null
+++ b/.claude/skills/create-functional-component/SKILL.md
@@ -0,0 +1,73 @@
+---
+name: create-functional-component
+description: Create Skeleton functional components in both React and Svelte packages using the repository's anatomy/modules conventions.
+---
+
+# Create Functional Component
+
+Scaffold a new framework component in both Skeleton packages using the existing anatomy/modules authoring style.
+
+## Where things live
+
+- React components: [packages/skeleton-react/src/components/](packages/skeleton-react/src/components/)
+- Svelte components: [packages/skeleton-svelte/src/components/](packages/skeleton-svelte/src/components/)
+- React component tests: [packages/skeleton-react/test/components/](packages/skeleton-react/test/components/)
+- Svelte component tests: [packages/skeleton-svelte/test/components/](packages/skeleton-svelte/test/components/)
+- Public package exports: [packages/skeleton-react/src/index.ts](packages/skeleton-react/src/index.ts), [packages/skeleton-svelte/src/index.ts](packages/skeleton-svelte/src/index.ts)
+- Reference components to model after:
+ - Static/non-machine: [app-bar](packages/skeleton-react/src/components/app-bar/index.ts), [app-bar](packages/skeleton-svelte/src/components/app-bar/index.ts)
+ - Machine-backed: [accordion](packages/skeleton-react/src/components/accordion/index.ts), [accordion](packages/skeleton-svelte/src/components/accordion/index.ts)
+
+## File destination rules
+
+Recommend structure based on component complexity, explain the reasoning, accept overrides.
+
+- **Simple/static component** → create `anatomy/*`, `modules/anatomy.ts`, and `index.ts` in both framework folders.
+- **Machine-backed component** → add provider/context modules in both frameworks:
+ - React: `modules/provider.ts`, context files as needed.
+ - Svelte: `modules/provider.svelte.ts`, context files as needed.
+- **Always mirror APIs** across React and Svelte (part names, prop interface names, namespace members).
+
+## Conventions (from app-bar / accordion / dialog)
+
+- Folder is kebab-case; exported namespace is PascalCase (`app-bar` -> `AppBar`).
+- Keep anatomy/modules split:
+ - `anatomy/*` = renderable parts
+ - `modules/*` = context/providers/namespace composition
+ - `index.ts` = type exports + namespace export
+- Use `PropsWithElement` + `HTMLAttributes` in part prop interfaces.
+- Build attributes with `mergeProps` and render with element override fallback.
+- React anatomy files are `.tsx`; `index.ts` type exports reference `.jsx` paths.
+- Svelte anatomy files are `.svelte`; interfaces are in `
+
+
+
+{#if element}
+ {@render element(attributes)}
+{:else}
+
+{/if}
diff --git a/packages/skeleton-svelte/src/components/qr-code/anatomy/frame.svelte b/packages/skeleton-svelte/src/components/qr-code/anatomy/frame.svelte
new file mode 100644
index 0000000000..7385b8d92c
--- /dev/null
+++ b/packages/skeleton-svelte/src/components/qr-code/anatomy/frame.svelte
@@ -0,0 +1,27 @@
+
+
+
+
+{#if element}
+ {@render element(attributes)}
+{:else}
+
+{/if}
diff --git a/packages/skeleton-svelte/src/components/qr-code/anatomy/overlay.svelte b/packages/skeleton-svelte/src/components/qr-code/anatomy/overlay.svelte
new file mode 100644
index 0000000000..c7c21e0cb4
--- /dev/null
+++ b/packages/skeleton-svelte/src/components/qr-code/anatomy/overlay.svelte
@@ -0,0 +1,27 @@
+
+
+
+
+{#if element}
+ {@render element(attributes)}
+{:else}
+
+ {@render children?.()}
+
+{/if}
diff --git a/packages/skeleton-svelte/src/components/qr-code/anatomy/pattern.svelte b/packages/skeleton-svelte/src/components/qr-code/anatomy/pattern.svelte
new file mode 100644
index 0000000000..04ab79de7c
--- /dev/null
+++ b/packages/skeleton-svelte/src/components/qr-code/anatomy/pattern.svelte
@@ -0,0 +1,25 @@
+
+
+
+
+{#if element}
+ {@render element(attributes)}
+{:else}
+
+{/if}
diff --git a/packages/skeleton-svelte/src/components/qr-code/anatomy/root-context.svelte b/packages/skeleton-svelte/src/components/qr-code/anatomy/root-context.svelte
new file mode 100644
index 0000000000..dff0e4f1ec
--- /dev/null
+++ b/packages/skeleton-svelte/src/components/qr-code/anatomy/root-context.svelte
@@ -0,0 +1,20 @@
+
+
+
+
+{@render children(qrCode)}
diff --git a/packages/skeleton-svelte/src/components/qr-code/anatomy/root-provider.svelte b/packages/skeleton-svelte/src/components/qr-code/anatomy/root-provider.svelte
new file mode 100644
index 0000000000..1706311265
--- /dev/null
+++ b/packages/skeleton-svelte/src/components/qr-code/anatomy/root-provider.svelte
@@ -0,0 +1,30 @@
+
+
+
+
+{#if element}
+ {@render element(attributes)}
+{:else}
+
+ {@render children?.()}
+
+{/if}
diff --git a/packages/skeleton-svelte/src/components/qr-code/anatomy/root.svelte b/packages/skeleton-svelte/src/components/qr-code/anatomy/root.svelte
new file mode 100644
index 0000000000..15d24759f8
--- /dev/null
+++ b/packages/skeleton-svelte/src/components/qr-code/anatomy/root.svelte
@@ -0,0 +1,37 @@
+
+
+
+
+{#if element}
+ {@render element(attributes)}
+{:else}
+
+ {@render children?.()}
+
+{/if}
diff --git a/packages/skeleton-svelte/src/components/qr-code/index.ts b/packages/skeleton-svelte/src/components/qr-code/index.ts
new file mode 100644
index 0000000000..5b36b1b949
--- /dev/null
+++ b/packages/skeleton-svelte/src/components/qr-code/index.ts
@@ -0,0 +1,9 @@
+export type { QrCodeDownloadTriggerProps } from './anatomy/download-trigger.svelte';
+export type { QrCodeFrameProps } from './anatomy/frame.svelte';
+export type { QrCodeOverlayProps } from './anatomy/overlay.svelte';
+export type { QrCodePatternProps } from './anatomy/pattern.svelte';
+export type { QrCodeRootProps } from './anatomy/root.svelte';
+export type { QrCodeRootContextProps } from './anatomy/root-context.svelte';
+export type { QrCodeRootProviderProps } from './anatomy/root-provider.svelte';
+export { QrCode } from './modules/anatomy.js';
+export { useQrCode } from './modules/provider.svelte.js';
diff --git a/packages/skeleton-svelte/src/components/qr-code/modules/anatomy.ts b/packages/skeleton-svelte/src/components/qr-code/modules/anatomy.ts
new file mode 100644
index 0000000000..7ba164452e
--- /dev/null
+++ b/packages/skeleton-svelte/src/components/qr-code/modules/anatomy.ts
@@ -0,0 +1,16 @@
+import DownloadTrigger from '../anatomy/download-trigger.svelte';
+import Frame from '../anatomy/frame.svelte';
+import Overlay from '../anatomy/overlay.svelte';
+import Pattern from '../anatomy/pattern.svelte';
+import RootContext from '../anatomy/root-context.svelte';
+import RootProvider from '../anatomy/root-provider.svelte';
+import Root from '../anatomy/root.svelte';
+
+export const QrCode = Object.assign(Root, {
+ Provider: RootProvider,
+ Context: RootContext,
+ DownloadTrigger: DownloadTrigger,
+ Frame: Frame,
+ Pattern: Pattern,
+ Overlay: Overlay,
+});
diff --git a/packages/skeleton-svelte/src/components/qr-code/modules/provider.svelte.ts b/packages/skeleton-svelte/src/components/qr-code/modules/provider.svelte.ts
new file mode 100644
index 0000000000..91603bd118
--- /dev/null
+++ b/packages/skeleton-svelte/src/components/qr-code/modules/provider.svelte.ts
@@ -0,0 +1,8 @@
+import { connect, machine, type Api, type Props } from '@zag-js/qr-code';
+import { normalizeProps, useMachine, type PropTypes } from '@zag-js/svelte';
+
+export function useQrCode(props: Props | (() => Props)): () => Api {
+ const service = useMachine(machine, props);
+ const qrCode = $derived(connect(service, normalizeProps));
+ return () => qrCode;
+}
diff --git a/packages/skeleton-svelte/src/components/qr-code/modules/root-context.ts b/packages/skeleton-svelte/src/components/qr-code/modules/root-context.ts
new file mode 100644
index 0000000000..56b8c65645
--- /dev/null
+++ b/packages/skeleton-svelte/src/components/qr-code/modules/root-context.ts
@@ -0,0 +1,4 @@
+import { createContext } from '../../../internal/create-context.js';
+import type { useQrCode } from './provider.svelte.js';
+
+export const RootContext = createContext>();
diff --git a/packages/skeleton-svelte/src/index.ts b/packages/skeleton-svelte/src/index.ts
index f6b95832bf..d701981872 100644
--- a/packages/skeleton-svelte/src/index.ts
+++ b/packages/skeleton-svelte/src/index.ts
@@ -15,6 +15,7 @@ export * from './components/pagination/index.js';
export * from './components/popover/index.js';
export * from './components/portal/index.js';
export * from './components/progress/index.js';
+export * from './components/qr-code/index.js';
export * from './components/rating-group/index.js';
export * from './components/segmented-control/index.js';
export * from './components/slider/index.js';
diff --git a/packages/skeleton-svelte/test/components/qr-code.svelte b/packages/skeleton-svelte/test/components/qr-code.svelte
new file mode 100644
index 0000000000..4d5a9fbeef
--- /dev/null
+++ b/packages/skeleton-svelte/test/components/qr-code.svelte
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/skeleton-svelte/test/components/qr-code.test.ts b/packages/skeleton-svelte/test/components/qr-code.test.ts
new file mode 100644
index 0000000000..995f18fd58
--- /dev/null
+++ b/packages/skeleton-svelte/test/components/qr-code.test.ts
@@ -0,0 +1,41 @@
+import QrCode from './qr-code.svelte';
+import { describe, expect, it } from 'vitest';
+import { render } from 'vitest-browser-svelte';
+import { page } from 'vitest/browser';
+
+describe('QrCode', () => {
+ describe('Root', () => {
+ it('renders', async () => {
+ render(QrCode);
+ await expect.element(page.getByTestId('root')).toBeInTheDocument();
+ });
+ });
+
+ describe('Frame', () => {
+ it('renders', async () => {
+ render(QrCode);
+ await expect.element(page.getByTestId('frame')).toBeInTheDocument();
+ });
+ });
+
+ describe('Pattern', () => {
+ it('renders', async () => {
+ render(QrCode);
+ await expect.element(page.getByTestId('pattern')).toBeInTheDocument();
+ });
+ });
+
+ describe('Overlay', () => {
+ it('renders', async () => {
+ render(QrCode);
+ await expect.element(page.getByTestId('overlay')).toBeInTheDocument();
+ });
+ });
+
+ describe('DownloadTrigger', () => {
+ it('renders', async () => {
+ render(QrCode);
+ await expect.element(page.getByTestId('download-trigger')).toBeInTheDocument();
+ });
+ });
+});
diff --git a/playgrounds/skeleton-react/src/routes/components/qr-code/index.tsx b/playgrounds/skeleton-react/src/routes/components/qr-code/index.tsx
new file mode 100644
index 0000000000..a70379331d
--- /dev/null
+++ b/playgrounds/skeleton-react/src/routes/components/qr-code/index.tsx
@@ -0,0 +1,20 @@
+import { QrCode } from '@skeletonlabs/skeleton-react';
+import { createFileRoute } from '@tanstack/react-router';
+
+export const Route = createFileRoute('/components/qr-code/')({
+ component: Page,
+});
+
+function Page() {
+ return (
+
+
+
+
+ Overlay
+
+ Download
+
+
+ );
+}
diff --git a/playgrounds/skeleton-svelte/src/routes/components/qr-code/+page.svelte b/playgrounds/skeleton-svelte/src/routes/components/qr-code/+page.svelte
new file mode 100644
index 0000000000..995a581575
--- /dev/null
+++ b/playgrounds/skeleton-svelte/src/routes/components/qr-code/+page.svelte
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+ Overlay
+ Download
+
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index ea417d453b..7f0112fb02 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -195,6 +195,9 @@ catalogs:
'@zag-js/progress':
specifier: 1.40.0
version: 1.40.0
+ '@zag-js/qr-code':
+ specifier: 1.40.0
+ version: 1.40.0
'@zag-js/radio-group':
specifier: 1.40.0
version: 1.40.0
@@ -613,6 +616,9 @@ importers:
'@zag-js/progress':
specifier: 'catalog:'
version: 1.40.0
+ '@zag-js/qr-code':
+ specifier: 'catalog:'
+ version: 1.40.0
'@zag-js/radio-group':
specifier: 'catalog:'
version: 1.40.0
@@ -737,6 +743,9 @@ importers:
'@zag-js/progress':
specifier: 'catalog:'
version: 1.40.0
+ '@zag-js/qr-code':
+ specifier: 'catalog:'
+ version: 1.40.0
'@zag-js/radio-group':
specifier: 'catalog:'
version: 1.40.0
@@ -4022,6 +4031,9 @@ packages:
'@zag-js/progress@1.40.0':
resolution: {integrity: sha512-V61a5CHEs8suevQVS+/1ENj1RDVYNOUUTawK6uriCA6Ol59xe30DmF+eV6Y9miM7L/pN3YjZRq9uEDJMXXK32g==}
+ '@zag-js/qr-code@1.40.0':
+ resolution: {integrity: sha512-xD37tVrQ46CeqVLqkSm61kURoJ4Z/uOFcB8z7Hu3UX+1OFTfkhgrns6iLUneoRjO3hsqQaTaVkxVOQeLYWb+wA==}
+
'@zag-js/radio-group@1.40.0':
resolution: {integrity: sha512-sFJCdyOKzQC9hylSP19R71yv44by/C78D9EHfsxQJtvOgDv9E+h13NNX4n9wWyubC20xftlxkja8sNT5NfJKUw==}
@@ -5834,6 +5846,9 @@ packages:
proxy-compare@3.0.1:
resolution: {integrity: sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==}
+ proxy-memoize@3.0.1:
+ resolution: {integrity: sha512-VDdG/VYtOgdGkWJx7y0o7p+zArSf2383Isci8C+BP3YXgMYDoPd3cCBjw0JdWb6YBb9sFiOPbAADDVTPJnh+9g==}
+
punycode@2.3.1:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
@@ -6651,6 +6666,9 @@ packages:
peerDependencies:
browserslist: '>= 4.21.0'
+ uqr@0.1.2:
+ resolution: {integrity: sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==}
+
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
@@ -9805,6 +9823,16 @@ snapshots:
'@zag-js/types': 1.40.0
'@zag-js/utils': 1.40.0
+ '@zag-js/qr-code@1.40.0':
+ dependencies:
+ '@zag-js/anatomy': 1.40.0
+ '@zag-js/core': 1.40.0
+ '@zag-js/dom-query': 1.40.0
+ '@zag-js/types': 1.40.0
+ '@zag-js/utils': 1.40.0
+ proxy-memoize: 3.0.1
+ uqr: 0.1.2
+
'@zag-js/radio-group@1.40.0':
dependencies:
'@zag-js/anatomy': 1.40.0
@@ -12004,6 +12032,10 @@ snapshots:
proxy-compare@3.0.1: {}
+ proxy-memoize@3.0.1:
+ dependencies:
+ proxy-compare: 3.0.1
+
punycode@2.3.1:
optional: true
@@ -12873,6 +12905,8 @@ snapshots:
escalade: 3.2.0
picocolors: 1.1.1
+ uqr@0.1.2: {}
+
uri-js@4.4.1:
dependencies:
punycode: 2.3.1
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index e0148ecb27..4d7e101d24 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -67,6 +67,7 @@ catalog:
'@zag-js/pagination': 1.40.0
'@zag-js/popover': 1.40.0
'@zag-js/progress': 1.40.0
+ '@zag-js/qr-code': 1.40.0
'@zag-js/radio-group': 1.40.0
'@zag-js/rating-group': 1.40.0
'@zag-js/react': 1.40.0
diff --git a/sites/skeleton.dev/src/content/component-types/react/qr-code.json b/sites/skeleton.dev/src/content/component-types/react/qr-code.json
new file mode 100644
index 0000000000..a6bd0e92aa
--- /dev/null
+++ b/sites/skeleton.dev/src/content/component-types/react/qr-code.json
@@ -0,0 +1,127 @@
+{
+ "name": "qr-code",
+ "types": [
+ {
+ "name": "QrCodeRootProps",
+ "props": [
+ {
+ "name": "element",
+ "type": "((attributes: HTMLAttributes<\"div\">) => Element) | undefined",
+ "typeKind": "function",
+ "optional": true,
+ "JSDoc": {
+ "description": "Render the element yourself",
+ "tags": []
+ }
+ }
+ ],
+ "metadata": {}
+ },
+ {
+ "name": "QrCodeRootProviderProps",
+ "props": [
+ {
+ "name": "value",
+ "type": "Api",
+ "typeKind": "primitive",
+ "optional": false,
+ "JSDoc": {
+ "description": null,
+ "tags": []
+ }
+ },
+ {
+ "name": "element",
+ "type": "((attributes: HTMLAttributes<\"div\">) => Element) | undefined",
+ "typeKind": "function",
+ "optional": true,
+ "JSDoc": {
+ "description": "Render the element yourself",
+ "tags": []
+ }
+ }
+ ],
+ "metadata": {}
+ },
+ {
+ "name": "QrCodeRootContextProps",
+ "props": [
+ {
+ "name": "children",
+ "type": "(qrCode: Api) => ReactNode",
+ "typeKind": "function",
+ "optional": false,
+ "JSDoc": {
+ "description": null,
+ "tags": []
+ }
+ }
+ ],
+ "metadata": {}
+ },
+ {
+ "name": "QrCodeDownloadTriggerProps",
+ "props": [
+ {
+ "name": "element",
+ "type": "((attributes: HTMLAttributes<\"button\">) => Element) | undefined",
+ "typeKind": "function",
+ "optional": true,
+ "JSDoc": {
+ "description": "Render the element yourself",
+ "tags": []
+ }
+ }
+ ],
+ "metadata": {}
+ },
+ {
+ "name": "QrCodeFrameProps",
+ "props": [
+ {
+ "name": "element",
+ "type": "((attributes: HTMLAttributes<\"svg\">) => Element) | undefined",
+ "typeKind": "function",
+ "optional": true,
+ "JSDoc": {
+ "description": "Render the element yourself",
+ "tags": []
+ }
+ }
+ ],
+ "metadata": {}
+ },
+ {
+ "name": "QrCodePatternProps",
+ "props": [
+ {
+ "name": "element",
+ "type": "((attributes: HTMLAttributes<\"path\">) => Element) | undefined",
+ "typeKind": "function",
+ "optional": true,
+ "JSDoc": {
+ "description": "Render the element yourself",
+ "tags": []
+ }
+ }
+ ],
+ "metadata": {}
+ },
+ {
+ "name": "QrCodeOverlayProps",
+ "props": [
+ {
+ "name": "element",
+ "type": "((attributes: HTMLAttributes<\"div\">) => Element) | undefined",
+ "typeKind": "function",
+ "optional": true,
+ "JSDoc": {
+ "description": "Render the element yourself",
+ "tags": []
+ }
+ }
+ ],
+ "metadata": {}
+ }
+ ]
+}
diff --git a/sites/skeleton.dev/src/content/component-types/svelte/qr-code.json b/sites/skeleton.dev/src/content/component-types/svelte/qr-code.json
new file mode 100644
index 0000000000..bff597cbac
--- /dev/null
+++ b/sites/skeleton.dev/src/content/component-types/svelte/qr-code.json
@@ -0,0 +1,127 @@
+{
+ "name": "qr-code",
+ "types": [
+ {
+ "name": "QrCodeRootProps",
+ "props": [
+ {
+ "name": "element",
+ "type": "Snippet<[HTMLAttributes<\"div\">]> | undefined",
+ "typeKind": "function",
+ "optional": true,
+ "JSDoc": {
+ "description": "Render the element yourself",
+ "tags": []
+ }
+ }
+ ],
+ "metadata": {}
+ },
+ {
+ "name": "QrCodeRootProviderProps",
+ "props": [
+ {
+ "name": "value",
+ "type": "() => Api",
+ "typeKind": "function",
+ "optional": false,
+ "JSDoc": {
+ "description": null,
+ "tags": []
+ }
+ },
+ {
+ "name": "element",
+ "type": "Snippet<[HTMLAttributes<\"div\">]> | undefined",
+ "typeKind": "function",
+ "optional": true,
+ "JSDoc": {
+ "description": "Render the element yourself",
+ "tags": []
+ }
+ }
+ ],
+ "metadata": {}
+ },
+ {
+ "name": "QrCodeRootContextProps",
+ "props": [
+ {
+ "name": "children",
+ "type": "Snippet<[() => Api]>",
+ "typeKind": "function",
+ "optional": false,
+ "JSDoc": {
+ "description": null,
+ "tags": []
+ }
+ }
+ ],
+ "metadata": {}
+ },
+ {
+ "name": "QrCodeDownloadTriggerProps",
+ "props": [
+ {
+ "name": "element",
+ "type": "Snippet<[HTMLAttributes<\"button\">]> | undefined",
+ "typeKind": "function",
+ "optional": true,
+ "JSDoc": {
+ "description": "Render the element yourself",
+ "tags": []
+ }
+ }
+ ],
+ "metadata": {}
+ },
+ {
+ "name": "QrCodeFrameProps",
+ "props": [
+ {
+ "name": "element",
+ "type": "Snippet<[HTMLAttributes<\"svg\">]> | undefined",
+ "typeKind": "function",
+ "optional": true,
+ "JSDoc": {
+ "description": "Render the element yourself",
+ "tags": []
+ }
+ }
+ ],
+ "metadata": {}
+ },
+ {
+ "name": "QrCodePatternProps",
+ "props": [
+ {
+ "name": "element",
+ "type": "Snippet<[HTMLAttributes<\"path\">]> | undefined",
+ "typeKind": "function",
+ "optional": true,
+ "JSDoc": {
+ "description": "Render the element yourself",
+ "tags": []
+ }
+ }
+ ],
+ "metadata": {}
+ },
+ {
+ "name": "QrCodeOverlayProps",
+ "props": [
+ {
+ "name": "element",
+ "type": "Snippet<[HTMLAttributes<\"div\">]> | undefined",
+ "typeKind": "function",
+ "optional": true,
+ "JSDoc": {
+ "description": "Render the element yourself",
+ "tags": []
+ }
+ }
+ ],
+ "metadata": {}
+ }
+ ]
+}