eggi-ai-db-schema-2 0.1.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 (188) hide show
  1. package/CHANGELOG.md +750 -0
  2. package/README.md +660 -0
  3. package/dist/config/database.d.ts +28 -0
  4. package/dist/config/database.d.ts.map +1 -0
  5. package/dist/config/database.js +72 -0
  6. package/dist/config/database.js.map +1 -0
  7. package/dist/index.d.ts +28 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +199 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/lib/database-service.d.ts +714 -0
  12. package/dist/lib/database-service.d.ts.map +1 -0
  13. package/dist/lib/database-service.js +1394 -0
  14. package/dist/lib/database-service.js.map +1 -0
  15. package/dist/lib/db-types.d.ts +167 -0
  16. package/dist/lib/db-types.d.ts.map +1 -0
  17. package/dist/lib/db-types.js +28 -0
  18. package/dist/lib/db-types.js.map +1 -0
  19. package/dist/lib/db.d.ts +58 -0
  20. package/dist/lib/db.d.ts.map +1 -0
  21. package/dist/lib/db.js +292 -0
  22. package/dist/lib/db.js.map +1 -0
  23. package/dist/lib/index.d.ts +11 -0
  24. package/dist/lib/index.d.ts.map +1 -0
  25. package/dist/lib/index.js +26 -0
  26. package/dist/lib/index.js.map +1 -0
  27. package/dist/lib/pg-client.d.ts +50 -0
  28. package/dist/lib/pg-client.d.ts.map +1 -0
  29. package/dist/lib/pg-client.js +106 -0
  30. package/dist/lib/pg-client.js.map +1 -0
  31. package/dist/lib/schema.d.ts +298 -0
  32. package/dist/lib/schema.d.ts.map +1 -0
  33. package/dist/lib/schema.js +12 -0
  34. package/dist/lib/schema.js.map +1 -0
  35. package/dist/migration-manager.d.ts +49 -0
  36. package/dist/migration-manager.d.ts.map +1 -0
  37. package/dist/migration-manager.js +282 -0
  38. package/dist/migration-manager.js.map +1 -0
  39. package/dist/queries/minimal-connections.d.ts +31 -0
  40. package/dist/queries/minimal-connections.d.ts.map +1 -0
  41. package/dist/queries/minimal-connections.js +143 -0
  42. package/dist/queries/minimal-connections.js.map +1 -0
  43. package/dist/schema.ts +340 -0
  44. package/dist/seed.d.ts +8 -0
  45. package/dist/seed.d.ts.map +1 -0
  46. package/dist/seed.js +40 -0
  47. package/dist/seed.js.map +1 -0
  48. package/dist/types/index.d.ts +7 -0
  49. package/dist/types/index.d.ts.map +1 -0
  50. package/dist/types/index.js +23 -0
  51. package/dist/types/index.js.map +1 -0
  52. package/dist/types/types.d.ts +77 -0
  53. package/dist/types/types.d.ts.map +1 -0
  54. package/dist/types/types.js +3 -0
  55. package/dist/types/types.js.map +1 -0
  56. package/dist/utils/authenticated-user-operations.d.ts +110 -0
  57. package/dist/utils/authenticated-user-operations.d.ts.map +1 -0
  58. package/dist/utils/authenticated-user-operations.js +292 -0
  59. package/dist/utils/authenticated-user-operations.js.map +1 -0
  60. package/dist/utils/authentication-operations.d.ts +48 -0
  61. package/dist/utils/authentication-operations.d.ts.map +1 -0
  62. package/dist/utils/authentication-operations.js +172 -0
  63. package/dist/utils/authentication-operations.js.map +1 -0
  64. package/dist/utils/company-mapping-job-operations.d.ts +103 -0
  65. package/dist/utils/company-mapping-job-operations.d.ts.map +1 -0
  66. package/dist/utils/company-mapping-job-operations.js +413 -0
  67. package/dist/utils/company-mapping-job-operations.js.map +1 -0
  68. package/dist/utils/company-sheet-upload-operations.d.ts +53 -0
  69. package/dist/utils/company-sheet-upload-operations.d.ts.map +1 -0
  70. package/dist/utils/company-sheet-upload-operations.js +135 -0
  71. package/dist/utils/company-sheet-upload-operations.js.map +1 -0
  72. package/dist/utils/contact-operations.d.ts +70 -0
  73. package/dist/utils/contact-operations.d.ts.map +1 -0
  74. package/dist/utils/contact-operations.js +294 -0
  75. package/dist/utils/contact-operations.js.map +1 -0
  76. package/dist/utils/forager-linkedin-operations.d.ts +74 -0
  77. package/dist/utils/forager-linkedin-operations.d.ts.map +1 -0
  78. package/dist/utils/forager-linkedin-operations.js +778 -0
  79. package/dist/utils/forager-linkedin-operations.js.map +1 -0
  80. package/dist/utils/ghost-genius-linkedin-operations.d.ts +23 -0
  81. package/dist/utils/ghost-genius-linkedin-operations.d.ts.map +1 -0
  82. package/dist/utils/ghost-genius-linkedin-operations.js +282 -0
  83. package/dist/utils/ghost-genius-linkedin-operations.js.map +1 -0
  84. package/dist/utils/index.d.ts +29 -0
  85. package/dist/utils/index.d.ts.map +1 -0
  86. package/dist/utils/index.js +77 -0
  87. package/dist/utils/index.js.map +1 -0
  88. package/dist/utils/introduction-request-operations.d.ts +160 -0
  89. package/dist/utils/introduction-request-operations.d.ts.map +1 -0
  90. package/dist/utils/introduction-request-operations.js +492 -0
  91. package/dist/utils/introduction-request-operations.js.map +1 -0
  92. package/dist/utils/invitation-operations.d.ts +141 -0
  93. package/dist/utils/invitation-operations.d.ts.map +1 -0
  94. package/dist/utils/invitation-operations.js +749 -0
  95. package/dist/utils/invitation-operations.js.map +1 -0
  96. package/dist/utils/linkedin-account-operations.d.ts +45 -0
  97. package/dist/utils/linkedin-account-operations.d.ts.map +1 -0
  98. package/dist/utils/linkedin-account-operations.js +279 -0
  99. package/dist/utils/linkedin-account-operations.js.map +1 -0
  100. package/dist/utils/linkedin-account-relationship-operations.d.ts +77 -0
  101. package/dist/utils/linkedin-account-relationship-operations.d.ts.map +1 -0
  102. package/dist/utils/linkedin-account-relationship-operations.js +274 -0
  103. package/dist/utils/linkedin-account-relationship-operations.js.map +1 -0
  104. package/dist/utils/linkedin-data-operations.d.ts +102 -0
  105. package/dist/utils/linkedin-data-operations.d.ts.map +1 -0
  106. package/dist/utils/linkedin-data-operations.js +613 -0
  107. package/dist/utils/linkedin-data-operations.js.map +1 -0
  108. package/dist/utils/linkedin-identifier-utils.d.ts +31 -0
  109. package/dist/utils/linkedin-identifier-utils.d.ts.map +1 -0
  110. package/dist/utils/linkedin-identifier-utils.js +63 -0
  111. package/dist/utils/linkedin-identifier-utils.js.map +1 -0
  112. package/dist/utils/linkedin-profile-cache.d.ts +131 -0
  113. package/dist/utils/linkedin-profile-cache.d.ts.map +1 -0
  114. package/dist/utils/linkedin-profile-cache.js +418 -0
  115. package/dist/utils/linkedin-profile-cache.js.map +1 -0
  116. package/dist/utils/llm-inference-job-operations.d.ts +116 -0
  117. package/dist/utils/llm-inference-job-operations.d.ts.map +1 -0
  118. package/dist/utils/llm-inference-job-operations.js +267 -0
  119. package/dist/utils/llm-inference-job-operations.js.map +1 -0
  120. package/dist/utils/mapping-job-operations.d.ts +272 -0
  121. package/dist/utils/mapping-job-operations.d.ts.map +1 -0
  122. package/dist/utils/mapping-job-operations.js +833 -0
  123. package/dist/utils/mapping-job-operations.js.map +1 -0
  124. package/dist/utils/mapping-operations.d.ts +80 -0
  125. package/dist/utils/mapping-operations.d.ts.map +1 -0
  126. package/dist/utils/mapping-operations.js +318 -0
  127. package/dist/utils/mapping-operations.js.map +1 -0
  128. package/dist/utils/on-demand-mapping-operations.d.ts +199 -0
  129. package/dist/utils/on-demand-mapping-operations.d.ts.map +1 -0
  130. package/dist/utils/on-demand-mapping-operations.js +728 -0
  131. package/dist/utils/on-demand-mapping-operations.js.map +1 -0
  132. package/dist/utils/onboarding-operations.d.ts +53 -0
  133. package/dist/utils/onboarding-operations.d.ts.map +1 -0
  134. package/dist/utils/onboarding-operations.js +223 -0
  135. package/dist/utils/onboarding-operations.js.map +1 -0
  136. package/dist/utils/organization-assignment-job-operations.d.ts +258 -0
  137. package/dist/utils/organization-assignment-job-operations.d.ts.map +1 -0
  138. package/dist/utils/organization-assignment-job-operations.js +881 -0
  139. package/dist/utils/organization-assignment-job-operations.js.map +1 -0
  140. package/dist/utils/organization-assignment-operations.d.ts +59 -0
  141. package/dist/utils/organization-assignment-operations.d.ts.map +1 -0
  142. package/dist/utils/organization-assignment-operations.js +130 -0
  143. package/dist/utils/organization-assignment-operations.js.map +1 -0
  144. package/dist/utils/organization-operations.d.ts +284 -0
  145. package/dist/utils/organization-operations.d.ts.map +1 -0
  146. package/dist/utils/organization-operations.js +1030 -0
  147. package/dist/utils/organization-operations.js.map +1 -0
  148. package/dist/utils/organization-relationship-operations.d.ts +79 -0
  149. package/dist/utils/organization-relationship-operations.d.ts.map +1 -0
  150. package/dist/utils/organization-relationship-operations.js +294 -0
  151. package/dist/utils/organization-relationship-operations.js.map +1 -0
  152. package/dist/utils/quota-operations.d.ts +107 -0
  153. package/dist/utils/quota-operations.d.ts.map +1 -0
  154. package/dist/utils/quota-operations.js +692 -0
  155. package/dist/utils/quota-operations.js.map +1 -0
  156. package/dist/utils/recursive-mapping-job-operations.d.ts +42 -0
  157. package/dist/utils/recursive-mapping-job-operations.d.ts.map +1 -0
  158. package/dist/utils/recursive-mapping-job-operations.js +169 -0
  159. package/dist/utils/recursive-mapping-job-operations.js.map +1 -0
  160. package/dist/utils/relationship-operations.d.ts +130 -0
  161. package/dist/utils/relationship-operations.d.ts.map +1 -0
  162. package/dist/utils/relationship-operations.js +329 -0
  163. package/dist/utils/relationship-operations.js.map +1 -0
  164. package/dist/utils/sales-pipeline-operations.d.ts +163 -0
  165. package/dist/utils/sales-pipeline-operations.d.ts.map +1 -0
  166. package/dist/utils/sales-pipeline-operations.js +725 -0
  167. package/dist/utils/sales-pipeline-operations.js.map +1 -0
  168. package/dist/utils/skills-operations.d.ts +117 -0
  169. package/dist/utils/skills-operations.d.ts.map +1 -0
  170. package/dist/utils/skills-operations.js +487 -0
  171. package/dist/utils/skills-operations.js.map +1 -0
  172. package/dist/utils/subscription-operations.d.ts +123 -0
  173. package/dist/utils/subscription-operations.d.ts.map +1 -0
  174. package/dist/utils/subscription-operations.js +391 -0
  175. package/dist/utils/subscription-operations.js.map +1 -0
  176. package/dist/utils/unipile-account-operations.d.ts +96 -0
  177. package/dist/utils/unipile-account-operations.d.ts.map +1 -0
  178. package/dist/utils/unipile-account-operations.js +255 -0
  179. package/dist/utils/unipile-account-operations.js.map +1 -0
  180. package/dist/utils/user-industry-operations.d.ts +80 -0
  181. package/dist/utils/user-industry-operations.d.ts.map +1 -0
  182. package/dist/utils/user-industry-operations.js +237 -0
  183. package/dist/utils/user-industry-operations.js.map +1 -0
  184. package/dist/utils/user-operations.d.ts +87 -0
  185. package/dist/utils/user-operations.d.ts.map +1 -0
  186. package/dist/utils/user-operations.js +212 -0
  187. package/dist/utils/user-operations.js.map +1 -0
  188. package/package.json +98 -0
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ /**
3
+ * LinkedIn Identifier Utilities for RDS Schema Package
4
+ *
5
+ * Utilities for validating and working with LinkedIn identifiers
6
+ * Now uses consolidated linkedin.accounts table for centralized identifier management
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.InvalidAcoIdentifierError = void 0;
10
+ exports.validateAcoIdentifier = validateAcoIdentifier;
11
+ exports.extractLinkedInIdentifiers = extractLinkedInIdentifiers;
12
+ /**
13
+ * Validation error for invalid ACoA identifiers
14
+ */
15
+ class InvalidAcoIdentifierError extends Error {
16
+ constructor(identifier, reason) {
17
+ super(`Invalid ACoA identifier "${identifier}": ${reason}`);
18
+ this.name = "InvalidAcoIdentifierError";
19
+ }
20
+ }
21
+ exports.InvalidAcoIdentifierError = InvalidAcoIdentifierError;
22
+ /**
23
+ * Validates that an ACoA identifier meets all requirements:
24
+ * - Starts with "ACoA"
25
+ * - Is exactly 39 characters long
26
+ * - Contains only valid characters (alphanumeric + underscores, hyphens)
27
+ */
28
+ function validateAcoIdentifier(identifier) {
29
+ if (!identifier) {
30
+ throw new InvalidAcoIdentifierError(identifier, "identifier cannot be empty or null");
31
+ }
32
+ const trimmed = identifier.trim();
33
+ if (!trimmed.startsWith("ACoA")) {
34
+ throw new InvalidAcoIdentifierError(identifier, "must start with 'ACoA'");
35
+ }
36
+ if (trimmed.length !== 39) {
37
+ throw new InvalidAcoIdentifierError(identifier, `must be exactly 39 characters long, got ${trimmed.length} characters`);
38
+ }
39
+ // Optional: Validate character set (LinkedIn identifiers typically use alphanumeric + some special chars)
40
+ const validPattern = /^ACoA[A-Za-z0-9_-]+$/;
41
+ if (!validPattern.test(trimmed)) {
42
+ throw new InvalidAcoIdentifierError(identifier, "contains invalid characters (only alphanumeric, underscore, and hyphen allowed after 'ACoA')");
43
+ }
44
+ }
45
+ /**
46
+ * Extract LinkedIn identifiers from profile data for linkedin.accounts table
47
+ * This is the consolidated approach that replaces the old identifier mapping logic
48
+ */
49
+ function extractLinkedInIdentifiers(requestIdentifier, profileData) {
50
+ // Extract ACoA identifier (prioritize provider_id from Ghost Genius)
51
+ const acoaIdentifier = profileData.provider_id || requestIdentifier;
52
+ // Extract public identifier
53
+ const publicIdentifier = profileData.public_identifier || "unknown";
54
+ // Validate ACoA identifier if it looks like one
55
+ if (acoaIdentifier.startsWith("ACoA")) {
56
+ validateAcoIdentifier(acoaIdentifier);
57
+ }
58
+ return {
59
+ linkedinIdentifierAcoa: acoaIdentifier,
60
+ publicIdentifier,
61
+ };
62
+ }
63
+ //# sourceMappingURL=linkedin-identifier-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linkedin-identifier-utils.js","sourceRoot":"","sources":["../../src/utils/linkedin-identifier-utils.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAkBH,sDA0BC;AAMD,gEAsBC;AAtED;;GAEG;AACH,MAAa,yBAA0B,SAAQ,KAAK;IAClD,YAAY,UAAkB,EAAE,MAAc;QAC5C,KAAK,CAAC,4BAA4B,UAAU,MAAM,MAAM,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;IAC1C,CAAC;CACF;AALD,8DAKC;AAED;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,UAAkB;IACtD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,yBAAyB,CAAC,UAAU,EAAE,oCAAoC,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;IAElC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,yBAAyB,CAAC,UAAU,EAAE,wBAAwB,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC1B,MAAM,IAAI,yBAAyB,CACjC,UAAU,EACV,2CAA2C,OAAO,CAAC,MAAM,aAAa,CACvE,CAAC;IACJ,CAAC;IAED,0GAA0G;IAC1G,MAAM,YAAY,GAAG,sBAAsB,CAAC;IAC5C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,yBAAyB,CACjC,UAAU,EACV,8FAA8F,CAC/F,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,0BAA0B,CACxC,iBAAyB,EACzB,WAAyF;IAKzF,qEAAqE;IACrE,MAAM,cAAc,GAAG,WAAW,CAAC,WAAW,IAAI,iBAAiB,CAAC;IAEpE,4BAA4B;IAC5B,MAAM,gBAAgB,GAAG,WAAW,CAAC,iBAAiB,IAAI,SAAS,CAAC;IAEpE,gDAAgD;IAChD,IAAI,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACtC,qBAAqB,CAAC,cAAc,CAAC,CAAC;IACxC,CAAC;IAED,OAAO;QACL,sBAAsB,EAAE,cAAc;QACtC,gBAAgB;KACjB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * LinkedIn Profile Caching Utilities - Consolidated Schema
3
+ *
4
+ * Provides functions to check for existing LinkedIn profiles and retrieve cached data
5
+ * to avoid unnecessary API calls when profile data is already available.
6
+ * Updated to work with the new consolidated linkedin.accounts schema.
7
+ */
8
+ import { Pool, PoolClient } from 'pg';
9
+ import type { Database } from "../lib/db";
10
+ /**
11
+ * Result of checking if a LinkedIn profile exists in cache
12
+ */
13
+ export interface ProfileCacheCheckResult {
14
+ exists: boolean;
15
+ linkedinAccountId?: number;
16
+ firstName?: string | undefined;
17
+ lastName?: string | undefined;
18
+ headline?: string | undefined;
19
+ location?: string | undefined;
20
+ profilePictureUrl?: string | undefined;
21
+ followerCount?: number | undefined;
22
+ connectionsCount?: number | undefined;
23
+ linkedinIdentifierAcoa?: string | undefined;
24
+ publicIdentifier?: string | undefined;
25
+ createdAt?: Date | undefined;
26
+ updatedAt?: Date | undefined;
27
+ }
28
+ /**
29
+ * Complete cached profile data in Ghost Genius format
30
+ */
31
+ export interface CachedLinkedInProfile {
32
+ provider_id: string;
33
+ public_identifier?: string | undefined;
34
+ first_name?: string | undefined;
35
+ last_name?: string | undefined;
36
+ headline?: string | undefined;
37
+ summary?: string | undefined;
38
+ location?: string | undefined;
39
+ profile_picture_url?: string | undefined;
40
+ follower_count?: number | undefined;
41
+ connections_count?: number | undefined;
42
+ skills?: Array<{
43
+ name: string;
44
+ }>;
45
+ work_experience?: Array<{
46
+ position?: string | undefined;
47
+ company?: string | undefined;
48
+ company_id?: string | undefined;
49
+ company_linkedin_url?: string | undefined;
50
+ location?: string | undefined;
51
+ employment_type?: string | undefined;
52
+ description?: string | undefined;
53
+ is_current?: boolean | undefined;
54
+ start_date?: string | undefined;
55
+ end_date?: string | undefined;
56
+ skills?: Array<{
57
+ name: string;
58
+ }>;
59
+ }>;
60
+ education?: Array<{
61
+ degree?: string | undefined;
62
+ school?: string | undefined;
63
+ school_id?: string | undefined;
64
+ field_of_study?: string | undefined;
65
+ grade?: string | undefined;
66
+ description?: string | undefined;
67
+ activities_and_societies?: string | undefined;
68
+ school_linkedin_url?: string | undefined;
69
+ start_date?: string | undefined;
70
+ end_date?: string | undefined;
71
+ skills?: Array<{
72
+ name: string;
73
+ }>;
74
+ }>;
75
+ certifications?: Array<{
76
+ name?: string | undefined;
77
+ authority?: string | undefined;
78
+ license_number?: string | undefined;
79
+ url?: string | undefined;
80
+ start_date?: string | undefined;
81
+ end_date?: string | undefined;
82
+ }>;
83
+ projects?: Array<{
84
+ title?: string | undefined;
85
+ description?: string | undefined;
86
+ url?: string | undefined;
87
+ start_date?: string | undefined;
88
+ end_date?: string | undefined;
89
+ }>;
90
+ contact_info?: Array<{
91
+ type: "EMAIL" | "PHONE_NUMBER" | "URL";
92
+ value: string;
93
+ source?: string;
94
+ }>;
95
+ }
96
+ /**
97
+ * Check if LinkedIn profiles exist in cache for multiple ACoA identifiers
98
+ * Returns basic profile information for cache hit determination
99
+ */
100
+ export declare function checkLinkedInProfilesExistInCache(db: Database | Pool | PoolClient, acoIdentifiers: string[]): Promise<ProfileCacheCheckResult[]>;
101
+ /**
102
+ * Check if a single LinkedIn profile exists in cache
103
+ */
104
+ export declare function checkLinkedInProfileExistsInCache(db: Database | Pool | PoolClient, identifier: string): Promise<ProfileCacheCheckResult>;
105
+ /**
106
+ * Get complete cached LinkedIn profile data in Ghost Genius format
107
+ * Supports both ACoA identifiers and public identifiers
108
+ */
109
+ export declare function getCachedLinkedInProfile(db: Database | Pool | PoolClient, identifier: string): Promise<CachedLinkedInProfile | null>;
110
+ /**
111
+ * Get complete cached LinkedIn profile data by LinkedIn account ID
112
+ * More efficient when you already have the account ID (avoids identifier lookup)
113
+ */
114
+ export declare function getCachedLinkedInProfileById(db: Database | Pool | PoolClient, linkedinAccountId: number): Promise<CachedLinkedInProfile | null>;
115
+ /**
116
+ * Get multiple cached LinkedIn profiles by ACoA identifiers
117
+ */
118
+ export declare function getCachedLinkedInProfiles(db: Database | Pool | PoolClient, identifiers: string[]): Promise<(CachedLinkedInProfile | null)[]>;
119
+ /**
120
+ * Check if a LinkedIn profile has complete data (useful for cache validation)
121
+ */
122
+ export declare function isProfileDataComplete(profile: CachedLinkedInProfile): boolean;
123
+ /**
124
+ * Get the age of cached profile data in hours
125
+ */
126
+ export declare function getCachedProfileAge(cacheCheckResult: ProfileCacheCheckResult): number | null;
127
+ /**
128
+ * Determine if cached profile data should be refreshed based on age
129
+ */
130
+ export declare function shouldRefreshCachedProfile(cacheCheckResult: ProfileCacheCheckResult, maxAgeHours?: number): boolean;
131
+ //# sourceMappingURL=linkedin-profile-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linkedin-profile-cache.d.ts","sourceRoot":"","sources":["../../src/utils/linkedin-profile-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,418 @@
1
+ "use strict";
2
+ /**
3
+ * LinkedIn Profile Caching Utilities - Consolidated Schema
4
+ *
5
+ * Provides functions to check for existing LinkedIn profiles and retrieve cached data
6
+ * to avoid unnecessary API calls when profile data is already available.
7
+ * Updated to work with the new consolidated linkedin.accounts schema.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.checkLinkedInProfilesExistInCache = checkLinkedInProfilesExistInCache;
11
+ exports.checkLinkedInProfileExistsInCache = checkLinkedInProfileExistsInCache;
12
+ exports.getCachedLinkedInProfile = getCachedLinkedInProfile;
13
+ exports.getCachedLinkedInProfileById = getCachedLinkedInProfileById;
14
+ exports.getCachedLinkedInProfiles = getCachedLinkedInProfiles;
15
+ exports.isProfileDataComplete = isProfileDataComplete;
16
+ exports.getCachedProfileAge = getCachedProfileAge;
17
+ exports.shouldRefreshCachedProfile = shouldRefreshCachedProfile;
18
+ const pg_client_1 = require("../lib/pg-client");
19
+ /**
20
+ * Helper function to handle optional string fields
21
+ * Returns undefined if value is null, undefined, or empty string
22
+ * This ensures optional fields are omitted from JSON response when not present
23
+ */
24
+ function optionalString(value) {
25
+ if (value === null || value === undefined || value.trim() === "") {
26
+ return undefined;
27
+ }
28
+ return value;
29
+ }
30
+ /**
31
+ * Helper function for required string fields
32
+ * Returns empty string if value is null/undefined (required fields must be present)
33
+ */
34
+ function requiredString(value) {
35
+ return value || "";
36
+ }
37
+ // =============================================================================
38
+ // CACHE CHECK FUNCTIONS
39
+ // =============================================================================
40
+ /**
41
+ * Check if LinkedIn profiles exist in cache for multiple ACoA identifiers
42
+ * Returns basic profile information for cache hit determination
43
+ */
44
+ async function checkLinkedInProfilesExistInCache(db, acoIdentifiers) {
45
+ if (acoIdentifiers.length === 0) {
46
+ return [];
47
+ }
48
+ try {
49
+ const placeholders = acoIdentifiers.map((_, i) => `$${i + 1}`).join(', ');
50
+ const sql = `
51
+ SELECT
52
+ id as linkedin_account_id,
53
+ first_name,
54
+ last_name,
55
+ headline,
56
+ location,
57
+ COALESCE(profile_image_cloudfront_url, profile_picture_url) as profile_picture_url,
58
+ follower_count,
59
+ connections_count,
60
+ linkedin_identifier_acoa,
61
+ public_identifier,
62
+ created_at,
63
+ profiles_updated_at
64
+ FROM linkedin.accounts
65
+ WHERE linkedin_identifier_acoa IN (${placeholders})
66
+ `;
67
+ const results = await (0, pg_client_1.query)(db, sql, acoIdentifiers);
68
+ // Create a map of found profiles
69
+ const foundProfiles = new Map();
70
+ results.forEach(result => {
71
+ if (result.linkedin_identifier_acoa) {
72
+ foundProfiles.set(result.linkedin_identifier_acoa, {
73
+ exists: true,
74
+ linkedinAccountId: result.linkedin_account_id,
75
+ firstName: result.first_name || undefined,
76
+ lastName: result.last_name || undefined,
77
+ headline: result.headline || undefined,
78
+ location: result.location || undefined,
79
+ profilePictureUrl: result.profile_picture_url || undefined,
80
+ followerCount: result.follower_count || undefined,
81
+ connectionsCount: result.connections_count || undefined,
82
+ linkedinIdentifierAcoa: result.linkedin_identifier_acoa,
83
+ publicIdentifier: result.public_identifier || undefined,
84
+ createdAt: result.created_at,
85
+ updatedAt: result.profiles_updated_at || undefined,
86
+ });
87
+ }
88
+ });
89
+ // Return results in the same order as input, with exists: false for missing profiles
90
+ return acoIdentifiers.map(identifier => {
91
+ return foundProfiles.get(identifier) || { exists: false };
92
+ });
93
+ }
94
+ catch (error) {
95
+ console.error("Error checking LinkedIn profiles in cache:", error);
96
+ throw error;
97
+ }
98
+ }
99
+ /**
100
+ * Check if a single LinkedIn profile exists in cache
101
+ */
102
+ async function checkLinkedInProfileExistsInCache(db, identifier) {
103
+ const results = await checkLinkedInProfilesExistInCache(db, [identifier]);
104
+ return results[0] || { exists: false };
105
+ }
106
+ // =============================================================================
107
+ // COMPLETE PROFILE RETRIEVAL
108
+ // =============================================================================
109
+ /**
110
+ * Get complete cached LinkedIn profile data in Ghost Genius format
111
+ * Supports both ACoA identifiers and public identifiers
112
+ */
113
+ async function getCachedLinkedInProfile(db, identifier) {
114
+ try {
115
+ // Find the LinkedIn account by identifier (ACoA or public)
116
+ const accountSql = `
117
+ SELECT
118
+ id as linkedin_account_id,
119
+ first_name,
120
+ last_name,
121
+ headline,
122
+ summary,
123
+ location,
124
+ COALESCE(profile_image_cloudfront_url, profile_picture_url) as profile_picture_url,
125
+ follower_count,
126
+ connections_count,
127
+ linkedin_identifier_acoa,
128
+ public_identifier
129
+ FROM linkedin.accounts
130
+ WHERE linkedin_identifier_acoa = $1 OR public_identifier = $1
131
+ LIMIT 1
132
+ `;
133
+ const account = await (0, pg_client_1.queryOne)(db, accountSql, [identifier]);
134
+ if (!account) {
135
+ return null;
136
+ }
137
+ const linkedinAccountId = account.linkedin_account_id;
138
+ // Get all related data in parallel
139
+ const [workExperience, education, certifications, projects, profileSkills] = await Promise.all([
140
+ // Work experience
141
+ (0, pg_client_1.query)(db, `SELECT id, position, company, company_id, company_linkedin_url, location, employment_type, description, is_current, start_date, end_date
142
+ FROM linkedin.work_experience
143
+ WHERE linkedin_account_id = $1`, [linkedinAccountId]),
144
+ // Education
145
+ (0, pg_client_1.query)(db, `SELECT id, degree, school, school_id, field_of_study, grade, description, activities_and_societies, school_linkedin_url, start_date, end_date
146
+ FROM linkedin.education
147
+ WHERE linkedin_account_id = $1`, [linkedinAccountId]),
148
+ // Certifications
149
+ (0, pg_client_1.query)(db, `SELECT name, organization, url
150
+ FROM linkedin.certifications
151
+ WHERE linkedin_account_id = $1`, [linkedinAccountId]),
152
+ // Projects
153
+ (0, pg_client_1.query)(db, `SELECT name, description, start_date, end_date
154
+ FROM linkedin.projects
155
+ WHERE linkedin_account_id = $1`, [linkedinAccountId]),
156
+ // Profile skills
157
+ (0, pg_client_1.query)(db, `SELECT s.name as skill_name
158
+ FROM linkedin.profile_skills ps
159
+ INNER JOIN linkedin.skills s ON ps.skill_id = s.id
160
+ WHERE ps.linkedin_account_id = $1`, [linkedinAccountId]),
161
+ ]);
162
+ // Get work experience skills
163
+ const workExpSkills = await Promise.all(workExperience.map(async (exp) => {
164
+ const expSkills = await (0, pg_client_1.query)(db, `SELECT s.name as skill_name
165
+ FROM linkedin.work_experience_skills wes
166
+ INNER JOIN linkedin.skills s ON wes.skill_id = s.id
167
+ WHERE wes.work_experience_id = $1`, [exp.id]);
168
+ return {
169
+ workExperienceId: exp.id,
170
+ skills: expSkills.map(s => ({ name: s.skill_name })),
171
+ };
172
+ }));
173
+ // Get education skills
174
+ const eduSkills = await Promise.all(education.map(async (edu) => {
175
+ const eduSkillsData = await (0, pg_client_1.query)(db, `SELECT s.name as skill_name
176
+ FROM linkedin.education_skills es
177
+ INNER JOIN linkedin.skills s ON es.skill_id = s.id
178
+ WHERE es.education_id = $1`, [edu.id]);
179
+ return {
180
+ educationId: edu.id,
181
+ skills: eduSkillsData.map(s => ({ name: s.skill_name })),
182
+ };
183
+ }));
184
+ // Create skills maps for easy lookup
185
+ const workExpSkillsMap = new Map(workExpSkills.map(item => [item.workExperienceId, item.skills]));
186
+ const eduSkillsMap = new Map(eduSkills.map(item => [item.educationId, item.skills]));
187
+ // Build the complete profile in Ghost Genius format
188
+ const cachedProfile = {
189
+ provider_id: account.linkedin_identifier_acoa || "",
190
+ public_identifier: optionalString(account.public_identifier),
191
+ first_name: optionalString(account.first_name),
192
+ last_name: optionalString(account.last_name),
193
+ headline: optionalString(account.headline),
194
+ summary: optionalString(account.summary),
195
+ location: optionalString(account.location),
196
+ profile_picture_url: optionalString(account.profile_picture_url),
197
+ follower_count: account.follower_count || undefined,
198
+ connections_count: account.connections_count || undefined,
199
+ skills: profileSkills.map(skill => ({ name: skill.skill_name })),
200
+ work_experience: workExperience.map(exp => ({
201
+ position: optionalString(exp.position),
202
+ company: optionalString(exp.company),
203
+ company_id: optionalString(exp.company_id),
204
+ company_linkedin_url: optionalString(exp.company_linkedin_url),
205
+ location: optionalString(exp.location),
206
+ employment_type: optionalString(exp.employment_type),
207
+ description: optionalString(exp.description),
208
+ is_current: exp.is_current || false,
209
+ start_date: optionalString(exp.start_date),
210
+ end_date: optionalString(exp.end_date),
211
+ skills: workExpSkillsMap.get(exp.id) || [],
212
+ })),
213
+ education: education.map(edu => ({
214
+ degree: optionalString(edu.degree),
215
+ school: optionalString(edu.school),
216
+ school_id: optionalString(edu.school_id),
217
+ field_of_study: optionalString(edu.field_of_study),
218
+ grade: optionalString(edu.grade),
219
+ description: optionalString(edu.description),
220
+ activities_and_societies: optionalString(edu.activities_and_societies),
221
+ school_linkedin_url: optionalString(edu.school_linkedin_url),
222
+ start_date: optionalString(edu.start_date),
223
+ end_date: optionalString(edu.end_date),
224
+ skills: eduSkillsMap.get(edu.id) || [],
225
+ })),
226
+ certifications: certifications.map(cert => ({
227
+ name: optionalString(cert.name),
228
+ authority: optionalString(cert.organization),
229
+ license_number: undefined,
230
+ url: optionalString(cert.url),
231
+ start_date: undefined,
232
+ end_date: undefined,
233
+ })),
234
+ projects: projects.map(project => ({
235
+ title: optionalString(project.name),
236
+ description: optionalString(project.description),
237
+ url: undefined,
238
+ start_date: optionalString(project.start_date),
239
+ end_date: optionalString(project.end_date),
240
+ })),
241
+ contact_info: [],
242
+ };
243
+ return cachedProfile;
244
+ }
245
+ catch (error) {
246
+ console.error("Error getting cached LinkedIn profile:", error);
247
+ throw error;
248
+ }
249
+ }
250
+ /**
251
+ * Get complete cached LinkedIn profile data by LinkedIn account ID
252
+ * More efficient when you already have the account ID (avoids identifier lookup)
253
+ */
254
+ async function getCachedLinkedInProfileById(db, linkedinAccountId) {
255
+ try {
256
+ // Direct query by account ID - no need to lookup by identifier
257
+ const accountSql = `
258
+ SELECT
259
+ id as linkedin_account_id,
260
+ first_name,
261
+ last_name,
262
+ headline,
263
+ summary,
264
+ location,
265
+ COALESCE(profile_image_cloudfront_url, profile_picture_url) as profile_picture_url,
266
+ follower_count,
267
+ connections_count,
268
+ linkedin_identifier_acoa,
269
+ public_identifier
270
+ FROM linkedin.accounts
271
+ WHERE id = $1
272
+ LIMIT 1
273
+ `;
274
+ const account = await (0, pg_client_1.queryOne)(db, accountSql, [linkedinAccountId]);
275
+ if (!account) {
276
+ return null;
277
+ }
278
+ const accountId = account.linkedin_account_id;
279
+ // Get all related data in parallel
280
+ const [workExperience, education, certifications, projects, profileSkills] = await Promise.all([
281
+ // Work experience
282
+ (0, pg_client_1.query)(db, `SELECT id, position, company, company_id, company_linkedin_url, location, employment_type, description, is_current, start_date, end_date
283
+ FROM linkedin.work_experience
284
+ WHERE linkedin_account_id = $1
285
+ ORDER BY start_date DESC`, [accountId]),
286
+ // Education
287
+ (0, pg_client_1.query)(db, `SELECT id, school, school_id, school_linkedin_url, degree, field_of_study, grade, description, activities_and_societies, start_date, end_date
288
+ FROM linkedin.education
289
+ WHERE linkedin_account_id = $1
290
+ ORDER BY start_date DESC`, [accountId]),
291
+ // Certifications
292
+ (0, pg_client_1.query)(db, `SELECT id, name, organization, url
293
+ FROM linkedin.certifications
294
+ WHERE linkedin_account_id = $1`, [accountId]),
295
+ // Projects
296
+ (0, pg_client_1.query)(db, `SELECT id, name, description, start_date, end_date
297
+ FROM linkedin.projects
298
+ WHERE linkedin_account_id = $1
299
+ ORDER BY start_date DESC`, [accountId]),
300
+ // Profile skills
301
+ (0, pg_client_1.query)(db, `SELECT s.name as skill_name
302
+ FROM linkedin.profile_skills ps
303
+ INNER JOIN linkedin.skills s ON ps.skill_id = s.id
304
+ WHERE ps.linkedin_account_id = $1`, [accountId]),
305
+ ]);
306
+ // Build the complete profile in Ghost Genius format
307
+ const cachedProfile = {
308
+ provider_id: account.linkedin_identifier_acoa || "",
309
+ public_identifier: optionalString(account.public_identifier),
310
+ first_name: optionalString(account.first_name),
311
+ last_name: optionalString(account.last_name),
312
+ headline: optionalString(account.headline),
313
+ summary: optionalString(account.summary),
314
+ location: optionalString(account.location),
315
+ profile_picture_url: optionalString(account.profile_picture_url),
316
+ follower_count: account.follower_count || undefined,
317
+ connections_count: account.connections_count || undefined,
318
+ skills: profileSkills.map(skill => ({ name: skill.skill_name })),
319
+ work_experience: workExperience.map(exp => ({
320
+ position: optionalString(exp.position),
321
+ company: optionalString(exp.company),
322
+ company_id: optionalString(exp.company_id),
323
+ company_linkedin_url: optionalString(exp.company_linkedin_url),
324
+ location: optionalString(exp.location),
325
+ employment_type: optionalString(exp.employment_type),
326
+ description: optionalString(exp.description),
327
+ is_current: exp.is_current || false,
328
+ start_date: exp.start_date || undefined,
329
+ end_date: exp.end_date || undefined,
330
+ })),
331
+ education: education.map(edu => ({
332
+ school: optionalString(edu.school),
333
+ school_id: optionalString(edu.school_id),
334
+ school_linkedin_url: optionalString(edu.school_linkedin_url),
335
+ degree: optionalString(edu.degree),
336
+ field_of_study: optionalString(edu.field_of_study),
337
+ grade: optionalString(edu.grade),
338
+ description: optionalString(edu.description),
339
+ activities_and_societies: optionalString(edu.activities_and_societies),
340
+ start_date: edu.start_date || undefined,
341
+ end_date: edu.end_date || undefined,
342
+ })),
343
+ certifications: certifications.map(cert => ({
344
+ name: optionalString(cert.name),
345
+ authority: optionalString(cert.organization),
346
+ url: optionalString(cert.url),
347
+ })),
348
+ projects: projects.map(proj => ({
349
+ title: optionalString(proj.name),
350
+ description: optionalString(proj.description),
351
+ start_date: proj.start_date || undefined,
352
+ end_date: proj.end_date || undefined,
353
+ })),
354
+ contact_info: [],
355
+ };
356
+ return cachedProfile;
357
+ }
358
+ catch (error) {
359
+ console.error("Error getting cached LinkedIn profile by ID:", error);
360
+ throw error;
361
+ }
362
+ }
363
+ /**
364
+ * Get multiple cached LinkedIn profiles by ACoA identifiers
365
+ */
366
+ async function getCachedLinkedInProfiles(db, identifiers) {
367
+ if (identifiers.length === 0) {
368
+ return [];
369
+ }
370
+ try {
371
+ // Get all profiles in parallel
372
+ const profiles = await Promise.all(identifiers.map(identifier => getCachedLinkedInProfile(db, identifier)));
373
+ return profiles;
374
+ }
375
+ catch (error) {
376
+ console.error("Error getting cached LinkedIn profiles:", error);
377
+ throw error;
378
+ }
379
+ }
380
+ // =============================================================================
381
+ // UTILITY FUNCTIONS
382
+ // =============================================================================
383
+ /**
384
+ * Check if a LinkedIn profile has complete data (useful for cache validation)
385
+ */
386
+ function isProfileDataComplete(profile) {
387
+ return !!(profile.first_name &&
388
+ profile.last_name &&
389
+ profile.headline &&
390
+ (profile.work_experience?.length || 0) > 0);
391
+ }
392
+ /**
393
+ * Get the age of cached profile data in hours
394
+ */
395
+ function getCachedProfileAge(cacheCheckResult) {
396
+ if (!cacheCheckResult.exists || !cacheCheckResult.updatedAt) {
397
+ return null;
398
+ }
399
+ const now = new Date();
400
+ const updatedAt = new Date(cacheCheckResult.updatedAt);
401
+ const diffMs = now.getTime() - updatedAt.getTime();
402
+ const diffHours = diffMs / (1000 * 60 * 60);
403
+ return diffHours;
404
+ }
405
+ /**
406
+ * Determine if cached profile data should be refreshed based on age
407
+ */
408
+ function shouldRefreshCachedProfile(cacheCheckResult, maxAgeHours = 24) {
409
+ if (!cacheCheckResult.exists) {
410
+ return true; // No cache, needs refresh
411
+ }
412
+ const age = getCachedProfileAge(cacheCheckResult);
413
+ if (age === null) {
414
+ return true; // No update timestamp, needs refresh
415
+ }
416
+ return age > maxAgeHours;
417
+ }
418
+ //# sourceMappingURL=linkedin-profile-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linkedin-profile-cache.js","sourceRoot":"","sources":["../../src/utils/linkedin-profile-cache.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAoHH,8EAyEC;AAKD,8EAMC;AAUD,4DA0OC;AAMD,oEA6LC;AAKD,8DAmBC;AASD,sDAOC;AAKD,kDAWC;AAKD,gEAcC;AAvsBD,gDAAmD;AAGnD;;;;GAIG;AACH,SAAS,cAAc,CAAC,KAAgC;IACtD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACjE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,KAAgC;IACtD,OAAO,KAAK,IAAI,EAAE,CAAC;AACrB,CAAC;AAoFD,gFAAgF;AAChF,wBAAwB;AACxB,gFAAgF;AAEhF;;;GAGG;AACI,KAAK,UAAU,iCAAiC,CACrD,EAAgC,EAChC,cAAwB;IAExB,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1E,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;2CAe2B,YAAY;KAClD,CAAC;QAEF,MAAM,OAAO,GAAG,MAAM,IAAA,iBAAK,EAaxB,EAAuB,EAAE,GAAG,EAAE,cAAc,CAAC,CAAC;QAEjD,iCAAiC;QACjC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAmC,CAAC;QACjE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACvB,IAAI,MAAM,CAAC,wBAAwB,EAAE,CAAC;gBACpC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,wBAAwB,EAAE;oBACjD,MAAM,EAAE,IAAI;oBACZ,iBAAiB,EAAE,MAAM,CAAC,mBAAmB;oBAC7C,SAAS,EAAE,MAAM,CAAC,UAAU,IAAI,SAAS;oBACzC,QAAQ,EAAE,MAAM,CAAC,SAAS,IAAI,SAAS;oBACvC,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,SAAS;oBACtC,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,SAAS;oBACtC,iBAAiB,EAAE,MAAM,CAAC,mBAAmB,IAAI,SAAS;oBAC1D,aAAa,EAAE,MAAM,CAAC,cAAc,IAAI,SAAS;oBACjD,gBAAgB,EAAE,MAAM,CAAC,iBAAiB,IAAI,SAAS;oBACvD,sBAAsB,EAAE,MAAM,CAAC,wBAAwB;oBACvD,gBAAgB,EAAE,MAAM,CAAC,iBAAiB,IAAI,SAAS;oBACvD,SAAS,EAAE,MAAM,CAAC,UAAU;oBAC5B,SAAS,EAAE,MAAM,CAAC,mBAAmB,IAAI,SAAS;iBACnD,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,qFAAqF;QACrF,OAAO,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;YACrC,OAAO,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAC5D,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,4CAA4C,EAAE,KAAK,CAAC,CAAC;QACnE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,iCAAiC,CACrD,EAAgC,EAChC,UAAkB;IAElB,MAAM,OAAO,GAAG,MAAM,iCAAiC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAC1E,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AACzC,CAAC;AAED,gFAAgF;AAChF,6BAA6B;AAC7B,gFAAgF;AAEhF;;;GAGG;AACI,KAAK,UAAU,wBAAwB,CAC5C,EAAgC,EAChC,UAAkB;IAElB,IAAI,CAAC;QACH,2DAA2D;QAC3D,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;KAgBlB,CAAC;QAEF,MAAM,OAAO,GAAG,MAAM,IAAA,oBAAQ,EAY3B,EAAuB,EAAE,UAAU,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;QAEtD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,iBAAiB,GAAG,OAAO,CAAC,mBAAmB,CAAC;QAEtD,mCAAmC;QACnC,MAAM,CAAC,cAAc,EAAE,SAAS,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC7F,kBAAkB;YAClB,IAAA,iBAAK,EAaH,EAAuB,EACvB;;wCAEgC,EAChC,CAAC,iBAAiB,CAAC,CACpB;YAED,YAAY;YACZ,IAAA,iBAAK,EAaH,EAAuB,EACvB;;wCAEgC,EAChC,CAAC,iBAAiB,CAAC,CACpB;YAED,iBAAiB;YACjB,IAAA,iBAAK,EAKH,EAAuB,EACvB;;wCAEgC,EAChC,CAAC,iBAAiB,CAAC,CACpB;YAED,WAAW;YACX,IAAA,iBAAK,EAMH,EAAuB,EACvB;;wCAEgC,EAChC,CAAC,iBAAiB,CAAC,CACpB;YAED,iBAAiB;YACjB,IAAA,iBAAK,EAGH,EAAuB,EACvB;;;2CAGmC,EACnC,CAAC,iBAAiB,CAAC,CACpB;SACF,CAAC,CAAC;QAEH,6BAA6B;QAC7B,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,GAAG,CACrC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAC,GAAG,EAAC,EAAE;YAC7B,MAAM,SAAS,GAAG,MAAM,IAAA,iBAAK,EAC3B,EAAuB,EACvB;;;6CAGmC,EACnC,CAAC,GAAG,CAAC,EAAE,CAAC,CACT,CAAC;YAEF,OAAO;gBACL,gBAAgB,EAAE,GAAG,CAAC,EAAE;gBACxB,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;aACrD,CAAC;QACJ,CAAC,CAAC,CACH,CAAC;QAEF,uBAAuB;QACvB,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAC,GAAG,EAAC,EAAE;YACxB,MAAM,aAAa,GAAG,MAAM,IAAA,iBAAK,EAC/B,EAAuB,EACvB;;;sCAG4B,EAC5B,CAAC,GAAG,CAAC,EAAE,CAAC,CACT,CAAC;YAEF,OAAO;gBACL,WAAW,EAAE,GAAG,CAAC,EAAE;gBACnB,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;aACzD,CAAC;QACJ,CAAC,CAAC,CACH,CAAC;QAEF,qCAAqC;QACrC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAC9B,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAChE,CAAC;QACF,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAErF,oDAAoD;QACpD,MAAM,aAAa,GAA0B;YAC3C,WAAW,EAAE,OAAO,CAAC,wBAAwB,IAAI,EAAE;YACnD,iBAAiB,EAAE,cAAc,CAAC,OAAO,CAAC,iBAAiB,CAAC;YAC5D,UAAU,EAAE,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC;YAC9C,SAAS,EAAE,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC;YAC5C,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC1C,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC;YACxC,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC1C,mBAAmB,EAAE,cAAc,CAAC,OAAO,CAAC,mBAAmB,CAAC;YAChE,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,SAAS;YACnD,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,IAAI,SAAS;YACzD,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;YAChE,eAAe,EAAE,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC1C,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAuB;gBAC5D,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC,OAAO,CAAuB;gBAC1D,UAAU,EAAE,cAAc,CAAC,GAAG,CAAC,UAAU,CAAuB;gBAChE,oBAAoB,EAAE,cAAc,CAAC,GAAG,CAAC,oBAAoB,CAAuB;gBACpF,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAuB;gBAC5D,eAAe,EAAE,cAAc,CAAC,GAAG,CAAC,eAAe,CAAuB;gBAC1E,WAAW,EAAE,cAAc,CAAC,GAAG,CAAC,WAAW,CAAuB;gBAClE,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,KAAK;gBACnC,UAAU,EAAE,cAAc,CAAC,GAAG,CAAC,UAAU,CAAuB;gBAChE,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAuB;gBAC5D,MAAM,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE;aAC3C,CAAC,CAAC;YACH,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC/B,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,MAAM,CAAuB;gBACxD,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,MAAM,CAAuB;gBACxD,SAAS,EAAE,cAAc,CAAC,GAAG,CAAC,SAAS,CAAuB;gBAC9D,cAAc,EAAE,cAAc,CAAC,GAAG,CAAC,cAAc,CAAuB;gBACxE,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,KAAK,CAAuB;gBACtD,WAAW,EAAE,cAAc,CAAC,GAAG,CAAC,WAAW,CAAuB;gBAClE,wBAAwB,EAAE,cAAc,CAAC,GAAG,CAAC,wBAAwB,CAAuB;gBAC5F,mBAAmB,EAAE,cAAc,CAAC,GAAG,CAAC,mBAAmB,CAAuB;gBAClF,UAAU,EAAE,cAAc,CAAC,GAAG,CAAC,UAAU,CAAuB;gBAChE,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAuB;gBAC5D,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE;aACvC,CAAC,CAAC;YACH,cAAc,EAAE,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC1C,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAuB;gBACrD,SAAS,EAAE,cAAc,CAAC,IAAI,CAAC,YAAY,CAAuB;gBAClE,cAAc,EAAE,SAA+B;gBAC/C,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,CAAuB;gBACnD,UAAU,EAAE,SAA+B;gBAC3C,QAAQ,EAAE,SAA+B;aAC1C,CAAC,CAAC;YACH,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACjC,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,IAAI,CAAuB;gBACzD,WAAW,EAAE,cAAc,CAAC,OAAO,CAAC,WAAW,CAAuB;gBACtE,GAAG,EAAE,SAA+B;gBACpC,UAAU,EAAE,cAAc,CAAC,OAAO,CAAC,UAAU,CAAuB;gBACpE,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAuB;aACjE,CAAC,CAAC;YACH,YAAY,EAAE,EAAE;SACjB,CAAC;QAEF,OAAO,aAAa,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE,KAAK,CAAC,CAAC;QAC/D,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,4BAA4B,CAChD,EAAgC,EAChC,iBAAyB;IAEzB,IAAI,CAAC;QACH,+DAA+D;QAC/D,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;KAgBlB,CAAC;QAEF,MAAM,OAAO,GAAG,MAAM,IAAA,oBAAQ,EAY3B,EAAuB,EAAE,UAAU,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAE7D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC;QAE9C,mCAAmC;QACnC,MAAM,CAAC,cAAc,EAAE,SAAS,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC7F,kBAAkB;YAClB,IAAA,iBAAK,EAaH,EAAuB,EACvB;;;kCAG0B,EAC1B,CAAC,SAAS,CAAC,CACZ;YAED,YAAY;YACZ,IAAA,iBAAK,EAaH,EAAuB,EACvB;;;kCAG0B,EAC1B,CAAC,SAAS,CAAC,CACZ;YAED,iBAAiB;YACjB,IAAA,iBAAK,EAMH,EAAuB,EACvB;;wCAEgC,EAChC,CAAC,SAAS,CAAC,CACZ;YAED,WAAW;YACX,IAAA,iBAAK,EAOH,EAAuB,EACvB;;;kCAG0B,EAC1B,CAAC,SAAS,CAAC,CACZ;YAED,iBAAiB;YACjB,IAAA,iBAAK,EAGH,EAAuB,EACvB;;;2CAGmC,EACnC,CAAC,SAAS,CAAC,CACZ;SACF,CAAC,CAAC;QAEH,oDAAoD;QACpD,MAAM,aAAa,GAA0B;YAC3C,WAAW,EAAE,OAAO,CAAC,wBAAwB,IAAI,EAAE;YACnD,iBAAiB,EAAE,cAAc,CAAC,OAAO,CAAC,iBAAiB,CAAC;YAC5D,UAAU,EAAE,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC;YAC9C,SAAS,EAAE,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC;YAC5C,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC1C,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC;YACxC,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC1C,mBAAmB,EAAE,cAAc,CAAC,OAAO,CAAC,mBAAmB,CAAC;YAChE,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,SAAS;YACnD,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,IAAI,SAAS;YACzD,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;YAChE,eAAe,EAAE,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC1C,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAuB;gBAC5D,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC,OAAO,CAAuB;gBAC1D,UAAU,EAAE,cAAc,CAAC,GAAG,CAAC,UAAU,CAAuB;gBAChE,oBAAoB,EAAE,cAAc,CAAC,GAAG,CAAC,oBAAoB,CAAuB;gBACpF,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAuB;gBAC5D,eAAe,EAAE,cAAc,CAAC,GAAG,CAAC,eAAe,CAAuB;gBAC1E,WAAW,EAAE,cAAc,CAAC,GAAG,CAAC,WAAW,CAAuB;gBAClE,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,KAAK;gBACnC,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,SAAS;gBACvC,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,SAAS;aACpC,CAAC,CAAC;YACH,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC/B,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,MAAM,CAAuB;gBACxD,SAAS,EAAE,cAAc,CAAC,GAAG,CAAC,SAAS,CAAuB;gBAC9D,mBAAmB,EAAE,cAAc,CAAC,GAAG,CAAC,mBAAmB,CAAuB;gBAClF,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,MAAM,CAAuB;gBACxD,cAAc,EAAE,cAAc,CAAC,GAAG,CAAC,cAAc,CAAuB;gBACxE,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,KAAK,CAAuB;gBACtD,WAAW,EAAE,cAAc,CAAC,GAAG,CAAC,WAAW,CAAuB;gBAClE,wBAAwB,EAAE,cAAc,CAAC,GAAG,CAAC,wBAAwB,CAAuB;gBAC5F,UAAU,EAAE,GAAG,CAAC,UAAU,IAAI,SAAS;gBACvC,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,SAAS;aACpC,CAAC,CAAC;YACH,cAAc,EAAE,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC1C,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAuB;gBACrD,SAAS,EAAE,cAAc,CAAC,IAAI,CAAC,YAAY,CAAuB;gBAClE,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,CAAuB;aACpD,CAAC,CAAC;YACH,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC9B,KAAK,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAuB;gBACtD,WAAW,EAAE,cAAc,CAAC,IAAI,CAAC,WAAW,CAAuB;gBACnE,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,SAAS;gBACxC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,SAAS;aACrC,CAAC,CAAC;YACH,YAAY,EAAE,EAAE;SACjB,CAAC;QAEF,OAAO,aAAa,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,8CAA8C,EAAE,KAAK,CAAC,CAAC;QACrE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,yBAAyB,CAC7C,EAAgC,EAChC,WAAqB;IAErB,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,+BAA+B;QAC/B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,wBAAwB,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CACxE,CAAC;QAEF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,yCAAyC,EAAE,KAAK,CAAC,CAAC;QAChE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF;AAEhF;;GAEG;AACH,SAAgB,qBAAqB,CAAC,OAA8B;IAClE,OAAO,CAAC,CAAC,CACP,OAAO,CAAC,UAAU;QAClB,OAAO,CAAC,SAAS;QACjB,OAAO,CAAC,QAAQ;QAChB,CAAC,OAAO,CAAC,eAAe,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAC3C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CAAC,gBAAyC;IAC3E,IAAI,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC;QAC5D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;IACnD,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IAE5C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAgB,0BAA0B,CACxC,gBAAyC,EACzC,cAAsB,EAAE;IAExB,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,CAAC,0BAA0B;IACzC,CAAC;IAED,MAAM,GAAG,GAAG,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;IAClD,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC,CAAC,qCAAqC;IACpD,CAAC;IAED,OAAO,GAAG,GAAG,WAAW,CAAC;AAC3B,CAAC"}