linkedin-automation-cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (314) hide show
  1. package/.env.example +12 -0
  2. package/.github/workflows/ci.yml +66 -0
  3. package/.github/workflows/publish.yml +48 -0
  4. package/.husky/pre-commit +6 -0
  5. package/.prettierignore +4 -0
  6. package/.prettierrc +10 -0
  7. package/AGENTS.md +294 -0
  8. package/CHANGELOG.md +40 -0
  9. package/GIT_RELEASE.md +167 -0
  10. package/LICENSE +21 -0
  11. package/Makefile +30 -0
  12. package/NPM_PUBLISHING.md +230 -0
  13. package/PYEOF +0 -0
  14. package/README.md +295 -0
  15. package/TESTING-GUIDE.md +151 -0
  16. package/cmd/linkedin/main.go +9 -0
  17. package/dist/agent/action-executor.d.ts +81 -0
  18. package/dist/agent/action-executor.d.ts.map +1 -0
  19. package/dist/agent/action-executor.js +170 -0
  20. package/dist/agent/action-executor.js.map +1 -0
  21. package/dist/agent/action-executor.test.d.ts +2 -0
  22. package/dist/agent/action-executor.test.d.ts.map +1 -0
  23. package/dist/agent/action-executor.test.js +366 -0
  24. package/dist/agent/action-executor.test.js.map +1 -0
  25. package/dist/agent/claude-client.d.ts +74 -0
  26. package/dist/agent/claude-client.d.ts.map +1 -0
  27. package/dist/agent/claude-client.js +314 -0
  28. package/dist/agent/claude-client.js.map +1 -0
  29. package/dist/agent/claude-client.test.d.ts +2 -0
  30. package/dist/agent/claude-client.test.d.ts.map +1 -0
  31. package/dist/agent/claude-client.test.js +590 -0
  32. package/dist/agent/claude-client.test.js.map +1 -0
  33. package/dist/agent/dom-extractor.d.ts +50 -0
  34. package/dist/agent/dom-extractor.d.ts.map +1 -0
  35. package/dist/agent/dom-extractor.js +374 -0
  36. package/dist/agent/dom-extractor.js.map +1 -0
  37. package/dist/agent/dom-extractor.test.d.ts +7 -0
  38. package/dist/agent/dom-extractor.test.d.ts.map +1 -0
  39. package/dist/agent/dom-extractor.test.js +504 -0
  40. package/dist/agent/dom-extractor.test.js.map +1 -0
  41. package/dist/agent/extension-client.d.ts +75 -0
  42. package/dist/agent/extension-client.d.ts.map +1 -0
  43. package/dist/agent/extension-client.js +245 -0
  44. package/dist/agent/extension-client.js.map +1 -0
  45. package/dist/agent/index.d.ts +8 -0
  46. package/dist/agent/index.d.ts.map +1 -0
  47. package/dist/agent/index.js +16 -0
  48. package/dist/agent/index.js.map +1 -0
  49. package/dist/agent/page-agent.d.ts +76 -0
  50. package/dist/agent/page-agent.d.ts.map +1 -0
  51. package/dist/agent/page-agent.js +236 -0
  52. package/dist/agent/page-agent.js.map +1 -0
  53. package/dist/agent/types.d.ts +236 -0
  54. package/dist/agent/types.d.ts.map +1 -0
  55. package/dist/agent/types.js +37 -0
  56. package/dist/agent/types.js.map +1 -0
  57. package/dist/cli/agent-commands.d.ts +3 -0
  58. package/dist/cli/agent-commands.d.ts.map +1 -0
  59. package/dist/cli/agent-commands.js +250 -0
  60. package/dist/cli/agent-commands.js.map +1 -0
  61. package/dist/cli/auth.d.ts +3 -0
  62. package/dist/cli/auth.d.ts.map +1 -0
  63. package/dist/cli/auth.js +288 -0
  64. package/dist/cli/auth.js.map +1 -0
  65. package/dist/cli/company.d.ts +3 -0
  66. package/dist/cli/company.d.ts.map +1 -0
  67. package/dist/cli/company.js +55 -0
  68. package/dist/cli/company.js.map +1 -0
  69. package/dist/cli/connection.d.ts +3 -0
  70. package/dist/cli/connection.d.ts.map +1 -0
  71. package/dist/cli/connection.js +79 -0
  72. package/dist/cli/connection.js.map +1 -0
  73. package/dist/cli/index.d.ts +7 -0
  74. package/dist/cli/index.d.ts.map +1 -0
  75. package/dist/cli/index.js +17 -0
  76. package/dist/cli/index.js.map +1 -0
  77. package/dist/cli/messages.d.ts +3 -0
  78. package/dist/cli/messages.d.ts.map +1 -0
  79. package/dist/cli/messages.js +268 -0
  80. package/dist/cli/messages.js.map +1 -0
  81. package/dist/cli/profile.d.ts +3 -0
  82. package/dist/cli/profile.d.ts.map +1 -0
  83. package/dist/cli/profile.js +81 -0
  84. package/dist/cli/profile.js.map +1 -0
  85. package/dist/cli/profile.test.d.ts +2 -0
  86. package/dist/cli/profile.test.d.ts.map +1 -0
  87. package/dist/cli/profile.test.js +15 -0
  88. package/dist/cli/profile.test.js.map +1 -0
  89. package/dist/cli/reply.d.ts +3 -0
  90. package/dist/cli/reply.d.ts.map +1 -0
  91. package/dist/cli/reply.js +129 -0
  92. package/dist/cli/reply.js.map +1 -0
  93. package/dist/core/audit.d.ts +17 -0
  94. package/dist/core/audit.d.ts.map +1 -0
  95. package/dist/core/audit.js +121 -0
  96. package/dist/core/audit.js.map +1 -0
  97. package/dist/core/audit.test.d.ts +2 -0
  98. package/dist/core/audit.test.d.ts.map +1 -0
  99. package/dist/core/audit.test.js +142 -0
  100. package/dist/core/audit.test.js.map +1 -0
  101. package/dist/core/browser-cookies.d.ts +19 -0
  102. package/dist/core/browser-cookies.d.ts.map +1 -0
  103. package/dist/core/browser-cookies.js +181 -0
  104. package/dist/core/browser-cookies.js.map +1 -0
  105. package/dist/core/browser.d.ts +50 -0
  106. package/dist/core/browser.d.ts.map +1 -0
  107. package/dist/core/browser.js +318 -0
  108. package/dist/core/browser.js.map +1 -0
  109. package/dist/core/config.d.ts +20 -0
  110. package/dist/core/config.d.ts.map +1 -0
  111. package/dist/core/config.js +103 -0
  112. package/dist/core/config.js.map +1 -0
  113. package/dist/core/config.test.d.ts +2 -0
  114. package/dist/core/config.test.d.ts.map +1 -0
  115. package/dist/core/config.test.js +111 -0
  116. package/dist/core/config.test.js.map +1 -0
  117. package/dist/core/storage.d.ts +19 -0
  118. package/dist/core/storage.d.ts.map +1 -0
  119. package/dist/core/storage.js +124 -0
  120. package/dist/core/storage.js.map +1 -0
  121. package/dist/core/storage.test.d.ts +2 -0
  122. package/dist/core/storage.test.d.ts.map +1 -0
  123. package/dist/core/storage.test.js +142 -0
  124. package/dist/core/storage.test.js.map +1 -0
  125. package/dist/index.d.ts +3 -0
  126. package/dist/index.d.ts.map +1 -0
  127. package/dist/index.js +63 -0
  128. package/dist/index.js.map +1 -0
  129. package/dist/linkedin/auth.d.ts +22 -0
  130. package/dist/linkedin/auth.d.ts.map +1 -0
  131. package/dist/linkedin/auth.js +167 -0
  132. package/dist/linkedin/auth.js.map +1 -0
  133. package/dist/linkedin/company-extractor.d.ts +36 -0
  134. package/dist/linkedin/company-extractor.d.ts.map +1 -0
  135. package/dist/linkedin/company-extractor.js +211 -0
  136. package/dist/linkedin/company-extractor.js.map +1 -0
  137. package/dist/linkedin/company-extractor.test.d.ts +2 -0
  138. package/dist/linkedin/company-extractor.test.d.ts.map +1 -0
  139. package/dist/linkedin/company-extractor.test.js +52 -0
  140. package/dist/linkedin/company-extractor.test.js.map +1 -0
  141. package/dist/linkedin/connector.d.ts +45 -0
  142. package/dist/linkedin/connector.d.ts.map +1 -0
  143. package/dist/linkedin/connector.js +245 -0
  144. package/dist/linkedin/connector.js.map +1 -0
  145. package/dist/linkedin/message-sender.d.ts +32 -0
  146. package/dist/linkedin/message-sender.d.ts.map +1 -0
  147. package/dist/linkedin/message-sender.js +112 -0
  148. package/dist/linkedin/message-sender.js.map +1 -0
  149. package/dist/linkedin/messages.d.ts +78 -0
  150. package/dist/linkedin/messages.d.ts.map +1 -0
  151. package/dist/linkedin/messages.js +745 -0
  152. package/dist/linkedin/messages.js.map +1 -0
  153. package/dist/linkedin/profile.d.ts +37 -0
  154. package/dist/linkedin/profile.d.ts.map +1 -0
  155. package/dist/linkedin/profile.js +268 -0
  156. package/dist/linkedin/profile.js.map +1 -0
  157. package/dist/linkedin/profile.test.d.ts +2 -0
  158. package/dist/linkedin/profile.test.d.ts.map +1 -0
  159. package/dist/linkedin/profile.test.js +68 -0
  160. package/dist/linkedin/profile.test.js.map +1 -0
  161. package/dist/linkedin/reply.d.ts +21 -0
  162. package/dist/linkedin/reply.d.ts.map +1 -0
  163. package/dist/linkedin/reply.js +76 -0
  164. package/dist/linkedin/reply.js.map +1 -0
  165. package/dist/linkedin/selector-engine.d.ts +69 -0
  166. package/dist/linkedin/selector-engine.d.ts.map +1 -0
  167. package/dist/linkedin/selector-engine.js +339 -0
  168. package/dist/linkedin/selector-engine.js.map +1 -0
  169. package/dist/linkedin/selector-engine.test.d.ts +2 -0
  170. package/dist/linkedin/selector-engine.test.d.ts.map +1 -0
  171. package/dist/linkedin/selector-engine.test.js +135 -0
  172. package/dist/linkedin/selector-engine.test.js.map +1 -0
  173. package/dist/linkedin/selectors.d.ts +65 -0
  174. package/dist/linkedin/selectors.d.ts.map +1 -0
  175. package/dist/linkedin/selectors.js +261 -0
  176. package/dist/linkedin/selectors.js.map +1 -0
  177. package/dist/templates/engine.d.ts +37 -0
  178. package/dist/templates/engine.d.ts.map +1 -0
  179. package/dist/templates/engine.js +215 -0
  180. package/dist/templates/engine.js.map +1 -0
  181. package/dist/templates/engine.test.d.ts +2 -0
  182. package/dist/templates/engine.test.d.ts.map +1 -0
  183. package/dist/templates/engine.test.js +212 -0
  184. package/dist/templates/engine.test.js.map +1 -0
  185. package/dist/templates/index.d.ts +2 -0
  186. package/dist/templates/index.d.ts.map +1 -0
  187. package/dist/templates/index.js +7 -0
  188. package/dist/templates/index.js.map +1 -0
  189. package/dist/types/index.d.ts +113 -0
  190. package/dist/types/index.d.ts.map +1 -0
  191. package/dist/types/index.js +3 -0
  192. package/dist/types/index.js.map +1 -0
  193. package/dist/types/index.test.d.ts +2 -0
  194. package/dist/types/index.test.d.ts.map +1 -0
  195. package/dist/types/index.test.js +90 -0
  196. package/dist/types/index.test.js.map +1 -0
  197. package/dist/utils/paths.d.ts +8 -0
  198. package/dist/utils/paths.d.ts.map +1 -0
  199. package/dist/utils/paths.js +68 -0
  200. package/dist/utils/paths.js.map +1 -0
  201. package/dist/utils/rate-limiter.d.ts +22 -0
  202. package/dist/utils/rate-limiter.d.ts.map +1 -0
  203. package/dist/utils/rate-limiter.js +57 -0
  204. package/dist/utils/rate-limiter.js.map +1 -0
  205. package/dist/utils/retry.d.ts +18 -0
  206. package/dist/utils/retry.d.ts.map +1 -0
  207. package/dist/utils/retry.js +49 -0
  208. package/dist/utils/retry.js.map +1 -0
  209. package/docs/connection-command.md +52 -0
  210. package/docs/plans/2025-03-03-linkedin-cli-design.md +280 -0
  211. package/docs/plans/2025-03-03-linkedin-cli-implementation-plan.md +2087 -0
  212. package/docs/plans/2025-03-03-linkedin-cli-implementation.md +2420 -0
  213. package/docs/plans/2026-02-19-linkedin-connection-feature.md +596 -0
  214. package/docs/plans/2026-02-28-messages-send-feature.md +480 -0
  215. package/docs/plans/2026-02-28-messages-show-design.md +243 -0
  216. package/docs/plans/2026-03-03-linkedin-cli-oss-publishing-design.md +394 -0
  217. package/docs/plans/2026-03-03-linkedin-cli-oss-publishing-plan.md +1592 -0
  218. package/docs/superpowers/plans/2026-03-13-linkedin-automation-resilience-migration.md +425 -0
  219. package/docs/superpowers/plans/2026-03-13-playwright-fara-migration.md +1112 -0
  220. package/docs/superpowers/plans/2026-03-14-page-agent-plan.md +1598 -0
  221. package/docs/superpowers/plans/2026-03-15-company-profile-extraction.md +591 -0
  222. package/docs/superpowers/plans/2026-03-15-profile-extraction-plan.md +943 -0
  223. package/docs/superpowers/specs/2026-03-14-company-profile-extraction-design.md +371 -0
  224. package/docs/superpowers/specs/2026-03-14-page-agent-design.md +385 -0
  225. package/docs/superpowers/specs/2026-03-15-profile-extraction-design.md +409 -0
  226. package/eslint.config.mjs +58 -0
  227. package/go.mod +9 -0
  228. package/go.sum +10 -0
  229. package/import-cookies.js +376 -0
  230. package/internal/cmd/actions.go +123 -0
  231. package/internal/cmd/auth.go +108 -0
  232. package/internal/cmd/connect.go +42 -0
  233. package/internal/cmd/message.go +44 -0
  234. package/internal/cmd/people.go +454 -0
  235. package/internal/cmd/profiles.go +121 -0
  236. package/internal/cmd/root.go +89 -0
  237. package/internal/cmd/sequence.go +192 -0
  238. package/internal/config/config.go +187 -0
  239. package/internal/config/config_test.go +121 -0
  240. package/internal/config/profile.go +65 -0
  241. package/internal/linkedin/navigator.go +195 -0
  242. package/internal/linkedin/selectors.go +39 -0
  243. package/internal/linkedin/validator.go +69 -0
  244. package/internal/pinchtab/client.go +183 -0
  245. package/internal/pinchtab/client_test.go +67 -0
  246. package/internal/pinchtab/types.go +50 -0
  247. package/internal/ratelimit/limiter.go +115 -0
  248. package/internal/ratelimit/limits.go +32 -0
  249. package/package.json +67 -0
  250. package/release.sh +66 -0
  251. package/scripts/debug-linkedin.js +156 -0
  252. package/scripts/debug-login.js +193 -0
  253. package/scripts/extract-from-edge.js +96 -0
  254. package/scripts/import-cookies.js +101 -0
  255. package/scripts/poc-show-data.js +205 -0
  256. package/scripts/proof-of-access.js +87 -0
  257. package/scripts/prove-connection.js +110 -0
  258. package/scripts/show-linkedin-data.js +173 -0
  259. package/src/agent/action-executor.test.ts +464 -0
  260. package/src/agent/action-executor.ts +203 -0
  261. package/src/agent/claude-client.test.ts +707 -0
  262. package/src/agent/claude-client.ts +422 -0
  263. package/src/agent/dom-extractor.test.ts +574 -0
  264. package/src/agent/dom-extractor.ts +437 -0
  265. package/src/agent/extension-client.ts +306 -0
  266. package/src/agent/index.ts +28 -0
  267. package/src/agent/page-agent.ts +292 -0
  268. package/src/agent/types.ts +288 -0
  269. package/src/cli/agent-commands.ts +274 -0
  270. package/src/cli/auth.ts +343 -0
  271. package/src/cli/company.ts +66 -0
  272. package/src/cli/connection.ts +89 -0
  273. package/src/cli/index.ts +7 -0
  274. package/src/cli/messages.ts +338 -0
  275. package/src/cli/profile.test.ts +14 -0
  276. package/src/cli/profile.ts +95 -0
  277. package/src/cli/reply.ts +110 -0
  278. package/src/core/audit.test.ts +134 -0
  279. package/src/core/audit.ts +98 -0
  280. package/src/core/browser-cookies.ts +203 -0
  281. package/src/core/browser.ts +304 -0
  282. package/src/core/config.test.ts +90 -0
  283. package/src/core/config.ts +81 -0
  284. package/src/core/storage.test.ts +129 -0
  285. package/src/core/storage.ts +100 -0
  286. package/src/index.ts +70 -0
  287. package/src/linkedin/auth.ts +218 -0
  288. package/src/linkedin/company-extractor.test.ts +58 -0
  289. package/src/linkedin/company-extractor.ts +222 -0
  290. package/src/linkedin/connector.ts +336 -0
  291. package/src/linkedin/message-sender.ts +141 -0
  292. package/src/linkedin/messages.ts +894 -0
  293. package/src/linkedin/profile.test.ts +79 -0
  294. package/src/linkedin/profile.ts +314 -0
  295. package/src/linkedin/reply.ts +96 -0
  296. package/src/linkedin/selector-engine.test.ts +167 -0
  297. package/src/linkedin/selector-engine.ts +393 -0
  298. package/src/linkedin/selectors.ts +268 -0
  299. package/src/templates/defaults/followup.txt +14 -0
  300. package/src/templates/defaults/meeting.txt +16 -0
  301. package/src/templates/defaults/welcome.txt +14 -0
  302. package/src/templates/engine.test.ts +228 -0
  303. package/src/templates/engine.ts +208 -0
  304. package/src/templates/index.ts +1 -0
  305. package/src/types/index.test.ts +94 -0
  306. package/src/types/index.ts +143 -0
  307. package/src/types/sql.js.d.ts +23 -0
  308. package/src/utils/paths.ts +33 -0
  309. package/src/utils/rate-limiter.ts +75 -0
  310. package/src/utils/retry.ts +78 -0
  311. package/test-cli.sh +85 -0
  312. package/test-real-data.sh +97 -0
  313. package/tsconfig.json +23 -0
  314. package/vitest.config.ts +35 -0
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SELECTORS = void 0;
4
+ /**
5
+ * Multi-layer selector system for LinkedIn's unstable UI
6
+ * Each selector key has multiple fallback strategies
7
+ */
8
+ exports.SELECTORS = {
9
+ // Login page
10
+ login: {
11
+ emailInput: ['input#username', 'input[name="session_key"]', 'input[type="email"]'],
12
+ passwordInput: ['input#password', 'input[name="session_password"]', 'input[type="password"]'],
13
+ submitButton: [
14
+ 'button[type="submit"]',
15
+ 'button.sign-in-form__submit-btn',
16
+ 'button:has-text("Sign in")',
17
+ ],
18
+ },
19
+ // 2FA
20
+ twoFA: {
21
+ pinInput: [
22
+ 'input#input__phone_verification_pin',
23
+ 'input[name="pin"]',
24
+ 'input[type="text"][*="pin" i]',
25
+ ],
26
+ submitButton: [
27
+ 'button[type="submit"]',
28
+ 'button:has-text("Submit")',
29
+ 'button:has-text("Verify")',
30
+ ],
31
+ },
32
+ // Navigation / logged in indicators
33
+ nav: {
34
+ globalNav: ['nav.global-nav', 'header.global-nav', '[data-testid="global-nav"]'],
35
+ profileDropdown: [
36
+ 'button[aria-label*="Settings"]',
37
+ '.global-nav__me-menu button',
38
+ '[data-testid="settings-menu-trigger"]',
39
+ ],
40
+ },
41
+ // Messaging
42
+ messages: {
43
+ conversationList: [
44
+ 'div.msg-conversations-container__conversations-list',
45
+ '[data-testid="conversations-list"]',
46
+ 'div[class*="conversations-list"]',
47
+ ],
48
+ conversationItem: [
49
+ 'div.msg-conversation-card',
50
+ '[data-testid="conversation-card"]',
51
+ 'div[class*="conversation-card"]',
52
+ ],
53
+ messageBubble: [
54
+ 'div.msg-s-message-group__message',
55
+ '[data-testid="message-bubble"]',
56
+ 'div[class*="message-bubble"]',
57
+ ],
58
+ messageInput: [
59
+ 'div.msg-form__contenteditable',
60
+ 'div[contenteditable="true"][role="textbox"]',
61
+ '[data-testid="message-input"]',
62
+ ],
63
+ sendButton: ['button.msg-form__send-btn', 'button[type="submit"]', 'button:has-text("Send")'],
64
+ },
65
+ // Connection requests
66
+ connection: {
67
+ // Primary connect button (various states)
68
+ // LinkedIn has many variants - we need comprehensive fallbacks
69
+ connectButton: [
70
+ // Aria-label variants
71
+ 'button[aria-label*="Connect"]',
72
+ 'button[aria-label*="Invite"]',
73
+ 'button[aria-label*="to connect"]',
74
+ // Text content variants
75
+ 'button:has-text("Connect")',
76
+ 'button:has-text("Invite")',
77
+ 'button:has-text("Connect ")',
78
+ // Class-based variants (LinkedIn uses artdeco classes)
79
+ 'button.artdeco-button--primary:has-text("Connect")',
80
+ 'button.artdeco-button--secondary:has-text("Connect")',
81
+ 'button.artdeco-button--primary',
82
+ 'button.artdeco-button--secondary',
83
+ // Specific profile page selectors
84
+ '.pv-top-card-v2-ctas button:has-text("Connect")',
85
+ '.profile-topcard-actions button:has-text("Connect")',
86
+ 'div.pv-top-card-v2-ctas button',
87
+ // Data test IDs
88
+ '[data-testid="connect-button"]',
89
+ '[data-testid="invite-button"]',
90
+ // Generic fallback - any button with connect-related text
91
+ 'button[id*="connect"]',
92
+ 'button[id*="invite"]',
93
+ ],
94
+ // More actions menu (three dots)
95
+ moreActionsButton: [
96
+ 'button[aria-label*="More actions"]',
97
+ 'button[aria-label*="More"]',
98
+ 'button:has-text("More")',
99
+ '.artdeco-dropdown__trigger',
100
+ 'button[data-testid="more-actions"]',
101
+ ],
102
+ // Connect option in dropdown menu
103
+ connectOptionInMenu: [
104
+ 'div[role="menuitem"]:has-text("Connect")',
105
+ 'button:has-text("Connect")',
106
+ '[role="menuitem"][aria-label*="Connect"]',
107
+ ],
108
+ // Add a note modal
109
+ addNoteButton: ['button[aria-label*="Add a note"]', 'button:has-text("Add a note")'],
110
+ noteTextarea: ['textarea[name="message"]', 'textarea[placeholder*="note"]', 'textarea'],
111
+ sendButton: [
112
+ // Aria-label variants
113
+ 'button[aria-label*="Send invitation"]',
114
+ 'button[aria-label*="Send invite"]',
115
+ 'button[aria-label="Send"]',
116
+ // Text content variants
117
+ 'button:has-text("Send")',
118
+ 'button:has-text("Send invitation")',
119
+ 'button:has-text("Send invite")',
120
+ // Modal-specific primary buttons
121
+ '.artdeco-modal button.artdeco-button--primary',
122
+ '.artdeco-modal button:has-text("Send")',
123
+ '.artdeco-modal button[type="submit"]',
124
+ // Generic modal submit
125
+ '[role="dialog"] button.artdeco-button--primary',
126
+ '[role="dialog"] button:has-text("Send")',
127
+ // Form submit in modal
128
+ 'form button[type="submit"]',
129
+ '.artdeco-modal form button.artdeco-button--primary',
130
+ // Generic fallback
131
+ 'button[type="submit"]',
132
+ '.artdeco-button--primary',
133
+ ],
134
+ },
135
+ // Company profile extraction
136
+ company: {
137
+ name: [
138
+ 'h1.text-heading-xlarge',
139
+ '.org-top-card-primary-content h1',
140
+ 'h1.org-top-card-summary__title',
141
+ ],
142
+ website: [
143
+ 'a[data-testid="website-link"]',
144
+ '.org-about-us-module__website a',
145
+ 'dd a[href^="http"]:not([href*="linkedin"])',
146
+ ],
147
+ industry: [
148
+ 'dt:has-text("Industry") + dd',
149
+ '.org-about-company-module__dl dt:has-text("Industry") + dd',
150
+ ],
151
+ company_size: [
152
+ 'dt:has-text("Company size") + dd',
153
+ 'dt:has-text("Employees") + dd',
154
+ '.org-about-company-module__dl dt:has-text("Company size") + dd',
155
+ ],
156
+ headquarters: [
157
+ 'dt:has-text("Headquarters") + dd',
158
+ '.org-about-company-module__dl dt:has-text("Headquarters") + dd',
159
+ ],
160
+ founded: [
161
+ 'dt:has-text("Founded") + dd',
162
+ '.org-about-company-module__dl dt:has-text("Founded") + dd',
163
+ ],
164
+ specialties: [
165
+ 'dt:has-text("Specialties") + dd',
166
+ '.org-about-company-module__dl dt:has-text("Specialties") + dd',
167
+ ],
168
+ type: [
169
+ 'dt:has-text("Company type") + dd',
170
+ 'dt:has-text("Type") + dd',
171
+ '.org-about-company-module__dl dt:has-text("Company type") + dd',
172
+ ],
173
+ follower_count: [
174
+ '.org-top-card-primary-content__followers-count',
175
+ '.org-top-card-module__followers-count',
176
+ 'span:has-text("followers")',
177
+ '.org-top-card-summary__followers',
178
+ ],
179
+ // Authwall dismiss button
180
+ dismissAuthwall: [
181
+ 'button[aria-label="Dismiss"]',
182
+ 'button[aria-label="Close"]',
183
+ '.artdeco-modal__dismiss',
184
+ 'button.artdeco-modal__dismiss',
185
+ ],
186
+ },
187
+ // Profile extraction
188
+ profile: {
189
+ // Top card
190
+ name: [
191
+ 'h1.text-heading-xlarge',
192
+ '[data-testid="top-card-profile-name"]',
193
+ '.pv-top-card .text-heading-xlarge',
194
+ 'section.artdeco-card h1',
195
+ ],
196
+ headline: [
197
+ '.text-body-medium',
198
+ '[data-testid="top-card-profile-headline"]',
199
+ '.pv-top-card .text-body-medium',
200
+ ],
201
+ location: [
202
+ '.text-body-small.inline.t-black--light',
203
+ '[data-testid="top-card-profile-location"]',
204
+ '.pv-top-card .text-body-small',
205
+ ],
206
+ // Experience section - find by heading text pattern
207
+ experienceSection: [
208
+ 'section:has(h2:has-text("Experience"))',
209
+ 'section[data-view-name="profile-card-experience"]',
210
+ 'section[id*="experience"]',
211
+ ],
212
+ experienceList: [
213
+ 'li[data-view-name="profile-component-entity"]',
214
+ 'section:has(h2:has-text("Experience")) li',
215
+ '.pvs-list__item',
216
+ ],
217
+ // Title: First .t-bold span in each experience item
218
+ experienceTitle: [
219
+ '.t-bold span[aria-hidden="true"]',
220
+ '.hoverable-link-text span[aria-hidden="true"]',
221
+ '.display-flex.align-items-center.t-bold span',
222
+ ],
223
+ // Company: First .t-14.t-normal span (after title)
224
+ experienceCompany: ['.t-14.t-normal span[aria-hidden="true"]', 'span[class*="t-14"]'],
225
+ // Duration: caption wrapper contains "X yrs Y mos"
226
+ experienceDuration: [
227
+ '.pvs-entity__caption-wrapper',
228
+ '.t-14.t-black--light span[aria-hidden="true"]',
229
+ 'span[class*="caption"]',
230
+ ],
231
+ companyLink: ['a[data-field="experience_company_logo"]', 'a[href*="/company/"]'],
232
+ // Contact info
233
+ contactInfoButton: [
234
+ 'a[href*="contact-info"]',
235
+ 'button[aria-label*="contact info" i]',
236
+ '[data-control-name="contact_see_more"]',
237
+ ],
238
+ contactInfoPanel: [
239
+ '.pv-contact-info',
240
+ '[data-testid="contact-info-panel"]',
241
+ '.artdeco-modal__content',
242
+ ],
243
+ contactInfoCloseButton: [
244
+ '.artdeco-modal__dismiss',
245
+ 'button[aria-label*="Dismiss"]',
246
+ 'button[aria-label*="Close"]',
247
+ '[data-testid="modal-close"]',
248
+ ],
249
+ email: [
250
+ 'a[href^="mailto:"]',
251
+ '[data-testid="contact-email"]',
252
+ '.pv-contact-info__contact-type[href*="mailto"]',
253
+ ],
254
+ phone: [
255
+ 'a[href^="tel:"]',
256
+ '[data-testid="contact-phone"]',
257
+ '.pv-contact-info__contact-type[href*="tel"]',
258
+ ],
259
+ },
260
+ };
261
+ //# sourceMappingURL=selectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectors.js","sourceRoot":"","sources":["../../src/linkedin/selectors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { Template } from '../types';
2
+ export interface RenderOptions {
3
+ variables: Record<string, string>;
4
+ fallback?: string;
5
+ }
6
+ export declare class TemplateEngine {
7
+ private defaultsDir;
8
+ private customDir;
9
+ constructor();
10
+ private ensureDirectories;
11
+ /**
12
+ * Load a template by ID
13
+ */
14
+ load(templateId: string): Template | null;
15
+ /**
16
+ * Parse a template file into a Template object
17
+ */
18
+ private parseTemplate;
19
+ /**
20
+ * Save a custom template
21
+ */
22
+ save(template: Template): void;
23
+ /**
24
+ * Delete a custom template
25
+ */
26
+ delete(templateId: string): boolean;
27
+ /**
28
+ * List all available templates
29
+ */
30
+ list(): Template[];
31
+ /**
32
+ * Render a template with variables
33
+ */
34
+ render(templateId: string, options: RenderOptions): string;
35
+ }
36
+ export declare function getTemplateEngine(): TemplateEngine;
37
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/templates/engine.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;;IAQ1B,OAAO,CAAC,iBAAiB;IASzB;;OAEG;IACH,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAgBzC;;OAEG;IACH,OAAO,CAAC,aAAa;IAwDrB;;OAEG;IACH,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAe9B;;OAEG;IACH,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IASnC;;OAEG;IACH,IAAI,IAAI,QAAQ,EAAE;IAiClB;;OAEG;IACH,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM;CAqB3D;AAKD,wBAAgB,iBAAiB,IAAI,cAAc,CAKlD"}
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.TemplateEngine = void 0;
37
+ exports.getTemplateEngine = getTemplateEngine;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const paths_1 = require("../utils/paths");
41
+ class TemplateEngine {
42
+ defaultsDir;
43
+ customDir;
44
+ constructor() {
45
+ this.defaultsDir = (0, paths_1.getDefaultsDir)();
46
+ this.customDir = (0, paths_1.getCustomDir)();
47
+ this.ensureDirectories();
48
+ }
49
+ ensureDirectories() {
50
+ if (!fs.existsSync(this.defaultsDir)) {
51
+ fs.mkdirSync(this.defaultsDir, { recursive: true });
52
+ }
53
+ if (!fs.existsSync(this.customDir)) {
54
+ fs.mkdirSync(this.customDir, { recursive: true });
55
+ }
56
+ }
57
+ /**
58
+ * Load a template by ID
59
+ */
60
+ load(templateId) {
61
+ // Try custom templates first (user overrides)
62
+ const customPath = path.join(this.customDir, `${templateId}.txt`);
63
+ if (fs.existsSync(customPath)) {
64
+ return this.parseTemplate(templateId, customPath);
65
+ }
66
+ // Fall back to defaults
67
+ const defaultPath = path.join(this.defaultsDir, `${templateId}.txt`);
68
+ if (fs.existsSync(defaultPath)) {
69
+ return this.parseTemplate(templateId, defaultPath);
70
+ }
71
+ return null;
72
+ }
73
+ /**
74
+ * Parse a template file into a Template object
75
+ */
76
+ parseTemplate(id, filePath) {
77
+ const content = fs.readFileSync(filePath, 'utf8');
78
+ const lines = content.split('\n');
79
+ // Parse frontmatter if present
80
+ let name = id;
81
+ let description = '';
82
+ let category = 'custom';
83
+ let variables = [];
84
+ let templateContent = content;
85
+ if (lines[0] === '---') {
86
+ const endIndex = lines.indexOf('---', 1);
87
+ if (endIndex !== -1) {
88
+ const frontmatter = lines.slice(1, endIndex).join('\n');
89
+ templateContent = lines.slice(endIndex + 1).join('\n');
90
+ // Parse YAML-like frontmatter
91
+ for (const line of frontmatter.split('\n')) {
92
+ const match = line.match(/^(\w+):\s*(.+)$/);
93
+ if (match) {
94
+ const [, key, value] = match;
95
+ switch (key) {
96
+ case 'name':
97
+ name = value;
98
+ break;
99
+ case 'description':
100
+ description = value;
101
+ break;
102
+ case 'category':
103
+ if (['welcome', 'followup', 'meeting', 'custom'].includes(value)) {
104
+ category = value;
105
+ }
106
+ break;
107
+ }
108
+ }
109
+ }
110
+ }
111
+ }
112
+ // Extract variables from template content
113
+ const variableMatches = templateContent.match(/\{\{(\w+)\}\}/g);
114
+ if (variableMatches) {
115
+ variables = [...new Set(variableMatches.map((m) => m.replace(/[\{\}]/g, '')))];
116
+ }
117
+ return {
118
+ id,
119
+ name,
120
+ description,
121
+ content: templateContent.trim(),
122
+ variables,
123
+ category,
124
+ };
125
+ }
126
+ /**
127
+ * Save a custom template
128
+ */
129
+ save(template) {
130
+ const filePath = path.join(this.customDir, `${template.id}.txt`);
131
+ const frontmatter = [
132
+ '---',
133
+ `name: ${template.name}`,
134
+ `description: ${template.description}`,
135
+ `category: ${template.category}`,
136
+ '---',
137
+ ].join('\n');
138
+ const content = `${frontmatter}\n\n${template.content}`;
139
+ fs.writeFileSync(filePath, content);
140
+ }
141
+ /**
142
+ * Delete a custom template
143
+ */
144
+ delete(templateId) {
145
+ const customPath = path.join(this.customDir, `${templateId}.txt`);
146
+ if (fs.existsSync(customPath)) {
147
+ fs.unlinkSync(customPath);
148
+ return true;
149
+ }
150
+ return false;
151
+ }
152
+ /**
153
+ * List all available templates
154
+ */
155
+ list() {
156
+ const templates = [];
157
+ // Load defaults
158
+ if (fs.existsSync(this.defaultsDir)) {
159
+ const defaultFiles = fs.readdirSync(this.defaultsDir).filter((f) => f.endsWith('.txt'));
160
+ for (const file of defaultFiles) {
161
+ const id = path.basename(file, '.txt');
162
+ const template = this.load(id);
163
+ if (template)
164
+ templates.push(template);
165
+ }
166
+ }
167
+ // Load customs (may override defaults)
168
+ if (fs.existsSync(this.customDir)) {
169
+ const customFiles = fs.readdirSync(this.customDir).filter((f) => f.endsWith('.txt'));
170
+ for (const file of customFiles) {
171
+ const id = path.basename(file, '.txt');
172
+ const template = this.load(id);
173
+ if (template) {
174
+ // Remove default if exists
175
+ const existingIndex = templates.findIndex((t) => t.id === id);
176
+ if (existingIndex !== -1) {
177
+ templates.splice(existingIndex, 1);
178
+ }
179
+ templates.push(template);
180
+ }
181
+ }
182
+ }
183
+ return templates;
184
+ }
185
+ /**
186
+ * Render a template with variables
187
+ */
188
+ render(templateId, options) {
189
+ const template = this.load(templateId);
190
+ if (!template) {
191
+ throw new Error(`Template "${templateId}" not found`);
192
+ }
193
+ let content = template.content;
194
+ // Replace variables
195
+ for (const [key, value] of Object.entries(options.variables)) {
196
+ const regex = new RegExp(`\\{\\{\\s*${key}\\s*\\}\\}`, 'g');
197
+ content = content.replace(regex, value);
198
+ }
199
+ // Handle missing variables
200
+ if (options.fallback !== undefined) {
201
+ content = content.replace(/\{\{\s*\w+\s*\}\}/g, options.fallback);
202
+ }
203
+ return content;
204
+ }
205
+ }
206
+ exports.TemplateEngine = TemplateEngine;
207
+ // Singleton instance
208
+ let templateEngine = null;
209
+ function getTemplateEngine() {
210
+ if (!templateEngine) {
211
+ templateEngine = new TemplateEngine();
212
+ }
213
+ return templateEngine;
214
+ }
215
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/templates/engine.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0MA,8CAKC;AA/MD,uCAAyB;AACzB,2CAA6B;AAC7B,0CAA8D;AAQ9D,MAAa,cAAc;IACjB,WAAW,CAAS;IACpB,SAAS,CAAS;IAE1B;QACE,IAAI,CAAC,WAAW,GAAG,IAAA,sBAAc,GAAE,CAAC;QACpC,IAAI,CAAC,SAAS,GAAG,IAAA,oBAAY,GAAE,CAAC;QAChC,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3B,CAAC;IAEO,iBAAiB;QACvB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YACrC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACnC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,UAAkB;QACrB,8CAA8C;QAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,UAAU,MAAM,CAAC,CAAC;QAClE,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QACpD,CAAC;QAED,wBAAwB;QACxB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,UAAU,MAAM,CAAC,CAAC;QACrE,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QACrD,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACK,aAAa,CAAC,EAAU,EAAE,QAAgB;QAChD,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAElC,+BAA+B;QAC/B,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,IAAI,WAAW,GAAG,EAAE,CAAC;QACrB,IAAI,QAAQ,GAAyB,QAAQ,CAAC;QAC9C,IAAI,SAAS,GAAa,EAAE,CAAC;QAC7B,IAAI,eAAe,GAAG,OAAO,CAAC;QAE9B,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;YACvB,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACzC,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;gBACpB,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACxD,eAAe,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAEvD,8BAA8B;gBAC9B,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;oBAC5C,IAAI,KAAK,EAAE,CAAC;wBACV,MAAM,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC;wBAC7B,QAAQ,GAAG,EAAE,CAAC;4BACZ,KAAK,MAAM;gCACT,IAAI,GAAG,KAAK,CAAC;gCACb,MAAM;4BACR,KAAK,aAAa;gCAChB,WAAW,GAAG,KAAK,CAAC;gCACpB,MAAM;4BACR,KAAK,UAAU;gCACb,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;oCACjE,QAAQ,GAAG,KAA6B,CAAC;gCAC3C,CAAC;gCACD,MAAM;wBACV,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,0CAA0C;QAC1C,MAAM,eAAe,GAAG,eAAe,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAChE,IAAI,eAAe,EAAE,CAAC;YACpB,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,CAAC;QAED,OAAO;YACL,EAAE;YACF,IAAI;YACJ,WAAW;YACX,OAAO,EAAE,eAAe,CAAC,IAAI,EAAE;YAC/B,SAAS;YACT,QAAQ;SACT,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,QAAkB;QACrB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;QAEjE,MAAM,WAAW,GAAG;YAClB,KAAK;YACL,SAAS,QAAQ,CAAC,IAAI,EAAE;YACxB,gBAAgB,QAAQ,CAAC,WAAW,EAAE;YACtC,aAAa,QAAQ,CAAC,QAAQ,EAAE;YAChC,KAAK;SACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,OAAO,GAAG,GAAG,WAAW,OAAO,QAAQ,CAAC,OAAO,EAAE,CAAC;QACxD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,UAAkB;QACvB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,UAAU,MAAM,CAAC,CAAC;QAClE,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,IAAI;QACF,MAAM,SAAS,GAAe,EAAE,CAAC;QAEjC,gBAAgB;QAChB,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YACpC,MAAM,YAAY,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YACxF,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;gBAChC,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC/B,IAAI,QAAQ;oBAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAED,uCAAuC;QACvC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAClC,MAAM,WAAW,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YACrF,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;gBAC/B,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC/B,IAAI,QAAQ,EAAE,CAAC;oBACb,2BAA2B;oBAC3B,MAAM,aAAa,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;oBAC9D,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE,CAAC;wBACzB,SAAS,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;oBACrC,CAAC;oBACD,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC3B,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,UAAkB,EAAE,OAAsB;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,aAAa,UAAU,aAAa,CAAC,CAAC;QACxD,CAAC;QAED,IAAI,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;QAE/B,oBAAoB;QACpB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7D,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,aAAa,GAAG,YAAY,EAAE,GAAG,CAAC,CAAC;YAC5D,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QAED,2BAA2B;QAC3B,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACnC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QACpE,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AA3LD,wCA2LC;AAED,qBAAqB;AACrB,IAAI,cAAc,GAA0B,IAAI,CAAC;AAEjD,SAAgB,iBAAiB;IAC/B,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC;IACxC,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=engine.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.test.d.ts","sourceRoot":"","sources":["../../src/templates/engine.test.ts"],"names":[],"mappings":""}