@object-ui/plugin-timeline 17.5.0 → 17.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -62,7 +62,7 @@ This plugin automatically registers with ObjectUI's component registry when impo
62
62
  import '@object-ui/plugin-timeline';
63
63
 
64
64
  const schema = {
65
- component: 'timeline',
65
+ type: 'timeline',
66
66
  variant: 'vertical',
67
67
  items: [
68
68
  {
@@ -75,6 +75,59 @@ const schema = {
75
75
  };
76
76
  ```
77
77
 
78
+ ### Object-bound timeline (`object-timeline`)
79
+
80
+ `object-timeline` fetches records from `objectName` and draws one entry per
81
+ record, from the fields its `timeline` config names. An authored node takes its
82
+ props in the `properties` bag, where `@objectstack/spec`'s
83
+ `ComponentPropsMap['object-timeline']` row declares them:
84
+
85
+ ```json
86
+ {
87
+ "type": "object-timeline",
88
+ "properties": {
89
+ "objectName": "project_task",
90
+ "timeline": { "startDateField": "start_date", "titleField": "name" },
91
+ "navigation": { "mode": "drawer" }
92
+ }
93
+ }
94
+ ```
95
+
96
+ The first record source present wins: `items` (authored entries, drawn as
97
+ written), then `data` (pre-fetched records), then a `bind` path, then the query
98
+ on `objectName`. So `objectName` is optional: a timeline drawn from `items`,
99
+ `data` or a `bind` path needs none to draw (entry-click navigation still reads
100
+ it, below), and a node-level `dataSource` binding can supply the object instead. Records are composed into entries through the
101
+ `timeline` block's field bindings (`startDateField`, `endDateField`,
102
+ `titleField`, `groupByField`, `colorField`), each of which outranks the flat
103
+ key of the same binding; `mapping` (`{ title, date, description, variant }`)
104
+ is read where the block leaves a binding unset, and `descriptionField` names
105
+ the description field (`mapping.description` outranks it). `limit` caps the
106
+ query (`$top`, default 100), and `filter` / `sort` lower to `$filter` /
107
+ `$orderby` on it; the rail still draws composed entries by start date.
108
+ `dateFormat` is `short`, `long` or `iso`. `rowLabel`, `minDate`, `maxDate` and
109
+ `timeline.scale` are read by the gantt branch only, which on this block draws
110
+ authored `items`.
111
+
112
+ `navigation` is what an entry click opens — the spec's `NavigationConfig` by
113
+ reference, `ViewNavigationConfig` in `@object-ui/types`: `mode` (`page`,
114
+ `drawer`, `modal`, `split`, `popover`, `new_window` or `none`) with `size`,
115
+ `openNewTab` and `preventNavigation`. `drawer`, `modal` and `popover` open the
116
+ entry's record in that overlay, `new_window` and `openNewTab: true` open the
117
+ record page in a new tab, `preventNavigation: true` opens nothing, and `size`
118
+ sets the overlay width. `page`, and a block written without `mode` (it takes
119
+ the spec's `page` default), open the record page of the timeline's `objectName`
120
+ through the record navigator the host publishes (the console publishes one on
121
+ its custom pages, record pages and list views); under a host that publishes
122
+ none, such as an embedded renderer, or on a timeline that names no
123
+ `objectName`, the click opens nothing. On a timeline that names no
124
+ `objectName`, `new_window` and `openNewTab: true` open no record page either:
125
+ the tab opens at a slash and the entry's `id` alone (its `_id` when it has no
126
+ `id`, `undefined` when it has neither). A click handler from a parent view
127
+ outranks the whole key. ⚠️ With the key absent a click opens nothing: this renderer supplies no
128
+ drawer default. `split` opens nothing on this block either, because the
129
+ timeline gives the split shell no main panel.
130
+
78
131
  ## Links
79
132
 
80
133
  - 📚 [Documentation](https://www.objectui.org/docs/plugins/plugin-timeline)
@@ -1,5 +1,5 @@
1
1
  import { default as React } from 'react';
2
- import { DataSource, TimelineSchema, ListViewTimelineConfig } from '@object-ui/types';
2
+ import { DataSource, TimelineSchema, ListViewTimelineConfig, ViewNavigationConfig } from '@object-ui/types';
3
3
  /**
4
4
  * Rows fetched when the author declared no `limit`.
5
5
  *
@@ -19,6 +19,47 @@ export interface ObjectTimelineProps {
19
19
  * has always declared on it, and that this renderer now actually reads.
20
20
  */
21
21
  timeline?: ListViewTimelineConfig;
22
+ /**
23
+ * Entry-click navigation — what a click on an entry opens (an overlay
24
+ * mode, the record page in a new tab, or nothing), with the overlay `size`
25
+ * and the `openNewTab` / `preventNavigation` flags. Handed to
26
+ * `useNavigationOverlay` below, which the composed `onItemClick` fires.
27
+ *
28
+ * DECLARED by objectui#8654, the timeline arm of the objectui#8652
29
+ * maintainer ruling, verbatim 「B」: the platform half is
30
+ * `@objectstack/spec` 17.5.0, whose `ComponentPropsMap['object-timeline']`
31
+ * row declares `navigation: NavigationConfigSchema.optional()` for this
32
+ * block standalone, with no enclosing view. So this member follows the
33
+ * installed spec rather than leading it. Before it, the read went through
34
+ * an `as any` cast, and without the cast it would have compiled only
35
+ * through `BaseSchema`'s `[key: string]: any`.
36
+ *
37
+ * Declared HERE, beside `objectName`, `timeline`, `filter` and `sort`,
38
+ * rather than on `TimelineSchema` in `@object-ui/types`, and that is the
39
+ * spec's own split: `TimelineSchema` is the presentational rail, whose
40
+ * renderer never reads this key, while the spec declares it on the
41
+ * object-bound `object-timeline` row only. That row's other members live
42
+ * on this half for the same reason. The zod face of the row is
43
+ * `ObjectTimelineBlockSchema`'s `properties` bag, which reads the spec row
44
+ * by reference and so judges this key already.
45
+ *
46
+ * Same spec type as `ObjectKanbanSchema.navigation` and
47
+ * `ObjectCalendarSchema.navigation` — aligned with `@objectstack/spec`
48
+ * `NavigationConfig` rather than restated, so the vocabulary cannot fork.
49
+ *
50
+ * ⚠️ Unlike the board and the calendar, this renderer supplies NO default
51
+ * for an ABSENT key, and an absent key is not a `page` block: the hook's
52
+ * no-config branch hands the click to an `onNavigate` alone, which this
53
+ * component never passes, and never reads the host's record navigator. So
54
+ * a click opens nothing, under a host that publishes a navigator too. A
55
+ * block written without `mode` (`{ size: 'lg' }`) is different: it takes
56
+ * the spec's `page` default and opens the record page through that
57
+ * navigator (objectui#11293). A parent's `onRowClick` / `onItemClick`
58
+ * outranks the whole key. The members are pinned in
59
+ * `__tests__/timelineNavigationMembers-8654.test.tsx`, and the absent key
60
+ * against the mode-less block in `__tests__/objectTimelineInputs-11168.test.tsx`.
61
+ */
62
+ navigation?: ViewNavigationConfig;
22
63
  /**
23
64
  * Query filter for the object fetch, in any shape `toFilterNode` accepts
24
65
  * (spec `ViewFilterRule[]`, ObjectQL AST nodes, or a MongoDB-style object).
@@ -31,10 +72,11 @@ export interface ObjectTimelineProps {
31
72
  */
32
73
  filter?: any[] | Record<string, any>;
33
74
  /**
34
- * Query ordering — the legacy `"name desc"` clause or the spec's
35
- * `SortConfig[]`, both lowered through `convertSortToQueryParams`.
75
+ * Query ordering — the spec's `SortConfig[]`, lowered through
76
+ * `convertSortToQueryParams`. The legacy `"name desc"` clause is RETIRED
77
+ * (objectui#8221) and that sink refuses it out loud.
36
78
  */
37
- sort?: string | Array<{
79
+ sort?: Array<{
38
80
  field?: string;
39
81
  order?: 'asc' | 'desc';
40
82
  }>;
@@ -68,8 +110,23 @@ export interface ObjectTimelineProps {
68
110
  };
69
111
  dataSource?: DataSource;
70
112
  className?: string;
71
- onRowClick?: (record: any) => void;
72
- onItemClick?: (record: any) => void;
113
+ /**
114
+ * TWO parameters since objectui#9357, and the second is not decoration: this
115
+ * prop reaches `useNavigationOverlay` as its `onRowClick`, and `handleClick`
116
+ * invokes it as `onRowClick(record, event)` — the modifier payload a host
117
+ * needs to implement Cmd/Ctrl/middle-click for itself. Declaring one
118
+ * parameter hid the second on the ONE line a host reads. Spelled `any` and
119
+ * not `HandleClickModifiers` for the reason objectui#9341 measured on
120
+ * `ObjectKanbanSchema.onCardClick`: that interface lives in
121
+ * `@object-ui/react`, the published twins in `@object-ui/types` may not name
122
+ * it, and a host that discovered the payload from the implementation
123
+ * annotated it `React.MouseEvent` — which a narrower declaration refuses
124
+ * contravariantly. `BaseSchema`'s own `onClick` / `onChange` / `onSubmit`
125
+ * already use this spelling for exactly this situation.
126
+ */
127
+ onRowClick?: (record: any, event?: any) => void;
128
+ /** The other arm of the same `??` that feeds the hook — see `onRowClick` above (objectui#9357). */
129
+ onItemClick?: (record: any, event?: any) => void;
73
130
  }
74
131
  export declare const ObjectTimeline: React.FC<ObjectTimelineProps>;
75
132
  //# sourceMappingURL=ObjectTimeline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ObjectTimeline.d.ts","sourceRoot":"","sources":["../src/ObjectTimeline.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAoD,MAAM,OAAO,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AA8B3F;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAuB1C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,GAAG;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB;;;;WAIG;QACH,QAAQ,CAAC,EAAE,sBAAsB,CAAC;QAClC;;;;;;;;;WASG;QACH,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACrC;;;WAGG;QACH,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;SAAE,CAAC,CAAC;QAClE;;;;WAIG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,kDAAkD;QAClD,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,sDAAsD;QACtD,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,sDAAsD;QACtD,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,oDAAoD;QACpD,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,oDAAoD;QACpD,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,kDAAkD;QAClD,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,6CAA6C;QAC7C,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;QAE/D,OAAO,CAAC,EAAE;YACR,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,WAAW,CAAC,EAAE,MAAM,CAAC;YACrB,OAAO,CAAC,EAAE,MAAM,CAAC;SAClB,CAAA;KACF,CAAC;IACF,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;CACrC;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA0WxD,CAAA"}
1
+ {"version":3,"file":"ObjectTimeline.d.ts","sourceRoot":"","sources":["../src/ObjectTimeline.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAA4D,MAAM,OAAO,CAAC;AACjF,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAUjH;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAwI1C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,GAAG;QACvB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB;;;;WAIG;QACH,QAAQ,CAAC,EAAE,sBAAsB,CAAC;QAClC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAuCG;QACH,UAAU,CAAC,EAAE,oBAAoB,CAAC;QAClC;;;;;;;;;WASG;QACH,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACrC;;;;WAIG;QACH,IAAI,CAAC,EAAE,KAAK,CAAC;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;SAAE,CAAC,CAAC;QACzD;;;;WAIG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,kDAAkD;QAClD,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,sDAAsD;QACtD,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,sDAAsD;QACtD,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,oDAAoD;QACpD,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,oDAAoD;QACpD,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,kDAAkD;QAClD,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,6CAA6C;QAC7C,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;QAE/D,OAAO,CAAC,EAAE;YACR,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,WAAW,CAAC,EAAE,MAAM,CAAC;YACrB,OAAO,CAAC,EAAE,MAAM,CAAC;SAClB,CAAA;KACF,CAAC;IACF,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;;;OAaG;IACH,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAChD,mGAAmG;IACnG,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;CAClD;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAwtBxD,CAAA"}
package/dist/index.d.ts CHANGED
@@ -40,8 +40,8 @@ declare const TimelineGanttBar: React.ForwardRefExoticComponent<React.HTMLAttrib
40
40
  } & React.RefAttributes<HTMLDivElement>>;
41
41
  declare const TimelineGanttBarContent: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
42
42
  export { Timeline, TimelineItem, timelineItemVariants, TimelineMarker, timelineMarkerVariants, TimelineContent, TimelineTitle, TimelineTime, TimelineDescription, TimelineHorizontal, TimelineHorizontalItem, TimelineGantt, TimelineGanttHeader, TimelineGanttRowLabels, TimelineGanttGrid, TimelineGanttRow, TimelineGanttLabel, TimelineGanttBar, TimelineGanttBarContent, };
43
- export * from './renderer';
44
- export { ObjectTimeline } from './ObjectTimeline';
45
- export type { ObjectTimelineProps } from './ObjectTimeline';
43
+ export * from './renderer.js';
44
+ export { ObjectTimeline } from './ObjectTimeline.js';
45
+ export type { ObjectTimelineProps } from './ObjectTimeline.js';
46
46
  export declare const ObjectTimelineRenderer: React.FC<any>;
47
47
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAE5D,QAAA,MAAM,QAAQ,iHASZ,CAAA;AAGF,QAAA,MAAM,oBAAoB;;8EASxB,CAAA;AAEF,QAAA,MAAM,YAAY;;qHAShB,CAAA;AAGF,QAAA,MAAM,sBAAsB;;8EAiB3B,CAAA;AAED,KAAK,qBAAqB,GAAG,YAAY,CAAC,OAAO,sBAAsB,CAAC,CAAC,SAAS,CAAC,CAAA;AAEnF,QAAA,MAAM,cAAc;cAGN,qBAAqB;wCAUjC,CAAA;AAGF,QAAA,MAAM,eAAe,6GASnB,CAAA;AAGF,QAAA,MAAM,aAAa,qHASjB,CAAA;AAGF,QAAA,MAAM,YAAY,mHAShB,CAAA;AAGF,QAAA,MAAM,mBAAmB,yHASvB,CAAA;AAIF,QAAA,MAAM,kBAAkB,6GAStB,CAAA;AAGF,QAAA,MAAM,sBAAsB,6GAS1B,CAAA;AAIF,QAAA,MAAM,aAAa,6GASjB,CAAA;AAGF,QAAA,MAAM,mBAAmB,6GASvB,CAAA;AAGF,QAAA,MAAM,sBAAsB,6GAS1B,CAAA;AAGF,QAAA,MAAM,iBAAiB,6GASrB,CAAA;AAGF,QAAA,MAAM,gBAAgB,6GASpB,CAAA;AAGF,QAAA,MAAM,kBAAkB,6GAStB,CAAA;AAGF,QAAA,MAAM,gBAAgB;YAGV,MAAM;YACN,MAAM;cACJ,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM;wCA0BjE,CAAA;AAGF,QAAA,MAAM,uBAAuB,6GAS3B,CAAA;AAGF,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,aAAa,EACb,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,GACxB,CAAA;AAGD,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAiC5D,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,CAiBhD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAE5D,QAAA,MAAM,QAAQ,iHASZ,CAAA;AAGF,QAAA,MAAM,oBAAoB;;8EASxB,CAAA;AAEF,QAAA,MAAM,YAAY;;qHAShB,CAAA;AAGF,QAAA,MAAM,sBAAsB;;8EAiB3B,CAAA;AAED,KAAK,qBAAqB,GAAG,YAAY,CAAC,OAAO,sBAAsB,CAAC,CAAC,SAAS,CAAC,CAAA;AAEnF,QAAA,MAAM,cAAc;cAGN,qBAAqB;wCAUjC,CAAA;AAGF,QAAA,MAAM,eAAe,6GASnB,CAAA;AAGF,QAAA,MAAM,aAAa,qHASjB,CAAA;AAGF,QAAA,MAAM,YAAY,mHAShB,CAAA;AAGF,QAAA,MAAM,mBAAmB,yHASvB,CAAA;AAIF,QAAA,MAAM,kBAAkB,6GAStB,CAAA;AAGF,QAAA,MAAM,sBAAsB,6GAS1B,CAAA;AAIF,QAAA,MAAM,aAAa,6GASjB,CAAA;AAGF,QAAA,MAAM,mBAAmB,6GASvB,CAAA;AAGF,QAAA,MAAM,sBAAsB,6GAS1B,CAAA;AAGF,QAAA,MAAM,iBAAiB,6GASrB,CAAA;AAGF,QAAA,MAAM,gBAAgB,6GASpB,CAAA;AAGF,QAAA,MAAM,kBAAkB,6GAStB,CAAA;AAGF,QAAA,MAAM,gBAAgB;YAGV,MAAM;YACN,MAAM;cACJ,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM;wCA0BjE,CAAA;AAGF,QAAA,MAAM,uBAAuB,6GAS3B,CAAA;AAGF,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,aAAa,EACb,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,GACxB,CAAA;AAGD,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAkC5D,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,CAiB/C,CAAC"}