@happyvertical/smrt-events 0.30.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/AGENTS.md +20 -0
- package/CLAUDE.md +1 -0
- package/LICENSE +7 -0
- package/README.md +151 -0
- package/dist/__smrt-register__.d.ts +2 -0
- package/dist/__smrt-register__.d.ts.map +1 -0
- package/dist/collections/EventAssetCollection.d.ts +16 -0
- package/dist/collections/EventAssetCollection.d.ts.map +1 -0
- package/dist/collections/EventCollection.d.ts +108 -0
- package/dist/collections/EventCollection.d.ts.map +1 -0
- package/dist/collections/EventParticipantCollection.d.ts +42 -0
- package/dist/collections/EventParticipantCollection.d.ts.map +1 -0
- package/dist/collections/EventSeriesCollection.d.ts +62 -0
- package/dist/collections/EventSeriesCollection.d.ts.map +1 -0
- package/dist/collections/EventTypeCollection.d.ts +53 -0
- package/dist/collections/EventTypeCollection.d.ts.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1419 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.json +4067 -0
- package/dist/models/Event.d.ts +92 -0
- package/dist/models/Event.d.ts.map +1 -0
- package/dist/models/EventAsset.d.ts +17 -0
- package/dist/models/EventAsset.d.ts.map +1 -0
- package/dist/models/EventParticipant.d.ts +65 -0
- package/dist/models/EventParticipant.d.ts.map +1 -0
- package/dist/models/EventSeries.d.ts +73 -0
- package/dist/models/EventSeries.d.ts.map +1 -0
- package/dist/models/EventType.d.ts +44 -0
- package/dist/models/EventType.d.ts.map +1 -0
- package/dist/playground.d.ts +2 -0
- package/dist/playground.d.ts.map +1 -0
- package/dist/playground.js +47 -0
- package/dist/playground.js.map +1 -0
- package/dist/smrt-knowledge.json +1662 -0
- package/dist/svelte/components/MeetingView.svelte +321 -0
- package/dist/svelte/components/MeetingView.svelte.d.ts +9 -0
- package/dist/svelte/components/MeetingView.svelte.d.ts.map +1 -0
- package/dist/svelte/i18n.d.ts +10 -0
- package/dist/svelte/i18n.d.ts.map +1 -0
- package/dist/svelte/i18n.js +11 -0
- package/dist/svelte/index.d.ts +11 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +18 -0
- package/dist/svelte/playground.d.ts +40 -0
- package/dist/svelte/playground.d.ts.map +1 -0
- package/dist/svelte/playground.js +43 -0
- package/dist/svelte/types.d.ts +37 -0
- package/dist/svelte/types.d.ts.map +1 -0
- package/dist/svelte/types.js +6 -0
- package/dist/types.d.ts +127 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ui.d.ts +10 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +28 -0
- package/dist/ui.js.map +1 -0
- package/dist/utils.d.ts +93 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +127 -0
- package/dist/utils.js.map +1 -0
- package/package.json +102 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# @happyvertical/smrt-events
|
|
2
|
+
|
|
3
|
+
Infinite-nesting event hierarchy with series, types, participants, and role/placement management.
|
|
4
|
+
|
|
5
|
+
## Models
|
|
6
|
+
|
|
7
|
+
- **Event** (STI, extends `SmrtHierarchical`): self-referencing parent-child via `parentId` (UUID). Links to `seriesId`, `typeId`, `placeId`. Status: scheduled/in_progress/completed/cancelled/postponed. Hierarchy traversal (`getParent()`, `getChildren()`, `getAncestors()`, `getDescendants()`, `getHierarchy()`, `moveTo()`) is provided by `SmrtHierarchical`; `getRootEvent()` and `isRoot()` remain on `Event`.
|
|
8
|
+
- **EventAsset**: dedicated owned-asset join in `event_assets` with `relationship` and `sortOrder`.
|
|
9
|
+
- **EventType**: classification with JSON schema for custom fields per type.
|
|
10
|
+
- **EventSeries**: recurrence patterns (daily/weekly/monthly/yearly).
|
|
11
|
+
- **EventParticipant**: junction with `role` (home/away/speaker/panelist/etc.), `placement` (numeric — team ordering and rankings), `groupId` (team grouping within event). `conflictColumns: ['event_id', 'profile_id', 'role']`.
|
|
12
|
+
|
|
13
|
+
## Gotchas
|
|
14
|
+
|
|
15
|
+
- **No depth limit** on event hierarchy — deep nesting can cause N+1 queries
|
|
16
|
+
- **Placement is numeric**: used for both team ordering (0=home, 1=away) and rankings — context-dependent
|
|
17
|
+
- **GroupId not enforced at DB level**: for logical grouping only (e.g., team members in a game)
|
|
18
|
+
- **Optional tenancy** with nullable tenantId
|
|
19
|
+
- **Metadata stored as JSON string** with get/set/update helpers
|
|
20
|
+
- **Owned asset helpers**: use `Event.getAssets()` / `addAsset()` / `removeAsset()` or the matching `EventCollection` wrappers instead of generic `AssetAssociation`
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright <2025> <Happy Vertical Corporation>
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# @happyvertical/smrt-events
|
|
2
|
+
|
|
3
|
+
Infinite-nesting event hierarchy with series, participant tracking, and recurrence patterns. Events can model anything from conferences with sessions to sports games with periods and goals.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @happyvertical/smrt-events
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Hierarchical events with participants
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { EventCollection, EventSeriesCollection, EventParticipantCollection } from '@happyvertical/smrt-events';
|
|
17
|
+
|
|
18
|
+
const events = await EventCollection.create();
|
|
19
|
+
|
|
20
|
+
// Create a game with nested periods
|
|
21
|
+
const game = await events.create({
|
|
22
|
+
name: 'Lakers vs Warriors',
|
|
23
|
+
slug: 'lakers-warriors-2024-01-20',
|
|
24
|
+
startDate: new Date('2024-01-20T19:30:00'),
|
|
25
|
+
endDate: new Date('2024-01-20T22:00:00'),
|
|
26
|
+
status: 'scheduled',
|
|
27
|
+
placeId: 'arena-id', // plain string FK to smrt-places
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const quarter = await events.create({
|
|
31
|
+
name: '1st Quarter',
|
|
32
|
+
parentId: game.id, // infinite nesting (via SmrtHierarchical)
|
|
33
|
+
startDate: new Date('2024-01-20T19:30:00'),
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Hierarchy traversal
|
|
37
|
+
const hierarchy = await quarter.getHierarchy();
|
|
38
|
+
console.log(hierarchy.ancestors.map(e => e.name)); // ['Lakers vs Warriors']
|
|
39
|
+
|
|
40
|
+
// Add participants with roles and placement
|
|
41
|
+
const participants = await EventParticipantCollection.create();
|
|
42
|
+
await participants.create({
|
|
43
|
+
eventId: game.id,
|
|
44
|
+
profileId: 'lakers-id', // plain string FK to smrt-profiles
|
|
45
|
+
role: 'home',
|
|
46
|
+
placement: 0,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Recurring series
|
|
50
|
+
const series = await EventSeriesCollection.create();
|
|
51
|
+
await series.create({
|
|
52
|
+
name: 'Weekly Standup',
|
|
53
|
+
slug: 'weekly-standup-2024',
|
|
54
|
+
recurrence: { frequency: 'weekly', interval: 1, byDay: ['MO', 'WE', 'FR'] },
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Owned assets
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { AssetCollection } from '@happyvertical/smrt-assets';
|
|
62
|
+
|
|
63
|
+
const assets = await AssetCollection.create();
|
|
64
|
+
const hero = await assets.create({
|
|
65
|
+
name: 'launch-poster.jpg',
|
|
66
|
+
sourceUri: 'file:///tmp/launch-poster.jpg',
|
|
67
|
+
mimeType: 'image/jpeg',
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
await game.addAsset(hero, 'hero');
|
|
71
|
+
await events.addAsset(game.id!, hero, 'gallery', 1);
|
|
72
|
+
|
|
73
|
+
const heroAssets = await game.getAssets('hero');
|
|
74
|
+
const galleryAssets = await events.getAssets(game.id!, 'gallery');
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## API
|
|
78
|
+
|
|
79
|
+
### Models
|
|
80
|
+
|
|
81
|
+
| Export | Description |
|
|
82
|
+
|--------|------------|
|
|
83
|
+
| `Event` | Hierarchical event with status lifecycle, STI enabled. Links to series, type, place via string IDs |
|
|
84
|
+
| `EventSeries` | Recurring event group with recurrence patterns (daily/weekly/monthly/yearly) |
|
|
85
|
+
| `EventType` | Classification with JSON schema for custom fields per type |
|
|
86
|
+
| `EventParticipant` | Junction linking profiles to events with role, placement, and groupId |
|
|
87
|
+
| `EventAsset` | Dedicated owned-asset join stored in `event_assets` with `relationship` and `sortOrder` |
|
|
88
|
+
|
|
89
|
+
### Collections
|
|
90
|
+
|
|
91
|
+
| Export | Description |
|
|
92
|
+
|--------|------------|
|
|
93
|
+
| `EventCollection` | CRUD + hierarchy traversal for events |
|
|
94
|
+
| `EventAssetCollection` | Direct access to `event_assets` rows plus asset helper wrappers |
|
|
95
|
+
| `EventSeriesCollection` | CRUD for event series |
|
|
96
|
+
| `EventTypeCollection` | CRUD for event types |
|
|
97
|
+
| `EventParticipantCollection` | CRUD for participants (conflictColumns: event_id, profile_id, role) |
|
|
98
|
+
|
|
99
|
+
### Types
|
|
100
|
+
|
|
101
|
+
| Export | Description |
|
|
102
|
+
|--------|------------|
|
|
103
|
+
| `EventOptions`, `EventSeriesOptions`, `EventTypeOptions`, `EventParticipantOptions` | Creation option types for each model |
|
|
104
|
+
| `EventStatus` | `'scheduled' \| 'in_progress' \| 'completed' \| 'cancelled' \| 'postponed'` |
|
|
105
|
+
| `ParticipantRole` | Role values (speaker, home, away, organizer, etc.) |
|
|
106
|
+
| `RecurrenceFrequency` | `'daily' \| 'weekly' \| 'monthly' \| 'yearly'` |
|
|
107
|
+
| `RecurrencePattern` | Recurrence definition with count, until, byDay, byMonth filters |
|
|
108
|
+
| `EventSearchFilters`, `EventSeriesSearchFilters`, `ParticipantSearchFilters` | Query filter types |
|
|
109
|
+
|
|
110
|
+
### Utilities
|
|
111
|
+
|
|
112
|
+
| Export | Description |
|
|
113
|
+
|--------|------------|
|
|
114
|
+
| `formatEventDateRange` | Format start/end dates as human-readable string |
|
|
115
|
+
| `generateEventSlug` | Create URL-friendly slug from name + date |
|
|
116
|
+
| `checkSchedulingConflict` | Detect overlapping time ranges |
|
|
117
|
+
| `calculateDuration` | Duration in milliseconds between two dates |
|
|
118
|
+
| `formatDuration` | Human-readable duration (e.g., "2h 30m") |
|
|
119
|
+
| `isEventNow` | Check if event is currently in progress |
|
|
120
|
+
| `getEventStatusFromDates` | Auto-detect status from start/end dates |
|
|
121
|
+
| `sortEventsByDate` | Sort events chronologically |
|
|
122
|
+
| `validateEventStatus` | Validate status transition is allowed |
|
|
123
|
+
| `calculateNextOccurrence` | Next date for a recurrence pattern |
|
|
124
|
+
| `parseRecurrencePattern` | Parse recurrence from string or object |
|
|
125
|
+
|
|
126
|
+
### UI Metadata
|
|
127
|
+
|
|
128
|
+
| Export | Description |
|
|
129
|
+
|--------|------------|
|
|
130
|
+
| `EVENTS_MODULE_META` | Module metadata for UI registration |
|
|
131
|
+
| `EVENTS_UI_SLOTS` | UI slot definitions for the events module |
|
|
132
|
+
|
|
133
|
+
### Instance Methods (Event)
|
|
134
|
+
|
|
135
|
+
`getParent()`, `getChildren()`, `getAncestors()`, `getDescendants()`, `getRootEvent()`, `getHierarchy()` -- hierarchy traversal on any Event instance.
|
|
136
|
+
|
|
137
|
+
Owned asset helpers are available on both `Event` and `EventCollection` via
|
|
138
|
+
`getAssets()`, `addAsset()`, and `removeAsset()`. Common relationships include
|
|
139
|
+
`hero`, `gallery`, `attachment`, and `thumbnail`.
|
|
140
|
+
|
|
141
|
+
## Dependencies
|
|
142
|
+
|
|
143
|
+
| Package | Purpose |
|
|
144
|
+
|---------|---------|
|
|
145
|
+
| `@happyvertical/smrt-core` | SmrtObject/SmrtCollection base classes |
|
|
146
|
+
| `@happyvertical/smrt-tenancy` | Optional tenant scoping |
|
|
147
|
+
| `@happyvertical/smrt-places` | Place references (cross-package string FKs) |
|
|
148
|
+
| `@happyvertical/smrt-profiles` | Participant profile references (cross-package string FKs) |
|
|
149
|
+
| `@happyvertical/smrt-types` | Shared TypeScript types |
|
|
150
|
+
| `@happyvertical/sql` | Database operations |
|
|
151
|
+
| `@happyvertical/ai` | AI integration |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"__smrt-register__.d.ts","sourceRoot":"","sources":["../src/__smrt-register__.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Asset } from '@happyvertical/smrt-assets';
|
|
2
|
+
import { SmrtCollectionOptions, SmrtJunction } from '@happyvertical/smrt-core';
|
|
3
|
+
import { EventAsset } from '../models/EventAsset';
|
|
4
|
+
export interface EventAssetCollectionOptions extends SmrtCollectionOptions {
|
|
5
|
+
}
|
|
6
|
+
export declare class EventAssetCollection extends SmrtJunction<EventAsset> {
|
|
7
|
+
static readonly _itemClass: typeof EventAsset;
|
|
8
|
+
protected leftField: string;
|
|
9
|
+
protected rightField: string;
|
|
10
|
+
private eventCollectionPromise;
|
|
11
|
+
private getEventCollection;
|
|
12
|
+
getAssets(eventId: string, relationship?: string): Promise<Asset[]>;
|
|
13
|
+
addAsset(eventId: string, asset: Asset, relationship?: string, sortOrder?: number): Promise<void>;
|
|
14
|
+
removeAsset(eventId: string, assetId: string, relationship?: string): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=EventAssetCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventAssetCollection.d.ts","sourceRoot":"","sources":["../../src/collections/EventAssetCollection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAMxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAQ,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGlD,MAAM,WAAW,2BAA4B,SAAQ,qBAAqB;CAAG;AAE7E,qBAKa,oBAAqB,SAAQ,YAAY,CAAC,UAAU,CAAC;IAChE,MAAM,CAAC,QAAQ,CAAC,UAAU,oBAAc;IACxC,SAAS,CAAC,SAAS,SAAa;IAChC,SAAS,CAAC,UAAU,SAAa;IAEjC,OAAO,CAAC,sBAAsB,CAAyC;YAEzD,kBAAkB;IAS1B,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAQnE,QAAQ,CACZ,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,EACZ,YAAY,SAAe,EAC3B,SAAS,SAAI,GACZ,OAAO,CAAC,IAAI,CAAC;IAWV,WAAW,CACf,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC;CASjB"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Asset } from '@happyvertical/smrt-assets';
|
|
2
|
+
import { SmrtCollection } from '@happyvertical/smrt-core';
|
|
3
|
+
import { Event } from '../models/Event';
|
|
4
|
+
import { EventSearchFilters, EventStatus } from '../types';
|
|
5
|
+
export declare class EventCollection extends SmrtCollection<Event> {
|
|
6
|
+
static readonly _itemClass: typeof Event;
|
|
7
|
+
/**
|
|
8
|
+
* Get events by series
|
|
9
|
+
*
|
|
10
|
+
* @param seriesId - EventSeries ID
|
|
11
|
+
* @returns Array of Event instances
|
|
12
|
+
*/
|
|
13
|
+
getBySeriesId(seriesId: string): Promise<Event[]>;
|
|
14
|
+
/**
|
|
15
|
+
* Get events at a specific place
|
|
16
|
+
*
|
|
17
|
+
* @param placeId - Place ID
|
|
18
|
+
* @returns Array of Event instances
|
|
19
|
+
*/
|
|
20
|
+
getByPlace(placeId: string): Promise<Event[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Get events by date range
|
|
23
|
+
*
|
|
24
|
+
* @param startDate - Start of date range
|
|
25
|
+
* @param endDate - End of date range
|
|
26
|
+
* @returns Array of Event instances
|
|
27
|
+
*/
|
|
28
|
+
getByDateRange(startDate: Date, endDate: Date): Promise<Event[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Get upcoming events
|
|
31
|
+
*
|
|
32
|
+
* @param limit - Maximum number of events to return
|
|
33
|
+
* @returns Array of Event instances starting in the future
|
|
34
|
+
*/
|
|
35
|
+
getUpcoming(limit?: number): Promise<Event[]>;
|
|
36
|
+
/**
|
|
37
|
+
* Get events by status
|
|
38
|
+
*
|
|
39
|
+
* @param status - Event status to filter by
|
|
40
|
+
* @returns Array of Event instances
|
|
41
|
+
*/
|
|
42
|
+
getByStatus(status: EventStatus): Promise<Event[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Get events by type
|
|
45
|
+
*
|
|
46
|
+
* @param typeId - EventType ID
|
|
47
|
+
* @returns Array of Event instances
|
|
48
|
+
*/
|
|
49
|
+
getByType(typeId: string): Promise<Event[]>;
|
|
50
|
+
/**
|
|
51
|
+
* Get root events (no parent)
|
|
52
|
+
*
|
|
53
|
+
* @returns Array of Event instances with no parent
|
|
54
|
+
*/
|
|
55
|
+
getRootEvents(): Promise<Event[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Get children of a parent event
|
|
58
|
+
*
|
|
59
|
+
* @param parentId - Parent event ID
|
|
60
|
+
* @returns Array of child Event instances
|
|
61
|
+
*/
|
|
62
|
+
getByParent(parentId: string): Promise<Event[]>;
|
|
63
|
+
/**
|
|
64
|
+
* Get full event tree (hierarchy)
|
|
65
|
+
*
|
|
66
|
+
* @param eventId - Root event ID
|
|
67
|
+
* @returns Object with root event and nested children
|
|
68
|
+
*/
|
|
69
|
+
getEventTree(eventId: string): Promise<Event | null>;
|
|
70
|
+
getAssets(eventId: string, relationship?: string): Promise<Asset[]>;
|
|
71
|
+
addAsset(eventId: string, asset: Asset, relationship?: string, sortOrder?: number): Promise<void>;
|
|
72
|
+
removeAsset(eventId: string, assetId: string, relationship?: string): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Search events with filters
|
|
75
|
+
*
|
|
76
|
+
* @param query - Search query for name/description
|
|
77
|
+
* @param filters - Additional filter criteria
|
|
78
|
+
* @returns Array of matching Event instances
|
|
79
|
+
*/
|
|
80
|
+
search(query: string, filters?: EventSearchFilters): Promise<Event[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Get events in progress
|
|
83
|
+
*
|
|
84
|
+
* @returns Array of Event instances currently in progress
|
|
85
|
+
*/
|
|
86
|
+
getInProgress(): Promise<Event[]>;
|
|
87
|
+
/**
|
|
88
|
+
* Find all events for a specific tenant
|
|
89
|
+
*
|
|
90
|
+
* @param tenantId - Tenant ID to filter by
|
|
91
|
+
* @returns Array of Event instances for the tenant
|
|
92
|
+
*/
|
|
93
|
+
findByTenant(tenantId: string): Promise<Event[]>;
|
|
94
|
+
/**
|
|
95
|
+
* Find all global events (no tenant association)
|
|
96
|
+
*
|
|
97
|
+
* @returns Array of Event instances with no tenant
|
|
98
|
+
*/
|
|
99
|
+
findGlobal(): Promise<Event[]>;
|
|
100
|
+
/**
|
|
101
|
+
* Find events for a tenant including global events
|
|
102
|
+
*
|
|
103
|
+
* @param tenantId - Tenant ID to filter by
|
|
104
|
+
* @returns Array of Event instances for the tenant and global events
|
|
105
|
+
*/
|
|
106
|
+
findWithGlobals(tenantId: string): Promise<Event[]>;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=EventCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventCollection.d.ts","sourceRoot":"","sources":["../../src/collections/EventCollection.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAMxD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEhE,qBAAa,eAAgB,SAAQ,cAAc,CAAC,KAAK,CAAC;IACxD,MAAM,CAAC,QAAQ,CAAC,UAAU,eAAS;IAEnC;;;;;OAKG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAIvD;;;;;OAKG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAInD;;;;;;OAMG;IACG,cAAc,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAStE;;;;;OAKG;IACG,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAcnD;;;;;OAKG;IACG,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAIxD;;;;;OAKG;IACG,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAIjD;;;;OAIG;IACG,aAAa,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAKvC;;;;;OAKG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAIrD;;;;;OAKG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAOpD,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAInE,QAAQ,CACZ,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,EACZ,YAAY,SAAe,EAC3B,SAAS,SAAI,GACZ,OAAO,CAAC,IAAI,CAAC;IAWV,WAAW,CACf,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC;IAUhB;;;;;;OAMG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAmD3E;;;;OAIG;IACG,aAAa,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IASvC;;;;;OAKG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAItD;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAIpC;;;;;OAKG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;CAM1D"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { SmrtJunction } from '@happyvertical/smrt-core';
|
|
2
|
+
import { EventParticipant } from '../models/EventParticipant';
|
|
3
|
+
import { ParticipantSearchFilters } from '../types';
|
|
4
|
+
export declare class EventParticipantCollection extends SmrtJunction<EventParticipant> {
|
|
5
|
+
static readonly _itemClass: typeof EventParticipant;
|
|
6
|
+
protected leftField: string;
|
|
7
|
+
protected rightField: string;
|
|
8
|
+
protected sortField: string | null;
|
|
9
|
+
protected positionField: string | null;
|
|
10
|
+
/**
|
|
11
|
+
* Get participants ordered by placement (nulls last).
|
|
12
|
+
*/
|
|
13
|
+
getByPlacement(eventId: string): Promise<EventParticipant[]>;
|
|
14
|
+
/**
|
|
15
|
+
* Get participants by group within an event.
|
|
16
|
+
*/
|
|
17
|
+
getByGroup(eventId: string, groupId: string): Promise<EventParticipant[]>;
|
|
18
|
+
/**
|
|
19
|
+
* Get the home participant(s) — placement = 0.
|
|
20
|
+
*/
|
|
21
|
+
getHome(eventId: string): Promise<EventParticipant[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Get the away participant(s) — placement = 1.
|
|
24
|
+
*/
|
|
25
|
+
getAway(eventId: string): Promise<EventParticipant[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Search participants with optional filters.
|
|
28
|
+
*/
|
|
29
|
+
search(filters: ParticipantSearchFilters): Promise<EventParticipant[]>;
|
|
30
|
+
/**
|
|
31
|
+
* Get participation statistics for a profile, optionally filtered by event type.
|
|
32
|
+
*/
|
|
33
|
+
getParticipantStats(profileId: string, eventTypeId?: string): Promise<{
|
|
34
|
+
totalEvents: number;
|
|
35
|
+
byRole: Record<string, number>;
|
|
36
|
+
byPlacement: Record<number, number>;
|
|
37
|
+
}>;
|
|
38
|
+
findByTenant(tenantId: string): Promise<EventParticipant[]>;
|
|
39
|
+
findGlobal(): Promise<EventParticipant[]>;
|
|
40
|
+
findWithGlobals(tenantId: string): Promise<EventParticipant[]>;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=EventParticipantCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventParticipantCollection.d.ts","sourceRoot":"","sources":["../../src/collections/EventParticipantCollection.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAQ,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAIzD,qBACa,0BAA2B,SAAQ,YAAY,CAAC,gBAAgB,CAAC;IAC5E,MAAM,CAAC,QAAQ,CAAC,UAAU,0BAAoB;IAC9C,SAAS,CAAC,SAAS,SAAa;IAChC,SAAS,CAAC,UAAU,SAAe;IAGnC,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC1C,SAAS,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAQ;IAM9C;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAWlE;;OAEG;IACG,UAAU,CACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAI9B;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAI3D;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAI3D;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAqB5E;;OAEG;IACG,mBAAmB,CACvB,SAAS,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC;QACT,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACrC,CAAC;IAqCI,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAI3D,UAAU,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAIzC,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAMrE"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { SmrtCollection } from '@happyvertical/smrt-core';
|
|
2
|
+
import { EventSeries } from '../models/EventSeries';
|
|
3
|
+
import { EventSeriesSearchFilters } from '../types';
|
|
4
|
+
export declare class EventSeriesCollection extends SmrtCollection<EventSeries> {
|
|
5
|
+
static readonly _itemClass: typeof EventSeries;
|
|
6
|
+
/**
|
|
7
|
+
* Get series by organizer
|
|
8
|
+
*
|
|
9
|
+
* @param organizerId - Profile ID of the organizer
|
|
10
|
+
* @returns Array of EventSeries instances
|
|
11
|
+
*/
|
|
12
|
+
getByOrganizer(organizerId: string): Promise<EventSeries[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Get currently active series
|
|
15
|
+
*
|
|
16
|
+
* @returns Array of EventSeries instances active today
|
|
17
|
+
*/
|
|
18
|
+
getActive(): Promise<EventSeries[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Get upcoming series
|
|
21
|
+
*
|
|
22
|
+
* @param limit - Maximum number of series to return
|
|
23
|
+
* @returns Array of EventSeries instances starting in the future
|
|
24
|
+
*/
|
|
25
|
+
getUpcoming(limit?: number): Promise<EventSeries[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Get series by type
|
|
28
|
+
*
|
|
29
|
+
* @param typeId - EventType ID
|
|
30
|
+
* @returns Array of EventSeries instances
|
|
31
|
+
*/
|
|
32
|
+
getByType(typeId: string): Promise<EventSeries[]>;
|
|
33
|
+
/**
|
|
34
|
+
* Search series with filters
|
|
35
|
+
*
|
|
36
|
+
* @param query - Search query for name/description
|
|
37
|
+
* @param filters - Additional filter criteria
|
|
38
|
+
* @returns Array of matching EventSeries instances
|
|
39
|
+
*/
|
|
40
|
+
search(query: string, filters?: EventSeriesSearchFilters): Promise<EventSeries[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Find all event series for a specific tenant
|
|
43
|
+
*
|
|
44
|
+
* @param tenantId - Tenant ID to filter by
|
|
45
|
+
* @returns Array of EventSeries instances for the tenant
|
|
46
|
+
*/
|
|
47
|
+
findByTenant(tenantId: string): Promise<EventSeries[]>;
|
|
48
|
+
/**
|
|
49
|
+
* Find all global event series (no tenant association)
|
|
50
|
+
*
|
|
51
|
+
* @returns Array of EventSeries instances with no tenant
|
|
52
|
+
*/
|
|
53
|
+
findGlobal(): Promise<EventSeries[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Find event series for a tenant including global series
|
|
56
|
+
*
|
|
57
|
+
* @param tenantId - Tenant ID to filter by
|
|
58
|
+
* @returns Array of EventSeries instances for the tenant and global series
|
|
59
|
+
*/
|
|
60
|
+
findWithGlobals(tenantId: string): Promise<EventSeries[]>;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=EventSeriesCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventSeriesCollection.d.ts","sourceRoot":"","sources":["../../src/collections/EventSeriesCollection.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAEzD,qBAAa,qBAAsB,SAAQ,cAAc,CAAC,WAAW,CAAC;IACpE,MAAM,CAAC,QAAQ,CAAC,UAAU,qBAAe;IAEzC;;;;;OAKG;IACG,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAIjE;;;;OAIG;IACG,SAAS,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAWzC;;;;;OAKG;IACG,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAczD;;;;;OAKG;IACG,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAIvD;;;;;;OAMG;IACG,MAAM,CACV,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,WAAW,EAAE,CAAC;IAsCzB;;;;;OAKG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAI5D;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAI1C;;;;;OAKG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;CAMhE"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { SmrtCollection } from '@happyvertical/smrt-core';
|
|
2
|
+
import { EventType } from '../models/EventType';
|
|
3
|
+
export declare class EventTypeCollection extends SmrtCollection<EventType> {
|
|
4
|
+
static readonly _itemClass: typeof EventType;
|
|
5
|
+
/**
|
|
6
|
+
* Get or create an event type by slug
|
|
7
|
+
*
|
|
8
|
+
* @param slug - EventType slug (e.g., 'basketball-game', 'concert')
|
|
9
|
+
* @param name - Optional display name (defaults to capitalized slug)
|
|
10
|
+
* @returns EventType instance
|
|
11
|
+
*/
|
|
12
|
+
getOrCreate(slug: string, name?: string): Promise<EventType>;
|
|
13
|
+
/**
|
|
14
|
+
* Get an event type by slug
|
|
15
|
+
*
|
|
16
|
+
* @param slug - EventType slug to search for
|
|
17
|
+
* @returns EventType instance or null if not found
|
|
18
|
+
*/
|
|
19
|
+
getBySlug(slug: string): Promise<EventType | null>;
|
|
20
|
+
/**
|
|
21
|
+
* Initialize default event types
|
|
22
|
+
*
|
|
23
|
+
* Creates common event types if they don't exist:
|
|
24
|
+
* - Sports: game, period, goal, assist, penalty
|
|
25
|
+
* - Entertainment: concert, performance, song
|
|
26
|
+
* - Professional: conference, session, presentation, workshop
|
|
27
|
+
* - Community: meeting, agenda-item, motion, vote
|
|
28
|
+
*
|
|
29
|
+
* @returns Array of created/existing event types
|
|
30
|
+
*/
|
|
31
|
+
initializeDefaults(): Promise<EventType[]>;
|
|
32
|
+
/**
|
|
33
|
+
* Find all event types for a specific tenant
|
|
34
|
+
*
|
|
35
|
+
* @param tenantId - Tenant ID to filter by
|
|
36
|
+
* @returns Array of EventType instances for the tenant
|
|
37
|
+
*/
|
|
38
|
+
findByTenant(tenantId: string): Promise<EventType[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Find all global event types (no tenant association)
|
|
41
|
+
*
|
|
42
|
+
* @returns Array of EventType instances with no tenant
|
|
43
|
+
*/
|
|
44
|
+
findGlobal(): Promise<EventType[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Find event types for a tenant including global types
|
|
47
|
+
*
|
|
48
|
+
* @param tenantId - Tenant ID to filter by
|
|
49
|
+
* @returns Array of EventType instances for the tenant and global types
|
|
50
|
+
*/
|
|
51
|
+
findWithGlobals(tenantId: string): Promise<EventType[]>;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=EventTypeCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventTypeCollection.d.ts","sourceRoot":"","sources":["../../src/collections/EventTypeCollection.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,qBAAa,mBAAoB,SAAQ,cAAc,CAAC,SAAS,CAAC;IAChE,MAAM,CAAC,QAAQ,CAAC,UAAU,mBAAa;IAEvC;;;;;;OAMG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAkBlE;;;;;OAKG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAIxD;;;;;;;;;;OAUG;IACG,kBAAkB,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IA0DhD;;;;;OAKG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAI1D;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAIxC;;;;;OAKG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;CAM9D"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { EventAssetCollection } from './collections/EventAssetCollection';
|
|
2
|
+
export { EventCollection } from './collections/EventCollection';
|
|
3
|
+
export { EventParticipantCollection } from './collections/EventParticipantCollection';
|
|
4
|
+
export { EventSeriesCollection } from './collections/EventSeriesCollection';
|
|
5
|
+
export { EventTypeCollection } from './collections/EventTypeCollection';
|
|
6
|
+
export { Event } from './models/Event';
|
|
7
|
+
export type { EventAssetOptions } from './models/EventAsset';
|
|
8
|
+
export { EventAsset } from './models/EventAsset';
|
|
9
|
+
export { EventParticipant } from './models/EventParticipant';
|
|
10
|
+
export { EventSeries } from './models/EventSeries';
|
|
11
|
+
export { EventType } from './models/EventType';
|
|
12
|
+
export type { EventOptions, EventParticipantOptions, EventSearchFilters, EventSeriesOptions, EventSeriesSearchFilters, EventStatus, EventTypeOptions, ParticipantRole, ParticipantSearchFilters, RecurrenceFrequency, RecurrencePattern, } from './types';
|
|
13
|
+
export { EVENTS_MODULE_META, EVENTS_UI_SLOTS } from './ui';
|
|
14
|
+
export { calculateDuration, calculateNextOccurrence, checkSchedulingConflict, formatDuration, formatEventDateRange, generateEventSlug, getEventStatusFromDates, isEventNow, parseRecurrencePattern, sortEventsByDate, validateEventStatus, } from './utils';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,wBAAwB,CAAC;AAEhC,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,0BAA0B,EAAE,MAAM,0CAA0C,CAAC;AACtF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAE5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,YAAY,EACV,YAAY,EACZ,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,wBAAwB,EACxB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAE3D,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,uBAAuB,EACvB,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,uBAAuB,EACvB,UAAU,EACV,sBAAsB,EACtB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,SAAS,CAAC"}
|