@framers/agentos 0.1.52 → 0.1.53

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.
Files changed (98) hide show
  1. package/dist/api/AgentOS.d.ts +10 -10
  2. package/dist/api/AgentOS.d.ts.map +1 -1
  3. package/dist/channels/index.d.ts +2 -1
  4. package/dist/channels/index.d.ts.map +1 -1
  5. package/dist/channels/index.js +2 -1
  6. package/dist/channels/index.js.map +1 -1
  7. package/dist/core/agency/index.d.ts +1 -2
  8. package/dist/core/agency/index.d.ts.map +1 -1
  9. package/dist/core/agency/index.js +1 -2
  10. package/dist/core/agency/index.js.map +1 -1
  11. package/dist/core/agents/AgentCore.d.ts +8 -19
  12. package/dist/core/agents/AgentCore.d.ts.map +1 -1
  13. package/dist/core/agents/AgentCore.js +7 -15
  14. package/dist/core/agents/AgentCore.js.map +1 -1
  15. package/dist/core/agents/AgentFactory.d.ts +9 -13
  16. package/dist/core/agents/AgentFactory.d.ts.map +1 -1
  17. package/dist/core/agents/AgentFactory.js +9 -13
  18. package/dist/core/agents/AgentFactory.js.map +1 -1
  19. package/dist/core/audio/SilenceDetector.d.ts +5 -5
  20. package/dist/core/audio/SilenceDetector.js +5 -5
  21. package/dist/core/evaluation/index.d.ts +2 -2
  22. package/dist/core/evaluation/index.js +2 -2
  23. package/dist/core/hitl/index.d.ts +1 -2
  24. package/dist/core/hitl/index.d.ts.map +1 -1
  25. package/dist/core/hitl/index.js +1 -2
  26. package/dist/core/hitl/index.js.map +1 -1
  27. package/dist/core/index.d.ts +1 -1
  28. package/dist/core/index.js +1 -1
  29. package/dist/core/llm/IPromptEngine.d.ts +13 -8
  30. package/dist/core/llm/IPromptEngine.d.ts.map +1 -1
  31. package/dist/core/llm/IPromptEngine.js.map +1 -1
  32. package/dist/core/marketplace/index.d.ts +2 -2
  33. package/dist/core/marketplace/index.js +2 -2
  34. package/dist/core/observability/index.d.ts +2 -2
  35. package/dist/core/observability/index.js +2 -2
  36. package/dist/core/planning/index.d.ts +1 -2
  37. package/dist/core/planning/index.d.ts.map +1 -1
  38. package/dist/core/planning/index.js +1 -2
  39. package/dist/core/planning/index.js.map +1 -1
  40. package/dist/core/provenance/index.d.ts +2 -2
  41. package/dist/core/provenance/index.js +2 -2
  42. package/dist/core/safety/index.d.ts +3 -2
  43. package/dist/core/safety/index.d.ts.map +1 -1
  44. package/dist/core/safety/index.js +3 -2
  45. package/dist/core/safety/index.js.map +1 -1
  46. package/dist/core/sandbox/index.d.ts +2 -2
  47. package/dist/core/sandbox/index.js +2 -2
  48. package/dist/core/structured/index.d.ts +1 -2
  49. package/dist/core/structured/index.d.ts.map +1 -1
  50. package/dist/core/structured/index.js +1 -2
  51. package/dist/core/structured/index.js.map +1 -1
  52. package/dist/core/tools/index.d.ts +2 -1
  53. package/dist/core/tools/index.d.ts.map +1 -1
  54. package/dist/core/tools/index.js +2 -1
  55. package/dist/core/tools/index.js.map +1 -1
  56. package/dist/discovery/index.d.ts +2 -1
  57. package/dist/discovery/index.d.ts.map +1 -1
  58. package/dist/discovery/index.js +2 -1
  59. package/dist/discovery/index.js.map +1 -1
  60. package/dist/memory/index.d.ts +2 -1
  61. package/dist/memory/index.d.ts.map +1 -1
  62. package/dist/memory/index.js +2 -1
  63. package/dist/memory/index.js.map +1 -1
  64. package/dist/rag/audit/index.d.ts +5 -2
  65. package/dist/rag/audit/index.d.ts.map +1 -1
  66. package/dist/rag/audit/index.js +5 -2
  67. package/dist/rag/audit/index.js.map +1 -1
  68. package/dist/rag/implementations/vector_stores/InMemoryVectorStore.d.ts +1 -2
  69. package/dist/rag/implementations/vector_stores/InMemoryVectorStore.d.ts.map +1 -1
  70. package/dist/rag/implementations/vector_stores/InMemoryVectorStore.js +1 -2
  71. package/dist/rag/implementations/vector_stores/InMemoryVectorStore.js.map +1 -1
  72. package/dist/rag/reranking/index.d.ts +2 -2
  73. package/dist/rag/reranking/index.js +2 -2
  74. package/dist/rag/reranking/providers/index.d.ts +3 -2
  75. package/dist/rag/reranking/providers/index.d.ts.map +1 -1
  76. package/dist/rag/reranking/providers/index.js +3 -2
  77. package/dist/rag/reranking/providers/index.js.map +1 -1
  78. package/dist/social-posting/ContentAdaptationEngine.d.ts +148 -0
  79. package/dist/social-posting/ContentAdaptationEngine.d.ts.map +1 -0
  80. package/dist/social-posting/ContentAdaptationEngine.js +445 -0
  81. package/dist/social-posting/ContentAdaptationEngine.js.map +1 -0
  82. package/dist/social-posting/SocialAbstractService.d.ts +52 -0
  83. package/dist/social-posting/SocialAbstractService.d.ts.map +1 -0
  84. package/dist/social-posting/SocialAbstractService.js +127 -0
  85. package/dist/social-posting/SocialAbstractService.js.map +1 -0
  86. package/dist/social-posting/SocialPostManager.d.ts +252 -0
  87. package/dist/social-posting/SocialPostManager.d.ts.map +1 -0
  88. package/dist/social-posting/SocialPostManager.js +344 -0
  89. package/dist/social-posting/SocialPostManager.js.map +1 -0
  90. package/dist/social-posting/index.d.ts +12 -0
  91. package/dist/social-posting/index.d.ts.map +1 -0
  92. package/dist/social-posting/index.js +15 -0
  93. package/dist/social-posting/index.js.map +1 -0
  94. package/dist/voice/index.d.ts +2 -1
  95. package/dist/voice/index.d.ts.map +1 -1
  96. package/dist/voice/index.js +2 -1
  97. package/dist/voice/index.js.map +1 -1
  98. package/package.json +6 -3
@@ -1,6 +1,7 @@
1
1
  /**
2
- * @fileoverview Reranker provider implementations.
3
- * @module backend/agentos/rag/reranking/providers
2
+ * Reranker provider implementations.
3
+ *
4
+ * @module @framers/agentos/rag/reranking/providers
4
5
  */
5
6
  export { CohereReranker, type CohereRerankerConfig, COHERE_RERANKER_MODELS, type CohereRerankerModel } from './CohereReranker';
6
7
  export { LocalCrossEncoderReranker, type LocalCrossEncoderConfig, LOCAL_RERANKER_MODELS, type LocalRerankerModel } from './LocalCrossEncoderReranker';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/rag/reranking/providers/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,sBAAsB,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC/H,OAAO,EAAE,yBAAyB,EAAE,KAAK,uBAAuB,EAAE,qBAAqB,EAAE,KAAK,kBAAkB,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/rag/reranking/providers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,sBAAsB,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC/H,OAAO,EAAE,yBAAyB,EAAE,KAAK,uBAAuB,EAAE,qBAAqB,EAAE,KAAK,kBAAkB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -1,6 +1,7 @@
1
1
  /**
2
- * @fileoverview Reranker provider implementations.
3
- * @module backend/agentos/rag/reranking/providers
2
+ * Reranker provider implementations.
3
+ *
4
+ * @module @framers/agentos/rag/reranking/providers
4
5
  */
5
6
  export { CohereReranker, COHERE_RERANKER_MODELS } from './CohereReranker.js';
6
7
  export { LocalCrossEncoderReranker, LOCAL_RERANKER_MODELS } from './LocalCrossEncoderReranker.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/rag/reranking/providers/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAA6B,sBAAsB,EAA4B,MAAM,kBAAkB,CAAC;AAC/H,OAAO,EAAE,yBAAyB,EAAgC,qBAAqB,EAA2B,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/rag/reranking/providers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAA6B,sBAAsB,EAA4B,MAAM,kBAAkB,CAAC;AAC/H,OAAO,EAAE,yBAAyB,EAAgC,qBAAqB,EAA2B,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * @fileoverview Content Adaptation Engine — platform-specific content transformation.
3
+ * @module @framers/agentos/social-posting/ContentAdaptationEngine
4
+ *
5
+ * Applies static, deterministic rules to adapt a base content string for
6
+ * each target social media platform. The engine enforces character limits,
7
+ * hashtag placement, and generates platform-specific warnings.
8
+ *
9
+ * LLM-powered adaptation (tone rewriting, audience targeting, etc.) is
10
+ * intentionally left to the skill layer. This module provides the
11
+ * constraint-aware foundation that skills can build upon.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { ContentAdaptationEngine } from '../social-posting';
16
+ *
17
+ * const engine = new ContentAdaptationEngine();
18
+ *
19
+ * const adapted = engine.adaptContent(
20
+ * 'Announcing our new feature! Check it out at https://example.com',
21
+ * ['twitter', 'linkedin', 'instagram'],
22
+ * ['announcement', 'product'],
23
+ * );
24
+ *
25
+ * console.log(adapted.twitter.text); // Truncated to 280 chars if needed
26
+ * console.log(adapted.instagram.hashtags); // ['#announcement', '#product']
27
+ * ```
28
+ */
29
+ /**
30
+ * Content constraints and capabilities for a social media platform.
31
+ */
32
+ export interface PlatformConstraints {
33
+ /** Maximum character length for a post. */
34
+ maxLength: number;
35
+ /** How hashtags should be positioned in the content. */
36
+ hashtagStyle: 'inline' | 'footer' | 'none';
37
+ /** Maximum number of hashtags allowed. */
38
+ maxHashtags: number;
39
+ /** Whether the platform supports image/photo attachments. */
40
+ supportsMedia: boolean;
41
+ /** Whether the platform supports video attachments. */
42
+ supportsVideo: boolean;
43
+ /** Whether the platform supports multi-image carousel posts. */
44
+ supportsCarousel: boolean;
45
+ /** Whether the platform supports poll creation. */
46
+ supportsPoll: boolean;
47
+ /** Whether the platform supports threaded/chained posts. */
48
+ supportsThreading: boolean;
49
+ /** Brief guidance on the expected tone for this platform. */
50
+ toneGuidance: string;
51
+ }
52
+ /**
53
+ * The result of adapting content for a single platform.
54
+ */
55
+ export interface AdaptedContent {
56
+ /** Target platform identifier. */
57
+ platform: string;
58
+ /** The adapted text content, truncated and formatted for the platform. */
59
+ text: string;
60
+ /** Extracted or generated hashtags (with '#' prefix). */
61
+ hashtags: string[];
62
+ /** Whether the text was truncated to fit the platform's maxLength. */
63
+ truncated: boolean;
64
+ /** Whether the platform supports media attachments. */
65
+ mediaSupported: boolean;
66
+ /** Platform-specific warnings (e.g. content too long, unsupported features). */
67
+ warnings: string[];
68
+ }
69
+ /**
70
+ * Adapts base content for multiple social media platforms using static rules.
71
+ *
72
+ * The engine applies character limits, hashtag formatting, and generates
73
+ * warnings when content exceeds platform constraints. It does **not** perform
74
+ * LLM-based rewriting — that responsibility belongs to the skill layer which
75
+ * can call the engine's constraint methods to inform its prompts.
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const engine = new ContentAdaptationEngine();
80
+ * const results = engine.adaptContent(
81
+ * 'We just shipped dark mode! Try it out.',
82
+ * ['twitter', 'linkedin'],
83
+ * ['darkmode', 'shipping'],
84
+ * );
85
+ *
86
+ * // results.twitter.text --> 'We just shipped dark mode! Try it out. #darkmode #shipping'
87
+ * // results.linkedin.text --> 'We just shipped dark mode! Try it out.\n\n#darkmode #shipping'
88
+ * ```
89
+ */
90
+ export declare class ContentAdaptationEngine {
91
+ /**
92
+ * Adapt base content for one or more target platforms.
93
+ *
94
+ * For each platform, the engine:
95
+ * 1. Formats hashtags according to the platform's hashtagStyle
96
+ * 2. Truncates content if it exceeds the platform's maxLength
97
+ * 3. Generates warnings for any constraint violations
98
+ *
99
+ * @param baseContent - The original, platform-agnostic content
100
+ * @param platforms - Target platform identifiers
101
+ * @param hashtags - Optional hashtags (without '#' prefix)
102
+ * @returns A record mapping each platform to its adapted content
103
+ */
104
+ adaptContent(baseContent: string, platforms: string[], hashtags?: string[]): Record<string, AdaptedContent>;
105
+ /**
106
+ * Retrieve the constraint definition for a platform.
107
+ *
108
+ * Returns a default constraint set for unknown platforms (10000 chars,
109
+ * no hashtags, basic media support).
110
+ *
111
+ * @param platform - Platform identifier
112
+ * @returns The PlatformConstraints for the given platform
113
+ */
114
+ getConstraints(platform: string): PlatformConstraints;
115
+ /**
116
+ * Truncate text to a maximum length, appending an ellipsis if truncated.
117
+ *
118
+ * Attempts to break at a word boundary to avoid cutting words mid-token.
119
+ * If no word boundary is found within the last 30 characters, truncates
120
+ * at the hard limit.
121
+ *
122
+ * @param text - The text to truncate
123
+ * @param maxLength - Maximum allowed length (including ellipsis)
124
+ * @returns The truncated text, or the original if within limits
125
+ */
126
+ truncateWithEllipsis(text: string, maxLength: number): string;
127
+ /**
128
+ * Adapt content for a single platform.
129
+ */
130
+ private adaptForPlatform;
131
+ /**
132
+ * Normalize hashtags: ensure '#' prefix, deduplicate, and limit count.
133
+ */
134
+ private normalizeHashtags;
135
+ /**
136
+ * Format content with hashtags according to the platform's style.
137
+ */
138
+ private formatWithHashtags;
139
+ /**
140
+ * Build a hashtag block string for footer-style placement.
141
+ */
142
+ private buildHashtagBlock;
143
+ /**
144
+ * Default constraints for unknown platforms.
145
+ */
146
+ private getDefaultConstraints;
147
+ }
148
+ //# sourceMappingURL=ContentAdaptationEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContentAdaptationEngine.d.ts","sourceRoot":"","sources":["../../src/social-posting/ContentAdaptationEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAMH;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,YAAY,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC3C,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,aAAa,EAAE,OAAO,CAAC;IACvB,uDAAuD;IACvD,aAAa,EAAE,OAAO,CAAC;IACvB,gEAAgE;IAChE,gBAAgB,EAAE,OAAO,CAAC;IAC1B,mDAAmD;IACnD,YAAY,EAAE,OAAO,CAAC;IACtB,4DAA4D;IAC5D,iBAAiB,EAAE,OAAO,CAAC;IAC3B,6DAA6D;IAC7D,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,sEAAsE;IACtE,SAAS,EAAE,OAAO,CAAC;IACnB,uDAAuD;IACvD,cAAc,EAAE,OAAO,CAAC;IACxB,gFAAgF;IAChF,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAgOD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,uBAAuB;IAKlC;;;;;;;;;;;;OAYG;IACH,YAAY,CACV,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EAAE,EACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,GAClB,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC;IAUjC;;;;;;;;OAQG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,mBAAmB;IAIrD;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;IA4B7D;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAoFxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAsBzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAkB1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACH,OAAO,CAAC,qBAAqB;CAa9B"}
@@ -0,0 +1,445 @@
1
+ /**
2
+ * @fileoverview Content Adaptation Engine — platform-specific content transformation.
3
+ * @module @framers/agentos/social-posting/ContentAdaptationEngine
4
+ *
5
+ * Applies static, deterministic rules to adapt a base content string for
6
+ * each target social media platform. The engine enforces character limits,
7
+ * hashtag placement, and generates platform-specific warnings.
8
+ *
9
+ * LLM-powered adaptation (tone rewriting, audience targeting, etc.) is
10
+ * intentionally left to the skill layer. This module provides the
11
+ * constraint-aware foundation that skills can build upon.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { ContentAdaptationEngine } from '../social-posting/index.js';
16
+ *
17
+ * const engine = new ContentAdaptationEngine();
18
+ *
19
+ * const adapted = engine.adaptContent(
20
+ * 'Announcing our new feature! Check it out at https://example.com',
21
+ * ['twitter', 'linkedin', 'instagram'],
22
+ * ['announcement', 'product'],
23
+ * );
24
+ *
25
+ * console.log(adapted.twitter.text); // Truncated to 280 chars if needed
26
+ * console.log(adapted.instagram.hashtags); // ['#announcement', '#product']
27
+ * ```
28
+ */
29
+ // ============================================================================
30
+ // Platform Constraints Registry
31
+ // ============================================================================
32
+ /**
33
+ * Static constraint definitions for all supported social media platforms.
34
+ *
35
+ * Platforms are grouped by category:
36
+ * - Short-form: twitter, threads, bluesky, mastodon, farcaster
37
+ * - Visual-first: instagram, tiktok, pinterest, youtube
38
+ * - Professional/general: linkedin, facebook, reddit, lemmy
39
+ * - Long-form blogging: devto, hashnode, medium, wordpress
40
+ */
41
+ const PLATFORM_CONSTRAINTS = {
42
+ // --------------------------------------------------------------------------
43
+ // Short-form Micro-blogging
44
+ // --------------------------------------------------------------------------
45
+ twitter: {
46
+ maxLength: 280,
47
+ hashtagStyle: 'inline',
48
+ maxHashtags: 5,
49
+ supportsMedia: true,
50
+ supportsVideo: true,
51
+ supportsCarousel: false,
52
+ supportsPoll: true,
53
+ supportsThreading: true,
54
+ toneGuidance: 'Concise, punchy, conversational. Use threads for longer content.',
55
+ },
56
+ threads: {
57
+ maxLength: 500,
58
+ hashtagStyle: 'inline',
59
+ maxHashtags: 5,
60
+ supportsMedia: true,
61
+ supportsVideo: true,
62
+ supportsCarousel: true,
63
+ supportsPoll: false,
64
+ supportsThreading: true,
65
+ toneGuidance: 'Conversational, casual, community-oriented.',
66
+ },
67
+ bluesky: {
68
+ maxLength: 300,
69
+ hashtagStyle: 'none',
70
+ maxHashtags: 0,
71
+ supportsMedia: true,
72
+ supportsVideo: true,
73
+ supportsCarousel: false,
74
+ supportsPoll: false,
75
+ supportsThreading: true,
76
+ toneGuidance: 'Authentic, concise. Hashtags use facets (rich text), not inline text.',
77
+ },
78
+ mastodon: {
79
+ maxLength: 500,
80
+ hashtagStyle: 'inline',
81
+ maxHashtags: 10,
82
+ supportsMedia: true,
83
+ supportsVideo: true,
84
+ supportsCarousel: false,
85
+ supportsPoll: true,
86
+ supportsThreading: true,
87
+ toneGuidance: 'Community-conscious, CW (content warning) support encouraged.',
88
+ },
89
+ farcaster: {
90
+ maxLength: 320,
91
+ hashtagStyle: 'none',
92
+ maxHashtags: 0,
93
+ supportsMedia: true,
94
+ supportsVideo: false,
95
+ supportsCarousel: false,
96
+ supportsPoll: false,
97
+ supportsThreading: true,
98
+ toneGuidance: 'Crypto/web3 native, concise, authentic.',
99
+ },
100
+ // --------------------------------------------------------------------------
101
+ // Visual-First Platforms
102
+ // --------------------------------------------------------------------------
103
+ instagram: {
104
+ maxLength: 2200,
105
+ hashtagStyle: 'footer',
106
+ maxHashtags: 30,
107
+ supportsMedia: true,
108
+ supportsVideo: true,
109
+ supportsCarousel: true,
110
+ supportsPoll: false,
111
+ supportsThreading: false,
112
+ toneGuidance: 'Visual-first, storytelling, hashtags in footer block.',
113
+ },
114
+ tiktok: {
115
+ maxLength: 2200,
116
+ hashtagStyle: 'inline',
117
+ maxHashtags: 10,
118
+ supportsMedia: false,
119
+ supportsVideo: true,
120
+ supportsCarousel: false,
121
+ supportsPoll: false,
122
+ supportsThreading: false,
123
+ toneGuidance: 'Trendy, authentic, short-form video focused.',
124
+ },
125
+ pinterest: {
126
+ maxLength: 500,
127
+ hashtagStyle: 'none',
128
+ maxHashtags: 0,
129
+ supportsMedia: true,
130
+ supportsVideo: true,
131
+ supportsCarousel: true,
132
+ supportsPoll: false,
133
+ supportsThreading: false,
134
+ toneGuidance: 'Keyword-rich, descriptive, aspirational. Focus on discoverability.',
135
+ },
136
+ youtube: {
137
+ maxLength: 5000,
138
+ hashtagStyle: 'inline',
139
+ maxHashtags: 15,
140
+ supportsMedia: false,
141
+ supportsVideo: true,
142
+ supportsCarousel: false,
143
+ supportsPoll: true,
144
+ supportsThreading: false,
145
+ toneGuidance: 'Descriptive, SEO-aware. This is the video description field.',
146
+ },
147
+ // --------------------------------------------------------------------------
148
+ // Professional & General Social
149
+ // --------------------------------------------------------------------------
150
+ linkedin: {
151
+ maxLength: 3000,
152
+ hashtagStyle: 'footer',
153
+ maxHashtags: 5,
154
+ supportsMedia: true,
155
+ supportsVideo: true,
156
+ supportsCarousel: true,
157
+ supportsPoll: true,
158
+ supportsThreading: false,
159
+ toneGuidance: 'Professional, thought-leadership, industry insights.',
160
+ },
161
+ facebook: {
162
+ maxLength: 63206,
163
+ hashtagStyle: 'inline',
164
+ maxHashtags: 10,
165
+ supportsMedia: true,
166
+ supportsVideo: true,
167
+ supportsCarousel: true,
168
+ supportsPoll: true,
169
+ supportsThreading: false,
170
+ toneGuidance: 'Casual, community-driven, longer-form acceptable.',
171
+ },
172
+ reddit: {
173
+ maxLength: 40000,
174
+ hashtagStyle: 'none',
175
+ maxHashtags: 0,
176
+ supportsMedia: true,
177
+ supportsVideo: true,
178
+ supportsCarousel: false,
179
+ supportsPoll: true,
180
+ supportsThreading: false,
181
+ toneGuidance: 'Community-specific, informative, no hashtags. Markdown supported.',
182
+ },
183
+ lemmy: {
184
+ maxLength: 10000,
185
+ hashtagStyle: 'none',
186
+ maxHashtags: 0,
187
+ supportsMedia: true,
188
+ supportsVideo: false,
189
+ supportsCarousel: false,
190
+ supportsPoll: false,
191
+ supportsThreading: false,
192
+ toneGuidance: 'Community-focused, federated. Markdown supported.',
193
+ },
194
+ // --------------------------------------------------------------------------
195
+ // Long-Form Blogging
196
+ // --------------------------------------------------------------------------
197
+ devto: {
198
+ maxLength: 100000,
199
+ hashtagStyle: 'none',
200
+ maxHashtags: 0,
201
+ supportsMedia: true,
202
+ supportsVideo: false,
203
+ supportsCarousel: false,
204
+ supportsPoll: false,
205
+ supportsThreading: false,
206
+ toneGuidance: 'Developer-focused, technical, tutorial-style. Markdown/front-matter.',
207
+ },
208
+ hashnode: {
209
+ maxLength: 100000,
210
+ hashtagStyle: 'none',
211
+ maxHashtags: 0,
212
+ supportsMedia: true,
213
+ supportsVideo: false,
214
+ supportsCarousel: false,
215
+ supportsPoll: false,
216
+ supportsThreading: false,
217
+ toneGuidance: 'Developer blogging, technical depth, markdown.',
218
+ },
219
+ medium: {
220
+ maxLength: 100000,
221
+ hashtagStyle: 'none',
222
+ maxHashtags: 0,
223
+ supportsMedia: true,
224
+ supportsVideo: false,
225
+ supportsCarousel: false,
226
+ supportsPoll: false,
227
+ supportsThreading: false,
228
+ toneGuidance: 'Narrative, polished, long-form essays and thought pieces.',
229
+ },
230
+ wordpress: {
231
+ maxLength: 100000,
232
+ hashtagStyle: 'none',
233
+ maxHashtags: 0,
234
+ supportsMedia: true,
235
+ supportsVideo: true,
236
+ supportsCarousel: false,
237
+ supportsPoll: false,
238
+ supportsThreading: false,
239
+ toneGuidance: 'Flexible — depends on blog style. HTML and shortcodes supported.',
240
+ },
241
+ };
242
+ // ============================================================================
243
+ // ContentAdaptationEngine
244
+ // ============================================================================
245
+ /**
246
+ * Adapts base content for multiple social media platforms using static rules.
247
+ *
248
+ * The engine applies character limits, hashtag formatting, and generates
249
+ * warnings when content exceeds platform constraints. It does **not** perform
250
+ * LLM-based rewriting — that responsibility belongs to the skill layer which
251
+ * can call the engine's constraint methods to inform its prompts.
252
+ *
253
+ * @example
254
+ * ```typescript
255
+ * const engine = new ContentAdaptationEngine();
256
+ * const results = engine.adaptContent(
257
+ * 'We just shipped dark mode! Try it out.',
258
+ * ['twitter', 'linkedin'],
259
+ * ['darkmode', 'shipping'],
260
+ * );
261
+ *
262
+ * // results.twitter.text --> 'We just shipped dark mode! Try it out. #darkmode #shipping'
263
+ * // results.linkedin.text --> 'We just shipped dark mode! Try it out.\n\n#darkmode #shipping'
264
+ * ```
265
+ */
266
+ export class ContentAdaptationEngine {
267
+ // --------------------------------------------------------------------------
268
+ // Public API
269
+ // --------------------------------------------------------------------------
270
+ /**
271
+ * Adapt base content for one or more target platforms.
272
+ *
273
+ * For each platform, the engine:
274
+ * 1. Formats hashtags according to the platform's hashtagStyle
275
+ * 2. Truncates content if it exceeds the platform's maxLength
276
+ * 3. Generates warnings for any constraint violations
277
+ *
278
+ * @param baseContent - The original, platform-agnostic content
279
+ * @param platforms - Target platform identifiers
280
+ * @param hashtags - Optional hashtags (without '#' prefix)
281
+ * @returns A record mapping each platform to its adapted content
282
+ */
283
+ adaptContent(baseContent, platforms, hashtags) {
284
+ const results = {};
285
+ for (const platform of platforms) {
286
+ results[platform] = this.adaptForPlatform(baseContent, platform, hashtags);
287
+ }
288
+ return results;
289
+ }
290
+ /**
291
+ * Retrieve the constraint definition for a platform.
292
+ *
293
+ * Returns a default constraint set for unknown platforms (10000 chars,
294
+ * no hashtags, basic media support).
295
+ *
296
+ * @param platform - Platform identifier
297
+ * @returns The PlatformConstraints for the given platform
298
+ */
299
+ getConstraints(platform) {
300
+ return PLATFORM_CONSTRAINTS[platform] ?? this.getDefaultConstraints();
301
+ }
302
+ /**
303
+ * Truncate text to a maximum length, appending an ellipsis if truncated.
304
+ *
305
+ * Attempts to break at a word boundary to avoid cutting words mid-token.
306
+ * If no word boundary is found within the last 30 characters, truncates
307
+ * at the hard limit.
308
+ *
309
+ * @param text - The text to truncate
310
+ * @param maxLength - Maximum allowed length (including ellipsis)
311
+ * @returns The truncated text, or the original if within limits
312
+ */
313
+ truncateWithEllipsis(text, maxLength) {
314
+ if (text.length <= maxLength) {
315
+ return text;
316
+ }
317
+ const ellipsis = '...';
318
+ const targetLength = maxLength - ellipsis.length;
319
+ if (targetLength <= 0) {
320
+ return text.slice(0, maxLength);
321
+ }
322
+ // Try to break at a word boundary
323
+ const truncated = text.slice(0, targetLength);
324
+ const lastSpace = truncated.lastIndexOf(' ');
325
+ // Only break at word boundary if it's within 30 chars of the target
326
+ if (lastSpace > 0 && targetLength - lastSpace < 30) {
327
+ return truncated.slice(0, lastSpace) + ellipsis;
328
+ }
329
+ return truncated + ellipsis;
330
+ }
331
+ // --------------------------------------------------------------------------
332
+ // Internal Helpers
333
+ // --------------------------------------------------------------------------
334
+ /**
335
+ * Adapt content for a single platform.
336
+ */
337
+ adaptForPlatform(baseContent, platform, hashtags) {
338
+ const constraints = this.getConstraints(platform);
339
+ const warnings = [];
340
+ // Normalize and limit hashtags
341
+ const normalizedHashtags = this.normalizeHashtags(hashtags ?? [], constraints.maxHashtags);
342
+ if (hashtags && hashtags.length > constraints.maxHashtags) {
343
+ warnings.push(`Hashtag count (${hashtags.length}) exceeds platform maximum (${constraints.maxHashtags}). ` +
344
+ `Truncated to ${constraints.maxHashtags}.`);
345
+ }
346
+ // Build the full text with hashtags placed according to platform style
347
+ let fullText = this.formatWithHashtags(baseContent, normalizedHashtags, constraints.hashtagStyle);
348
+ // Check for truncation
349
+ let truncated = false;
350
+ if (fullText.length > constraints.maxLength) {
351
+ // If hashtags are in footer, try truncating just the content
352
+ if (constraints.hashtagStyle === 'footer' &&
353
+ normalizedHashtags.length > 0) {
354
+ const hashtagBlock = this.buildHashtagBlock(normalizedHashtags);
355
+ const contentBudget = constraints.maxLength - hashtagBlock.length - 2; // 2 for '\n\n'
356
+ if (contentBudget > 0) {
357
+ const truncatedContent = this.truncateWithEllipsis(baseContent, contentBudget);
358
+ fullText = truncatedContent + '\n\n' + hashtagBlock;
359
+ truncated = true;
360
+ }
361
+ else {
362
+ fullText = this.truncateWithEllipsis(fullText, constraints.maxLength);
363
+ truncated = true;
364
+ }
365
+ }
366
+ else {
367
+ fullText = this.truncateWithEllipsis(fullText, constraints.maxLength);
368
+ truncated = true;
369
+ }
370
+ warnings.push(`Content truncated from ${baseContent.length} to fit ${platform}'s ` +
371
+ `${constraints.maxLength} character limit.`);
372
+ }
373
+ // Platform-specific warnings
374
+ if (platform === 'bluesky' && hashtags && hashtags.length > 0) {
375
+ warnings.push('Bluesky uses facets (rich text) for hashtags, not inline text. ' +
376
+ 'Hashtags have been omitted from the text. Apply them via the AT Protocol facets API.');
377
+ }
378
+ if (platform === 'mastodon') {
379
+ warnings.push('Consider adding a Content Warning (CW) if the content is sensitive.');
380
+ }
381
+ return {
382
+ platform,
383
+ text: fullText,
384
+ hashtags: normalizedHashtags,
385
+ truncated,
386
+ mediaSupported: constraints.supportsMedia,
387
+ warnings,
388
+ };
389
+ }
390
+ /**
391
+ * Normalize hashtags: ensure '#' prefix, deduplicate, and limit count.
392
+ */
393
+ normalizeHashtags(hashtags, maxCount) {
394
+ if (maxCount === 0)
395
+ return [];
396
+ const seen = new Set();
397
+ const normalized = [];
398
+ for (const tag of hashtags) {
399
+ const cleaned = tag.startsWith('#') ? tag : `#${tag}`;
400
+ const lower = cleaned.toLowerCase();
401
+ if (!seen.has(lower) && normalized.length < maxCount) {
402
+ seen.add(lower);
403
+ normalized.push(cleaned);
404
+ }
405
+ }
406
+ return normalized;
407
+ }
408
+ /**
409
+ * Format content with hashtags according to the platform's style.
410
+ */
411
+ formatWithHashtags(content, hashtags, style) {
412
+ if (hashtags.length === 0 || style === 'none') {
413
+ return content;
414
+ }
415
+ if (style === 'footer') {
416
+ const hashtagBlock = this.buildHashtagBlock(hashtags);
417
+ return content + '\n\n' + hashtagBlock;
418
+ }
419
+ // Inline: append hashtags after the content with a space
420
+ return content + ' ' + hashtags.join(' ');
421
+ }
422
+ /**
423
+ * Build a hashtag block string for footer-style placement.
424
+ */
425
+ buildHashtagBlock(hashtags) {
426
+ return hashtags.join(' ');
427
+ }
428
+ /**
429
+ * Default constraints for unknown platforms.
430
+ */
431
+ getDefaultConstraints() {
432
+ return {
433
+ maxLength: 10000,
434
+ hashtagStyle: 'inline',
435
+ maxHashtags: 10,
436
+ supportsMedia: true,
437
+ supportsVideo: true,
438
+ supportsCarousel: false,
439
+ supportsPoll: false,
440
+ supportsThreading: false,
441
+ toneGuidance: 'General purpose. Adapt to the specific platform context.',
442
+ };
443
+ }
444
+ }
445
+ //# sourceMappingURL=ContentAdaptationEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContentAdaptationEngine.js","sourceRoot":"","sources":["../../src/social-posting/ContentAdaptationEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAgDH,+EAA+E;AAC/E,gCAAgC;AAChC,+EAA+E;AAE/E;;;;;;;;GAQG;AACH,MAAM,oBAAoB,GAAwC;IAChE,6EAA6E;IAC7E,4BAA4B;IAC5B,6EAA6E;IAC7E,OAAO,EAAE;QACP,SAAS,EAAE,GAAG;QACd,YAAY,EAAE,QAAQ;QACtB,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,KAAK;QACvB,YAAY,EAAE,IAAI;QAClB,iBAAiB,EAAE,IAAI;QACvB,YAAY,EAAE,kEAAkE;KACjF;IACD,OAAO,EAAE;QACP,SAAS,EAAE,GAAG;QACd,YAAY,EAAE,QAAQ;QACtB,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,IAAI;QACtB,YAAY,EAAE,KAAK;QACnB,iBAAiB,EAAE,IAAI;QACvB,YAAY,EAAE,6CAA6C;KAC5D;IACD,OAAO,EAAE;QACP,SAAS,EAAE,GAAG;QACd,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,KAAK;QACvB,YAAY,EAAE,KAAK;QACnB,iBAAiB,EAAE,IAAI;QACvB,YAAY,EAAE,uEAAuE;KACtF;IACD,QAAQ,EAAE;QACR,SAAS,EAAE,GAAG;QACd,YAAY,EAAE,QAAQ;QACtB,WAAW,EAAE,EAAE;QACf,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,KAAK;QACvB,YAAY,EAAE,IAAI;QAClB,iBAAiB,EAAE,IAAI;QACvB,YAAY,EAAE,+DAA+D;KAC9E;IACD,SAAS,EAAE;QACT,SAAS,EAAE,GAAG;QACd,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,KAAK;QACpB,gBAAgB,EAAE,KAAK;QACvB,YAAY,EAAE,KAAK;QACnB,iBAAiB,EAAE,IAAI;QACvB,YAAY,EAAE,yCAAyC;KACxD;IAED,6EAA6E;IAC7E,yBAAyB;IACzB,6EAA6E;IAC7E,SAAS,EAAE;QACT,SAAS,EAAE,IAAI;QACf,YAAY,EAAE,QAAQ;QACtB,WAAW,EAAE,EAAE;QACf,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,IAAI;QACtB,YAAY,EAAE,KAAK;QACnB,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,uDAAuD;KACtE;IACD,MAAM,EAAE;QACN,SAAS,EAAE,IAAI;QACf,YAAY,EAAE,QAAQ;QACtB,WAAW,EAAE,EAAE;QACf,aAAa,EAAE,KAAK;QACpB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,KAAK;QACvB,YAAY,EAAE,KAAK;QACnB,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,8CAA8C;KAC7D;IACD,SAAS,EAAE;QACT,SAAS,EAAE,GAAG;QACd,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,IAAI;QACtB,YAAY,EAAE,KAAK;QACnB,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,oEAAoE;KACnF;IACD,OAAO,EAAE;QACP,SAAS,EAAE,IAAI;QACf,YAAY,EAAE,QAAQ;QACtB,WAAW,EAAE,EAAE;QACf,aAAa,EAAE,KAAK;QACpB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,KAAK;QACvB,YAAY,EAAE,IAAI;QAClB,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,8DAA8D;KAC7E;IAED,6EAA6E;IAC7E,gCAAgC;IAChC,6EAA6E;IAC7E,QAAQ,EAAE;QACR,SAAS,EAAE,IAAI;QACf,YAAY,EAAE,QAAQ;QACtB,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,IAAI;QACtB,YAAY,EAAE,IAAI;QAClB,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,sDAAsD;KACrE;IACD,QAAQ,EAAE;QACR,SAAS,EAAE,KAAK;QAChB,YAAY,EAAE,QAAQ;QACtB,WAAW,EAAE,EAAE;QACf,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,IAAI;QACtB,YAAY,EAAE,IAAI;QAClB,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,mDAAmD;KAClE;IACD,MAAM,EAAE;QACN,SAAS,EAAE,KAAK;QAChB,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,KAAK;QACvB,YAAY,EAAE,IAAI;QAClB,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,mEAAmE;KAClF;IACD,KAAK,EAAE;QACL,SAAS,EAAE,KAAK;QAChB,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,KAAK;QACpB,gBAAgB,EAAE,KAAK;QACvB,YAAY,EAAE,KAAK;QACnB,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,mDAAmD;KAClE;IAED,6EAA6E;IAC7E,qBAAqB;IACrB,6EAA6E;IAC7E,KAAK,EAAE;QACL,SAAS,EAAE,MAAM;QACjB,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,KAAK;QACpB,gBAAgB,EAAE,KAAK;QACvB,YAAY,EAAE,KAAK;QACnB,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,sEAAsE;KACrF;IACD,QAAQ,EAAE;QACR,SAAS,EAAE,MAAM;QACjB,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,KAAK;QACpB,gBAAgB,EAAE,KAAK;QACvB,YAAY,EAAE,KAAK;QACnB,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,gDAAgD;KAC/D;IACD,MAAM,EAAE;QACN,SAAS,EAAE,MAAM;QACjB,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,KAAK;QACpB,gBAAgB,EAAE,KAAK;QACvB,YAAY,EAAE,KAAK;QACnB,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,2DAA2D;KAC1E;IACD,SAAS,EAAE;QACT,SAAS,EAAE,MAAM;QACjB,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,IAAI;QACnB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,KAAK;QACvB,YAAY,EAAE,KAAK;QACnB,iBAAiB,EAAE,KAAK;QACxB,YAAY,EAAE,kEAAkE;KACjF;CACF,CAAC;AAEF,+EAA+E;AAC/E,0BAA0B;AAC1B,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAO,uBAAuB;IAClC,6EAA6E;IAC7E,aAAa;IACb,6EAA6E;IAE7E;;;;;;;;;;;;OAYG;IACH,YAAY,CACV,WAAmB,EACnB,SAAmB,EACnB,QAAmB;QAEnB,MAAM,OAAO,GAAmC,EAAE,CAAC;QAEnD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC7E,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;;;;OAQG;IACH,cAAc,CAAC,QAAgB;QAC7B,OAAO,oBAAoB,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;IACxE,CAAC;IAED;;;;;;;;;;OAUG;IACH,oBAAoB,CAAC,IAAY,EAAE,SAAiB;QAClD,IAAI,IAAI,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,QAAQ,GAAG,KAAK,CAAC;QACvB,MAAM,YAAY,GAAG,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC;QAEjD,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAClC,CAAC;QAED,kCAAkC;QAClC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;QAC9C,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAE7C,oEAAoE;QACpE,IAAI,SAAS,GAAG,CAAC,IAAI,YAAY,GAAG,SAAS,GAAG,EAAE,EAAE,CAAC;YACnD,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC;QAClD,CAAC;QAED,OAAO,SAAS,GAAG,QAAQ,CAAC;IAC9B,CAAC;IAED,6EAA6E;IAC7E,mBAAmB;IACnB,6EAA6E;IAE7E;;OAEG;IACK,gBAAgB,CACtB,WAAmB,EACnB,QAAgB,EAChB,QAAmB;QAEnB,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,+BAA+B;QAC/B,MAAM,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,CAC/C,QAAQ,IAAI,EAAE,EACd,WAAW,CAAC,WAAW,CACxB,CAAC;QAEF,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;YAC1D,QAAQ,CAAC,IAAI,CACX,kBAAkB,QAAQ,CAAC,MAAM,+BAA+B,WAAW,CAAC,WAAW,KAAK;gBAC1F,gBAAgB,WAAW,CAAC,WAAW,GAAG,CAC7C,CAAC;QACJ,CAAC;QAED,uEAAuE;QACvE,IAAI,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CACpC,WAAW,EACX,kBAAkB,EAClB,WAAW,CAAC,YAAY,CACzB,CAAC;QAEF,uBAAuB;QACvB,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,IAAI,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC,SAAS,EAAE,CAAC;YAC5C,6DAA6D;YAC7D,IACE,WAAW,CAAC,YAAY,KAAK,QAAQ;gBACrC,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAC7B,CAAC;gBACD,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;gBAChE,MAAM,aAAa,GAAG,WAAW,CAAC,SAAS,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,eAAe;gBACtF,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;oBACtB,MAAM,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,CAChD,WAAW,EACX,aAAa,CACd,CAAC;oBACF,QAAQ,GAAG,gBAAgB,GAAG,MAAM,GAAG,YAAY,CAAC;oBACpD,SAAS,GAAG,IAAI,CAAC;gBACnB,CAAC;qBAAM,CAAC;oBACN,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;oBACtE,SAAS,GAAG,IAAI,CAAC;gBACnB,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;gBACtE,SAAS,GAAG,IAAI,CAAC;YACnB,CAAC;YAED,QAAQ,CAAC,IAAI,CACX,0BAA0B,WAAW,CAAC,MAAM,WAAW,QAAQ,KAAK;gBAClE,GAAG,WAAW,CAAC,SAAS,mBAAmB,CAC9C,CAAC;QACJ,CAAC;QAED,6BAA6B;QAC7B,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9D,QAAQ,CAAC,IAAI,CACX,iEAAiE;gBAC/D,sFAAsF,CACzF,CAAC;QACJ,CAAC;QAED,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;YAC5B,QAAQ,CAAC,IAAI,CACX,qEAAqE,CACtE,CAAC;QACJ,CAAC;QAED,OAAO;YACL,QAAQ;YACR,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,kBAAkB;YAC5B,SAAS;YACT,cAAc,EAAE,WAAW,CAAC,aAAa;YACzC,QAAQ;SACT,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,iBAAiB,CACvB,QAAkB,EAClB,QAAgB;QAEhB,IAAI,QAAQ,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAE9B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,MAAM,UAAU,GAAa,EAAE,CAAC;QAEhC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;YACtD,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;YAEpC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;gBACrD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAChB,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;OAEG;IACK,kBAAkB,CACxB,OAAe,EACf,QAAkB,EAClB,KAAmC;QAEnC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YAC9C,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvB,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YACtD,OAAO,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC;QACzC,CAAC;QAED,yDAAyD;QACzD,OAAO,OAAO,GAAG,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,QAAkB;QAC1C,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED;;OAEG;IACK,qBAAqB;QAC3B,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,YAAY,EAAE,QAAQ;YACtB,WAAW,EAAE,EAAE;YACf,aAAa,EAAE,IAAI;YACnB,aAAa,EAAE,IAAI;YACnB,gBAAgB,EAAE,KAAK;YACvB,YAAY,EAAE,KAAK;YACnB,iBAAiB,EAAE,KAAK;YACxB,YAAY,EAAE,0DAA0D;SACzE,CAAC;IACJ,CAAC;CACF"}