tm-extractor 0.0.1

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 (34) hide show
  1. package/README.md +64 -0
  2. package/dist/constants/scm-activities.d.ts +35 -0
  3. package/dist/constants/scm-activities.d.ts.map +1 -0
  4. package/dist/constants/tma-formats.d.ts +77 -0
  5. package/dist/constants/tma-formats.d.ts.map +1 -0
  6. package/dist/constants/typology-definitions.d.ts +519 -0
  7. package/dist/constants/typology-definitions.d.ts.map +1 -0
  8. package/dist/core/data-transformer.d.ts +44 -0
  9. package/dist/core/data-transformer.d.ts.map +1 -0
  10. package/dist/core/pdf-processor.d.ts +48 -0
  11. package/dist/core/pdf-processor.d.ts.map +1 -0
  12. package/dist/extractors/branding-extractor.d.ts +21 -0
  13. package/dist/extractors/branding-extractor.d.ts.map +1 -0
  14. package/dist/extractors/scm-extractor.d.ts +96 -0
  15. package/dist/extractors/scm-extractor.d.ts.map +1 -0
  16. package/dist/extractors/strength-extractor.d.ts +21 -0
  17. package/dist/extractors/strength-extractor.d.ts.map +1 -0
  18. package/dist/extractors/talent-extractor.d.ts +25 -0
  19. package/dist/extractors/talent-extractor.d.ts.map +1 -0
  20. package/dist/extractors/typology-extractor.d.ts +25 -0
  21. package/dist/extractors/typology-extractor.d.ts.map +1 -0
  22. package/dist/index.cjs +1502 -0
  23. package/dist/index.cjs.map +1 -0
  24. package/dist/index.d.ts +37 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +1475 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/types/tma-types.d.ts +133 -0
  29. package/dist/types/tma-types.d.ts.map +1 -0
  30. package/dist/utils/error-handling.d.ts +46 -0
  31. package/dist/utils/error-handling.d.ts.map +1 -0
  32. package/dist/utils/format-detection.d.ts +48 -0
  33. package/dist/utils/format-detection.d.ts.map +1 -0
  34. package/package.json +67 -0
@@ -0,0 +1,44 @@
1
+ import { TalentData, Talent, CleanedTalent, CleanedTalentData, SinglePersonResult, TmaExtractorResult, ScmData, CleanedScmData } from '../types/tma-types';
2
+ /**
3
+ * Data transformation class that implements filteredExtractedData logic
4
+ * Removes unnecessary fields and metadata from extracted TMA data
5
+ */
6
+ export declare class DataTransformer {
7
+ /**
8
+ * Removes the 'sign' field from talents array
9
+ */
10
+ static removeTalentSign(talents: Talent[]): CleanedTalent[];
11
+ /**
12
+ * Removes SCM metadata while keeping activity data
13
+ * Filters out detectionConfidence and metadata according to filtered output spec
14
+ */
15
+ static removeScmMetadata(scmData: ScmData): CleanedScmData;
16
+ /**
17
+ * Cleans talent data by removing unnecessary fields
18
+ * Implements the filteredExtractedData logic from TMARawExtractor.vue
19
+ */
20
+ static cleanTalentData(rawData: TalentData): CleanedTalentData;
21
+ /**
22
+ * Transforms single person result to match filtered output format
23
+ */
24
+ static transformSinglePersonResult(result: SinglePersonResult): TmaExtractorResult;
25
+ /**
26
+ * Validates cleaned data structure
27
+ */
28
+ static validateCleanedData(data: CleanedTalentData): {
29
+ isValid: boolean;
30
+ errors: string[];
31
+ };
32
+ /**
33
+ * Gets summary statistics of cleaned data
34
+ */
35
+ static getDataSummary(data: CleanedTalentData): {
36
+ totalTalents: number;
37
+ totalStrengths: number;
38
+ totalTypologies: number;
39
+ totalPersonalBranding: number;
40
+ totalScmActivities: number | null;
41
+ hasScmData: boolean;
42
+ };
43
+ }
44
+ //# sourceMappingURL=data-transformer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-transformer.d.ts","sourceRoot":"","sources":["../../src/core/data-transformer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,MAAM,EACN,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,OAAO,EACP,cAAc,EACf,MAAM,oBAAoB,CAAC;AAE5B;;;GAGG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE;IAO3D;;;OAGG;IACH,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc;IAoB1D;;;OAGG;IACH,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,iBAAiB;IAiB9D;;OAEG;IACH,MAAM,CAAC,2BAA2B,CAAC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB;IASlF;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;IA2D3F;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,iBAAiB,GAAG;QAC9C,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;QACxB,qBAAqB,EAAE,MAAM,CAAC;QAC9B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;QAClC,UAAU,EAAE,OAAO,CAAC;KACrB;CAUF"}
@@ -0,0 +1,48 @@
1
+ import { TmaFormat, PageTexts, TmaExtractorConfig } from "../types/tma-types";
2
+ /**
3
+ * PDF Processing class that wraps PDF.js functionality for TMA extraction
4
+ */
5
+ export declare class PdfProcessor {
6
+ private workerSrc?;
7
+ constructor(config?: Partial<TmaExtractorConfig>);
8
+ /**
9
+ * Configures PDF.js worker source
10
+ */
11
+ private configurePdfWorker;
12
+ /**
13
+ * Gets the total number of pages in a PDF file
14
+ */
15
+ getPageCount(file: File): Promise<number>;
16
+ /**
17
+ * Detects TMA format based on page count
18
+ */
19
+ detectFormat(pageCount: number): TmaFormat;
20
+ /**
21
+ * Gets page numbers for extraction based on page count
22
+ */
23
+ getPageNumbers(pageCount: number): number[];
24
+ /**
25
+ * Gets SCM page number based on page count
26
+ */
27
+ getScmPageNumber(pageCount: number): number;
28
+ /**
29
+ * Extracts text content from a single PDF page
30
+ */
31
+ private getPageText;
32
+ /**
33
+ * Extracts text content from specific PDF pages
34
+ */
35
+ extractPageTexts(file: File, pageNumbers: number[]): Promise<PageTexts>;
36
+ /**
37
+ * Gets a specific PDF page for external processing (e.g., SCM)
38
+ */
39
+ getPage(file: File, pageNumber: number): Promise<any>;
40
+ /**
41
+ * Validates if a file is a valid PDF
42
+ */
43
+ validatePdfFile(file: File): {
44
+ isValid: boolean;
45
+ error?: string;
46
+ };
47
+ }
48
+ //# sourceMappingURL=pdf-processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-processor.d.ts","sourceRoot":"","sources":["../../src/core/pdf-processor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAK9E;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAC,CAAS;gBAEf,MAAM,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC;IAKhD;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAY1B;;OAEG;IACG,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;IAe/C;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS;IAI1C;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE;IAc3C;;OAEG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAc3C;;OAEG;YACW,WAAW;IAazB;;OAEG;IACG,gBAAgB,CACpB,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,SAAS,CAAC;IA6CrB;;OAEG;IACG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IA2B3D;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;CAoBlE"}
@@ -0,0 +1,21 @@
1
+ import { PersonalBranding } from '../types/tma-types';
2
+ /**
3
+ * Extracts personal branding data based on TMA format
4
+ */
5
+ export declare function extractPersonalBranding(text: string, pageCount?: number): PersonalBranding[];
6
+ /**
7
+ * Validates extracted personal branding data
8
+ */
9
+ export declare function validatePersonalBrandingData(branding: PersonalBranding[]): {
10
+ isValid: boolean;
11
+ errors: string[];
12
+ };
13
+ /**
14
+ * Normalizes personal branding IDs for consistency
15
+ */
16
+ export declare function normalizePersonalBrandingIds(branding: PersonalBranding[]): PersonalBranding[];
17
+ /**
18
+ * Filters personal branding to top N items
19
+ */
20
+ export declare function getTopPersonalBranding(branding: PersonalBranding[], count?: number): PersonalBranding[];
21
+ //# sourceMappingURL=branding-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branding-extractor.d.ts","sourceRoot":"","sources":["../../src/extractors/branding-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAqDtD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,MAAU,GAAG,gBAAgB,EAAE,CAQ/F;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,gBAAgB,EAAE,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CA2BjH;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAQ7F;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,EAAE,KAAK,GAAE,MAAgC,GAAG,gBAAgB,EAAE,CAKhI"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * SCM (Strength Cluster Map) Extractor
3
+ * Framework-independent extraction of 114 activities with PSP/PSS color detection
4
+ * Integrates PDF.js for rendering and Tesseract.js for OCR
5
+ */
6
+ import { type ScmColor, type ScmArea } from '../constants/scm-activities';
7
+ export interface ScmDetectedActivity {
8
+ activityName: string;
9
+ psp: ScmColor | null;
10
+ pss: ScmColor;
11
+ area: ScmArea;
12
+ position: number;
13
+ confidence: number;
14
+ }
15
+ export interface ScmMappedActivity {
16
+ id: string;
17
+ typology: string;
18
+ cluster: string;
19
+ psp: ScmColor | null;
20
+ pss: ScmColor;
21
+ detectionConfidence: number;
22
+ }
23
+ export interface ScmData {
24
+ activities: ScmMappedActivity[];
25
+ metadata: {
26
+ totalActivities: number;
27
+ detectedActivities: number;
28
+ unmappedActivities: string[];
29
+ averageConfidence: number;
30
+ extractionTime: number;
31
+ };
32
+ }
33
+ export declare class ScmExtractor {
34
+ private tesseractWorker;
35
+ /**
36
+ * Extract SCM data from a PDF page
37
+ */
38
+ extractScmData(pdfPage: any): Promise<ScmData | null>;
39
+ /**
40
+ * Detect if SCM page has ID below the name using PDF.js text extraction
41
+ */
42
+ private detectScmHasId;
43
+ /**
44
+ * Get area configurations based on whether ID is present
45
+ */
46
+ private getScmAreaConfigs;
47
+ /**
48
+ * Render PDF page to high-resolution canvas
49
+ */
50
+ private renderPageToCanvas;
51
+ /**
52
+ * Detect color at specific coordinates using Canvas API
53
+ */
54
+ private detectColorAt;
55
+ /**
56
+ * Map RGB values to SCM color using exact hex color matching
57
+ */
58
+ private mapRgbToScmColor;
59
+ /**
60
+ * Extract activities from a specific area using pre-defined positions
61
+ */
62
+ private extractAreaActivities;
63
+ /**
64
+ * Calculate activity coordinates based on area and position
65
+ */
66
+ private calculateActivityCoordinates;
67
+ /**
68
+ * Extract activity name using Tesseract OCR from canvas region
69
+ */
70
+ private extractActivityName;
71
+ /**
72
+ * Initialize Tesseract worker for OCR
73
+ */
74
+ private initializeTesseract;
75
+ /**
76
+ * Normalize activity name for matching
77
+ */
78
+ private normalizeActivityName;
79
+ /**
80
+ * Find best matching activity from pre-defined list
81
+ */
82
+ private findBestActivityMatch;
83
+ /**
84
+ * Calculate detection confidence score
85
+ */
86
+ private calculateDetectionConfidence;
87
+ /**
88
+ * Map detected activities to definitions
89
+ */
90
+ private mapDetectedToDefinitions;
91
+ /**
92
+ * Cleanup Tesseract worker
93
+ */
94
+ cleanup(): Promise<void>;
95
+ }
96
+ //# sourceMappingURL=scm-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scm-extractor.d.ts","sourceRoot":"","sources":["../../src/extractors/scm-extractor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAIL,KAAK,QAAQ,EACb,KAAK,OAAO,EACb,MAAM,6BAA6B,CAAC;AAGrC,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAC;IACrB,GAAG,EAAE,QAAQ,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAC;IACrB,GAAG,EAAE,QAAQ,CAAC;IACd,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,QAAQ,EAAE;QACR,eAAe,EAAE,MAAM,CAAC;QACxB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,kBAAkB,EAAE,MAAM,EAAE,CAAC;QAC7B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,eAAe,CAAa;IAEpC;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IA+D3D;;OAEG;YACW,cAAc;IA6B5B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAgDzB;;OAEG;YACW,kBAAkB;IAuBhC;;OAEG;IACH,OAAO,CAAC,aAAa;IA8BrB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAyCxB;;OAEG;YACW,qBAAqB;IAsDnC;;OAEG;IACH,OAAO,CAAC,4BAA4B;IA4EpC;;OAEG;YACW,mBAAmB;IA8EjC;;OAEG;YACW,mBAAmB;IAcjC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAS7B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAsB7B;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAoCpC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA8BhC;;OAEG;IACG,OAAO;CAMd"}
@@ -0,0 +1,21 @@
1
+ import { Strength } from '../types/tma-types';
2
+ /**
3
+ * Extracts strength data from text based on TMA format
4
+ */
5
+ export declare function extractStrength(text: string, pageCount?: number): Strength[];
6
+ /**
7
+ * Validates extracted strength data
8
+ */
9
+ export declare function validateStrengthData(strengths: Strength[]): {
10
+ isValid: boolean;
11
+ errors: string[];
12
+ };
13
+ /**
14
+ * Sorts strengths by their number in ascending order
15
+ */
16
+ export declare function sortStrengthsByNumber(strengths: Strength[]): Strength[];
17
+ /**
18
+ * Filters strengths to get top N strongest ones (lowest numbers)
19
+ */
20
+ export declare function getTopStrengths(strengths: Strength[], count?: number): Strength[];
21
+ //# sourceMappingURL=strength-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strength-extractor.d.ts","sourceRoot":"","sources":["../../src/extractors/strength-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAoC9C;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,MAAU,GAAG,QAAQ,EAAE,CAQ/E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CA4BlG;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAEvE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,KAAK,GAAE,MAAU,GAAG,QAAQ,EAAE,CAMpF"}
@@ -0,0 +1,25 @@
1
+ import { Talent } from '../types/tma-types';
2
+ /**
3
+ * Extracts talent order from text based on TMA format
4
+ */
5
+ export declare function extractTalentOrder(text: string, isPdfParse?: boolean, pageCount?: number): Talent[];
6
+ /**
7
+ * Extracts name from talent order text based on format
8
+ */
9
+ export declare function extractName(text: string, pageCount: number): string;
10
+ /**
11
+ * Validates extracted talent data
12
+ */
13
+ export declare function validateTalentData(talents: Talent[]): {
14
+ isValid: boolean;
15
+ errors: string[];
16
+ };
17
+ /**
18
+ * Calculates talent groups for analysis
19
+ */
20
+ export declare function calculateTalentGroups(talents: Talent[]): {
21
+ top14Talents: string[];
22
+ top7Talents: string[];
23
+ low14Talents: string[];
24
+ };
25
+ //# sourceMappingURL=talent-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"talent-extractor.d.ts","sourceRoot":"","sources":["../../src/extractors/talent-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AA6C5C;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,OAAe,EAC3B,SAAS,GAAE,MAAU,GACpB,MAAM,EAAE,CAaV;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAYnE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CA2B5F;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE;;;;EAYtD"}
@@ -0,0 +1,25 @@
1
+ import { Typology } from '../types/tma-types';
2
+ /**
3
+ * Extracts all 30 typologies with their scores from text
4
+ */
5
+ export declare function extractTypology(text: string): Typology[];
6
+ /**
7
+ * Validates extracted typology data
8
+ */
9
+ export declare function validateTypologyData(typologies: Typology[]): {
10
+ isValid: boolean;
11
+ errors: string[];
12
+ };
13
+ /**
14
+ * Sorts typologies by score in descending order
15
+ */
16
+ export declare function sortTypologiesByScore(typologies: Typology[]): Typology[];
17
+ /**
18
+ * Groups typologies by category
19
+ */
20
+ export declare function groupTypologiesByCategory(typologies: Typology[]): Record<string, Typology[]>;
21
+ /**
22
+ * Filters typologies to get top N highest scored ones
23
+ */
24
+ export declare function getTopTypologies(typologies: Typology[], count?: number): Typology[];
25
+ //# sourceMappingURL=typology-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typology-extractor.d.ts","sourceRoot":"","sources":["../../src/extractors/typology-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AA6B9C;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,CAqBxD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,QAAQ,EAAE,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CA4BnG;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAExE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAS5F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,KAAK,GAAE,MAAU,GAAG,QAAQ,EAAE,CAMtF"}