@cratis/scene.components 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,11 +6,9 @@ import { CratisComponentsProvider } from '@cratis/components/Common';
6
6
 
7
7
  // The stylesheet stack a `@cratis/components` component needs, in the order the layers resolve.
8
8
  //
9
- // PrimeReact 11 ships no CSS whatsoever - `primereact/resources/` does not exist, so the compiled theme
10
- // this file used to import has nothing left to resolve to. A look is no longer a stylesheet at all: it is
11
- // either a `@primeuix/themes` preset handed to the provider, which `@primeuix/styled` turns into `--p-*`
12
- // custom properties at runtime, or a sheet that assigns the library's own `--cratis-*` tokens directly.
13
- // This preview takes the second path - see the decorator below for why.
9
+ // Components 4 owns its own markup and styling outright - there is no PrimeReact underneath it any more,
10
+ // and so no preset and no `--p-*` values behind the tokens. A look is one thing now: a sheet that assigns
11
+ // the library's own `--cratis-*` tokens.
14
12
  //
15
13
  // `tokens` declares the `--cratis-*` layer every component stylesheet reads, `styles` is that component
16
14
  // CSS plus the compiled Tailwind utilities and the vendored Allotment sheet `DataPage`'s split view needs,
@@ -20,35 +18,33 @@ import { CratisComponentsProvider } from '@cratis/components/Common';
20
18
  import '@cratis/components/tokens';
21
19
  import '@cratis/components/styles';
22
20
  import '@cratis/components/theme';
21
+ // Components 4 renders an `Icon` given a string as `<i className={icon} />` - a consumer-owned icon font,
22
+ // whichever one the consumer happens to load. These stories demonstrate that with `pi pi-*`, so the
23
+ // preview loads primeicons to make them visible. It is a Storybook devDependency for exactly this reason
24
+ // and nothing in the package's own source reaches for it.
23
25
  import 'primeicons/primeicons.css';
24
26
  import '../theme/sceneTokenBridge.css';
25
27
 
26
28
  // The baseline theme is scoped to a `cratis-theme` ancestor rather than to `:root`, so something has to
27
- // carry the class. `<body>` rather than a wrapper inside each story, because PrimeReact 11 portals its
28
- // overlays - dialogs, select panels, the filter panel - straight to `document.body`; a wrapper would
29
- // leave every one of them outside the themed subtree and rendering unstyled.
29
+ // carry the class. `<body>` rather than a wrapper inside each story, because overlays - dialogs, select
30
+ // panels, the filter panel - are portaled to `document.body`; a wrapper would leave every one of them
31
+ // outside the themed subtree and rendering unstyled.
30
32
  document.body.classList.add('cratis-theme');
31
33
 
32
34
  /**
33
- * Every story renders inside `CratisComponentsProvider`, the library's own configuration provider over
34
- * PrimeReact's. Without it the wrapped components fall back to PrimeReact's defaults rather than
35
- * Cratis', so a story would be showing something subtly different from what an application renders -
36
- * which defeats the point of having stories at all.
35
+ * Every story renders inside `CratisComponentsProvider`, so a story shows what an application shows.
37
36
  *
38
- * `unstyled` is the posture the imported `@cratis/components/theme` is written for: it is Cratis-authored
39
- * MIT CSS that assigns the `--cratis-*` tokens outright, so it needs neither a `@primeuix/themes` preset
40
- * nor the PrimeUI license key a styled preset is gated behind. Choosing it over a preset also keeps this
41
- * package's dependency surface honest - `@primeuix/themes` is not one of its dependencies, and a preview
42
- * is the wrong place to start relying on a package nobody declared.
43
- *
44
- * It is the right choice for these stories on its own terms too. The `--cratis-*` token layer is exactly
45
- * what `theme/sceneTokenBridge.css` overrides, so a Scene theme visibly takes over from the baseline in
46
- * the `Themed` story rather than from a preset's `--p-*` values one level further down the chain.
37
+ * Components 4 narrowed the provider to configuration the library itself owns - `locale` and `messages`.
38
+ * The renderer keys it used to carry (`license`, `theme`, `defaults`, `pt`, `ripple`, `unstyled`) existed
39
+ * to configure PrimeReact underneath, and there is no PrimeReact underneath any more. `unstyled` in
40
+ * particular is gone rather than defaulted: the imported `@cratis/components/theme` is the look now, and
41
+ * `theme/sceneTokenBridge.css` overrides its `--cratis-*` tokens directly, which is what lets the `Themed`
42
+ * story visibly take over from the baseline.
47
43
  */
48
44
  const preview: Preview = {
49
45
  decorators: [
50
46
  Story => (
51
- <CratisComponentsProvider value={{ unstyled: true }}>
47
+ <CratisComponentsProvider value={{ locale: 'en-US' }}>
52
48
  <Story />
53
49
  </CratisComponentsProvider>
54
50
  ),
@@ -22,7 +22,11 @@ export function SceneTooltip({ element, slots }: RegisteredComponentProps) {
22
22
  position={unionProperty(element.properties, 'position', positions)}
23
23
  disabled={booleanProperty(element.properties, 'disabled')}
24
24
  >
25
- {slots.content}
25
+ {/* Components 4 takes a single focusable trigger, which it clones to attach its own
26
+ class and part attributes, and a Scene slot is a list. The span is that one element:
27
+ without it a slot holding anything other than exactly one node fails to type, and a
28
+ slot is authored content we cannot assume the shape of. */}
29
+ <span>{slots.content}</span>
26
30
  </Tooltip>
27
31
  );
28
32
  }
@@ -21,7 +21,9 @@ var properties = require('../properties.js');
21
21
  content: properties.stringProperty(element.properties, 'content') ?? '',
22
22
  position: properties.unionProperty(element.properties, 'position', positions),
23
23
  disabled: properties.booleanProperty(element.properties, 'disabled'),
24
- children: slots.content
24
+ children: /*#__PURE__*/ jsxRuntime.jsx("span", {
25
+ children: slots.content
26
+ })
25
27
  });
26
28
  }
27
29
 
@@ -1 +1 @@
1
- {"version":3,"file":"SceneTooltip.js","sources":["../../../common/SceneTooltip.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Tooltip } from '@cratis/components/Common';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { booleanProperty, stringProperty, unionProperty } from '../properties';\n\n/** Which side of the wrapped content the tooltip appears on. */\nconst positions = ['top', 'right', 'bottom', 'left'] as const;\n\n/**\n * The `Cratis.Components:tooltip` component - `Tooltip` from `@cratis/components/Common`.\n *\n * Wraps whatever is in its `content` slot and explains it on hover. `disabled` exists so a screen can\n * keep the wrapper in place while turning the hint off, rather than restructuring the element tree to\n * remove it - the tree is authored, and a conditional wrapper would be a worse thing to model.\n */\nexport function SceneTooltip({ element, slots }: RegisteredComponentProps) {\n return (\n <Tooltip\n content={stringProperty(element.properties, 'content') ?? ''}\n position={unionProperty(element.properties, 'position', positions)}\n disabled={booleanProperty(element.properties, 'disabled')}\n >\n {slots.content}\n </Tooltip>\n );\n}\n"],"names":["positions","SceneTooltip","element","slots","_jsx","Tooltip","content","stringProperty","properties","position","unionProperty","disabled","booleanProperty"],"mappings":";;;;;;AAOA,iEACA,MAAMA,SAAAA,GAAY;AAAC,IAAA,KAAA;AAAO,IAAA,OAAA;AAAS,IAAA,QAAA;AAAU,IAAA;AAAO,CAAA;AAEpD;;;;;;AAMC,IACM,SAASC,YAAAA,CAAa,EAAEC,OAAO,EAAEC,KAAK,EAA4B,EAAA;AACrE,IAAA,qBACIC,cAAA,CAACC,cAAAA,EAAAA;AACGC,QAAAA,OAAAA,EAASC,yBAAAA,CAAeL,OAAAA,CAAQM,UAAU,EAAE,SAAA,CAAA,IAAc,EAAA;AAC1DC,QAAAA,QAAAA,EAAUC,wBAAAA,CAAcR,OAAAA,CAAQM,UAAU,EAAE,UAAA,EAAYR,SAAAA,CAAAA;QACxDW,QAAAA,EAAUC,0BAAAA,CAAgBV,OAAAA,CAAQM,UAAU,EAAE,UAAA,CAAA;AAE7CL,QAAAA,QAAAA,EAAAA,KAAAA,CAAMG;;AAGnB;;;;"}
1
+ {"version":3,"file":"SceneTooltip.js","sources":["../../../common/SceneTooltip.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Tooltip } from '@cratis/components/Common';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { booleanProperty, stringProperty, unionProperty } from '../properties';\n\n/** Which side of the wrapped content the tooltip appears on. */\nconst positions = ['top', 'right', 'bottom', 'left'] as const;\n\n/**\n * The `Cratis.Components:tooltip` component - `Tooltip` from `@cratis/components/Common`.\n *\n * Wraps whatever is in its `content` slot and explains it on hover. `disabled` exists so a screen can\n * keep the wrapper in place while turning the hint off, rather than restructuring the element tree to\n * remove it - the tree is authored, and a conditional wrapper would be a worse thing to model.\n */\nexport function SceneTooltip({ element, slots }: RegisteredComponentProps) {\n return (\n <Tooltip\n content={stringProperty(element.properties, 'content') ?? ''}\n position={unionProperty(element.properties, 'position', positions)}\n disabled={booleanProperty(element.properties, 'disabled')}\n >\n {/* Components 4 takes a single focusable trigger, which it clones to attach its own\n class and part attributes, and a Scene slot is a list. The span is that one element:\n without it a slot holding anything other than exactly one node fails to type, and a\n slot is authored content we cannot assume the shape of. */}\n <span>{slots.content}</span>\n </Tooltip>\n );\n}\n"],"names":["positions","SceneTooltip","element","slots","_jsx","Tooltip","content","stringProperty","properties","position","unionProperty","disabled","booleanProperty","span"],"mappings":";;;;;;AAOA,iEACA,MAAMA,SAAAA,GAAY;AAAC,IAAA,KAAA;AAAO,IAAA,OAAA;AAAS,IAAA,QAAA;AAAU,IAAA;AAAO,CAAA;AAEpD;;;;;;AAMC,IACM,SAASC,YAAAA,CAAa,EAAEC,OAAO,EAAEC,KAAK,EAA4B,EAAA;AACrE,IAAA,qBACIC,cAAA,CAACC,cAAAA,EAAAA;AACGC,QAAAA,OAAAA,EAASC,yBAAAA,CAAeL,OAAAA,CAAQM,UAAU,EAAE,SAAA,CAAA,IAAc,EAAA;AAC1DC,QAAAA,QAAAA,EAAUC,wBAAAA,CAAcR,OAAAA,CAAQM,UAAU,EAAE,UAAA,EAAYR,SAAAA,CAAAA;QACxDW,QAAAA,EAAUC,0BAAAA,CAAgBV,OAAAA,CAAQM,UAAU,EAAE,UAAA,CAAA;AAM9C,QAAA,QAAA,gBAAAJ,cAAA,CAACS,MAAAA,EAAAA;AAAMV,YAAAA,QAAAA,EAAAA,KAAAA,CAAMG;;;AAGzB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"SceneTooltip.d.ts","sourceRoot":"","sources":["../../../common/SceneTooltip.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAa/D,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,wBAAwB,+BAUxE"}
1
+ {"version":3,"file":"SceneTooltip.d.ts","sourceRoot":"","sources":["../../../common/SceneTooltip.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAa/D,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,wBAAwB,+BAcxE"}
@@ -19,7 +19,9 @@ import { booleanProperty, unionProperty, stringProperty } from '../properties.js
19
19
  content: stringProperty(element.properties, 'content') ?? '',
20
20
  position: unionProperty(element.properties, 'position', positions),
21
21
  disabled: booleanProperty(element.properties, 'disabled'),
22
- children: slots.content
22
+ children: /*#__PURE__*/ jsx("span", {
23
+ children: slots.content
24
+ })
23
25
  });
24
26
  }
25
27
 
@@ -1 +1 @@
1
- {"version":3,"file":"SceneTooltip.js","sources":["../../../common/SceneTooltip.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Tooltip } from '@cratis/components/Common';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { booleanProperty, stringProperty, unionProperty } from '../properties';\n\n/** Which side of the wrapped content the tooltip appears on. */\nconst positions = ['top', 'right', 'bottom', 'left'] as const;\n\n/**\n * The `Cratis.Components:tooltip` component - `Tooltip` from `@cratis/components/Common`.\n *\n * Wraps whatever is in its `content` slot and explains it on hover. `disabled` exists so a screen can\n * keep the wrapper in place while turning the hint off, rather than restructuring the element tree to\n * remove it - the tree is authored, and a conditional wrapper would be a worse thing to model.\n */\nexport function SceneTooltip({ element, slots }: RegisteredComponentProps) {\n return (\n <Tooltip\n content={stringProperty(element.properties, 'content') ?? ''}\n position={unionProperty(element.properties, 'position', positions)}\n disabled={booleanProperty(element.properties, 'disabled')}\n >\n {slots.content}\n </Tooltip>\n );\n}\n"],"names":["positions","SceneTooltip","element","slots","_jsx","Tooltip","content","stringProperty","properties","position","unionProperty","disabled","booleanProperty"],"mappings":";;;;AAOA,iEACA,MAAMA,SAAAA,GAAY;AAAC,IAAA,KAAA;AAAO,IAAA,OAAA;AAAS,IAAA,QAAA;AAAU,IAAA;AAAO,CAAA;AAEpD;;;;;;AAMC,IACM,SAASC,YAAAA,CAAa,EAAEC,OAAO,EAAEC,KAAK,EAA4B,EAAA;AACrE,IAAA,qBACIC,GAAA,CAACC,OAAAA,EAAAA;AACGC,QAAAA,OAAAA,EAASC,cAAAA,CAAeL,OAAAA,CAAQM,UAAU,EAAE,SAAA,CAAA,IAAc,EAAA;AAC1DC,QAAAA,QAAAA,EAAUC,aAAAA,CAAcR,OAAAA,CAAQM,UAAU,EAAE,UAAA,EAAYR,SAAAA,CAAAA;QACxDW,QAAAA,EAAUC,eAAAA,CAAgBV,OAAAA,CAAQM,UAAU,EAAE,UAAA,CAAA;AAE7CL,QAAAA,QAAAA,EAAAA,KAAAA,CAAMG;;AAGnB;;;;"}
1
+ {"version":3,"file":"SceneTooltip.js","sources":["../../../common/SceneTooltip.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { Tooltip } from '@cratis/components/Common';\nimport { RegisteredComponentProps } from '@cratis/scene.react';\nimport { booleanProperty, stringProperty, unionProperty } from '../properties';\n\n/** Which side of the wrapped content the tooltip appears on. */\nconst positions = ['top', 'right', 'bottom', 'left'] as const;\n\n/**\n * The `Cratis.Components:tooltip` component - `Tooltip` from `@cratis/components/Common`.\n *\n * Wraps whatever is in its `content` slot and explains it on hover. `disabled` exists so a screen can\n * keep the wrapper in place while turning the hint off, rather than restructuring the element tree to\n * remove it - the tree is authored, and a conditional wrapper would be a worse thing to model.\n */\nexport function SceneTooltip({ element, slots }: RegisteredComponentProps) {\n return (\n <Tooltip\n content={stringProperty(element.properties, 'content') ?? ''}\n position={unionProperty(element.properties, 'position', positions)}\n disabled={booleanProperty(element.properties, 'disabled')}\n >\n {/* Components 4 takes a single focusable trigger, which it clones to attach its own\n class and part attributes, and a Scene slot is a list. The span is that one element:\n without it a slot holding anything other than exactly one node fails to type, and a\n slot is authored content we cannot assume the shape of. */}\n <span>{slots.content}</span>\n </Tooltip>\n );\n}\n"],"names":["positions","SceneTooltip","element","slots","_jsx","Tooltip","content","stringProperty","properties","position","unionProperty","disabled","booleanProperty","span"],"mappings":";;;;AAOA,iEACA,MAAMA,SAAAA,GAAY;AAAC,IAAA,KAAA;AAAO,IAAA,OAAA;AAAS,IAAA,QAAA;AAAU,IAAA;AAAO,CAAA;AAEpD;;;;;;AAMC,IACM,SAASC,YAAAA,CAAa,EAAEC,OAAO,EAAEC,KAAK,EAA4B,EAAA;AACrE,IAAA,qBACIC,GAAA,CAACC,OAAAA,EAAAA;AACGC,QAAAA,OAAAA,EAASC,cAAAA,CAAeL,OAAAA,CAAQM,UAAU,EAAE,SAAA,CAAA,IAAc,EAAA;AAC1DC,QAAAA,QAAAA,EAAUC,aAAAA,CAAcR,OAAAA,CAAQM,UAAU,EAAE,UAAA,EAAYR,SAAAA,CAAAA;QACxDW,QAAAA,EAAUC,eAAAA,CAAgBV,OAAAA,CAAQM,UAAU,EAAE,UAAA,CAAA;AAM9C,QAAA,QAAA,gBAAAJ,GAAA,CAACS,MAAAA,EAAAA;AAAMV,YAAAA,QAAAA,EAAAA,KAAAA,CAAMG;;;AAGzB;;;;"}
@@ -1,12 +1,11 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { fireEvent, render, screen } from '@testing-library/react';
3
- import { PrimeReactProvider } from '@primereact/core';
4
3
  import { externalComponent } from '../../given';
5
4
  import { SceneObjectNavigationalBar } from '../SceneObjectNavigationalBar';
6
5
  describe('when navigating back up the trail', () => {
7
6
  beforeEach(() => {
8
7
  const element = externalComponent('Cratis.Components:objectNavigationalBar', { navigationPath: ['shipping', 'address', 'street'] });
9
- render(_jsx(PrimeReactProvider, { children: _jsx(SceneObjectNavigationalBar, { element: element, slots: {} }) }));
8
+ render(_jsx(SceneObjectNavigationalBar, { element: element, slots: {} }));
10
9
  fireEvent.click(screen.getByText('address'));
11
10
  });
12
11
  it('should keep the crumb that was clicked', () => screen.getByText('address').textContent.should.equal('address'));
@@ -1 +1 @@
1
- {"version":3,"file":"when_navigating_back_up_the_trail.js","sourceRoot":"","sources":["../../../../editors/for_SceneObjectNavigationalBar/when_navigating_back_up_the_trail.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAE3E,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IAQ/C,UAAU,CAAC,GAAG,EAAE;QACZ,MAAM,OAAO,GAAG,iBAAiB,CAAC,yCAAyC,EAAE,EAAE,cAAc,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QACpI,MAAM,CACF,KAAC,kBAAkB,cACf,KAAC,0BAA0B,IAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,GAAI,GAC1C,CACxB,CAAC;QACF,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,WAAY,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IACrH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,WAAY,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;IAChH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;AACxG,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"when_navigating_back_up_the_trail.js","sourceRoot":"","sources":["../../../../editors/for_SceneObjectNavigationalBar/when_navigating_back_up_the_trail.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAE3E,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IAO/C,UAAU,CAAC,GAAG,EAAE;QACZ,MAAM,OAAO,GAAG,iBAAiB,CAAC,yCAAyC,EAAE,EAAE,cAAc,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QACpI,MAAM,CAAC,KAAC,0BAA0B,IAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,GAAI,CAAC,CAAC;QACpE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,WAAY,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IACrH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,WAAY,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;IAChH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;AACxG,CAAC,CAAC,CAAC"}