openplanter 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/investigation-tools/asic-officer-lookup.d.ts +7 -4
- package/dist/investigation-tools/asic-officer-lookup.d.ts.map +1 -1
- package/dist/investigation-tools/asic-officer-lookup.js +84 -24
- package/dist/investigation-tools/asic-officer-lookup.js.map +1 -1
- package/dist/investigation-tools/asx-reddit-scraper.d.ts +43 -0
- package/dist/investigation-tools/asx-reddit-scraper.d.ts.map +1 -0
- package/dist/investigation-tools/asx-reddit-scraper.js +215 -0
- package/dist/investigation-tools/asx-reddit-scraper.js.map +1 -0
- package/dist/investigation-tools/index.d.ts +5 -0
- package/dist/investigation-tools/index.d.ts.map +1 -1
- package/dist/investigation-tools/index.js +5 -0
- package/dist/investigation-tools/index.js.map +1 -1
- package/dist/investigation-tools/listcorp-scraper.d.ts +41 -0
- package/dist/investigation-tools/listcorp-scraper.d.ts.map +1 -0
- package/dist/investigation-tools/listcorp-scraper.js +204 -0
- package/dist/investigation-tools/listcorp-scraper.js.map +1 -0
- package/dist/investigation-tools/seeking-alpha-asx-scraper.d.ts +46 -0
- package/dist/investigation-tools/seeking-alpha-asx-scraper.d.ts.map +1 -0
- package/dist/investigation-tools/seeking-alpha-asx-scraper.js +184 -0
- package/dist/investigation-tools/seeking-alpha-asx-scraper.js.map +1 -0
- package/dist/investigation-tools/tool-registry.d.ts.map +1 -1
- package/dist/investigation-tools/tool-registry.js +56 -0
- package/dist/investigation-tools/tool-registry.js.map +1 -1
- package/dist/investigation-tools/universal-forum-scraper.d.ts +44 -0
- package/dist/investigation-tools/universal-forum-scraper.d.ts.map +1 -0
- package/dist/investigation-tools/universal-forum-scraper.js +175 -0
- package/dist/investigation-tools/universal-forum-scraper.js.map +1 -0
- package/dist/investigation-tools/yahoo-finance-au-scraper.d.ts +33 -0
- package/dist/investigation-tools/yahoo-finance-au-scraper.d.ts.map +1 -0
- package/dist/investigation-tools/yahoo-finance-au-scraper.js +211 -0
- package/dist/investigation-tools/yahoo-finance-au-scraper.js.map +1 -0
- package/dist/tool-defs.d.ts.map +1 -1
- package/dist/tool-defs.js +197 -0
- package/dist/tool-defs.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -371,6 +371,7 @@ All engine parameters can be configured via environment variables with the `OPEN
|
|
|
371
371
|
| `OPENPLANTER_CMD_TIMEOUT` | `45` | Shell command timeout (seconds) |
|
|
372
372
|
| `OPENPLANTER_RECURSIVE` | `true` | Enable recursive mode |
|
|
373
373
|
| `OPENPLANTER_DEMO` | `false` | Censor entity names |
|
|
374
|
+
| `OPENPLANTER_ABR_GUID` | _(none)_ | ABR API GUID for ASIC officer lookups (register at https://abr.business.gov.au) |
|
|
374
375
|
| `OPENPLANTER_MAX_OBS_CHARS` | `6000` | Max observation characters |
|
|
375
376
|
| `OPENPLANTER_MAX_FILES` | `400` | Max files listed |
|
|
376
377
|
| `OPENPLANTER_MAX_FILE_CHARS` | `20000` | Max file read characters |
|
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Data sources:
|
|
6
6
|
* - ASIC Connect Registry Search:
|
|
7
|
-
* https://
|
|
7
|
+
* https://asicconnect.asic.gov.au/public/
|
|
8
|
+
* (fallback: https://connectonline.asic.gov.au/RegistrySearch/)
|
|
8
9
|
* - Australian Business Register (ABR) JSON API:
|
|
9
|
-
* https://abr.business.gov.au/json/AbnDetails.aspx?abn=XXX&callback=callback
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* https://abr.business.gov.au/json/AbnDetails.aspx?abn=XXX&guid=YYY&callback=callback
|
|
11
|
+
* Requires ABR_GUID env var — register at https://abr.business.gov.au
|
|
12
|
+
* - ASX Markit Digital Company Header API:
|
|
13
|
+
* https://asx.api.markitdigital.com/asx-research/1.0/companies/{ticker}/header
|
|
12
14
|
*/
|
|
13
15
|
export interface AsxCompanyInfo {
|
|
14
16
|
name_full?: string;
|
|
@@ -23,6 +25,7 @@ export interface AbrData {
|
|
|
23
25
|
BusinessName?: Array<string | {
|
|
24
26
|
Value?: string;
|
|
25
27
|
}>;
|
|
28
|
+
Message?: string;
|
|
26
29
|
[key: string]: unknown;
|
|
27
30
|
}
|
|
28
31
|
export interface OfficerRecord {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asic-officer-lookup.d.ts","sourceRoot":"","sources":["../../src/investigation-tools/asic-officer-lookup.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"asic-officer-lookup.d.ts","sourceRoot":"","sources":["../../src/investigation-tools/asic-officer-lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAgCH,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,OAAO;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAwBD,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,MAAsB,GAC5B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAsBhC;AAYD,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,MAAM,EACX,KAAK,GAAE,MAAsB,GAC5B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAsCzB;AAuBD,wBAAsB,SAAS,CAC7B,WAAW,EAAE,MAAM,EACnB,KAAK,GAAE,MAAsB,GAC5B,OAAO,CAAC,aAAa,EAAE,CAAC,CA6E1B;AAID,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,UAAU,GAAE,MAA4B,GACvC,OAAO,CAAC,aAAa,EAAE,CAAC,CA0F1B"}
|
|
@@ -4,18 +4,22 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Data sources:
|
|
6
6
|
* - ASIC Connect Registry Search:
|
|
7
|
-
* https://
|
|
7
|
+
* https://asicconnect.asic.gov.au/public/
|
|
8
|
+
* (fallback: https://connectonline.asic.gov.au/RegistrySearch/)
|
|
8
9
|
* - Australian Business Register (ABR) JSON API:
|
|
9
|
-
* https://abr.business.gov.au/json/AbnDetails.aspx?abn=XXX&callback=callback
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* https://abr.business.gov.au/json/AbnDetails.aspx?abn=XXX&guid=YYY&callback=callback
|
|
11
|
+
* Requires ABR_GUID env var — register at https://abr.business.gov.au
|
|
12
|
+
* - ASX Markit Digital Company Header API:
|
|
13
|
+
* https://asx.api.markitdigital.com/asx-research/1.0/companies/{ticker}/header
|
|
12
14
|
*/
|
|
13
|
-
import { fetchHtml, fetchWithDelay, fetchJson, cleanAbn, formatAbn, sleep, } from "./shared.js";
|
|
15
|
+
import { fetchHtml, fetchWithDelay, fetchJson, cleanAbn, formatAbn, sleep, DEFAULT_USER_AGENT, } from "./shared.js";
|
|
14
16
|
// ── Constants ────────────────────────────────────────────────────
|
|
15
|
-
const
|
|
16
|
-
"
|
|
17
|
+
const ASIC_SEARCH_URLS = [
|
|
18
|
+
"https://asicconnect.asic.gov.au/public/",
|
|
19
|
+
"https://connectonline.asic.gov.au/RegistrySearch/faces/landing/SearchRegisters.jspx",
|
|
20
|
+
];
|
|
17
21
|
const ABR_API_URL = "https://abr.business.gov.au/json/AbnDetails.aspx";
|
|
18
|
-
const
|
|
22
|
+
const ASX_MARKIT_HEADER_URL = "https://asx.api.markitdigital.com/asx-research/1.0/companies/{ticker}/header";
|
|
19
23
|
const DEFAULT_MAX_RESULTS = 20;
|
|
20
24
|
const DEFAULT_DELAY = 1.0;
|
|
21
25
|
// ── Helpers ──────────────────────────────────────────────────────
|
|
@@ -23,11 +27,24 @@ function isAbnInput(value) {
|
|
|
23
27
|
const digits = value.replace(/\D/g, "");
|
|
24
28
|
return digits.length === 11;
|
|
25
29
|
}
|
|
26
|
-
// ── ASX company info lookup ──────────────────────────────────────
|
|
27
30
|
export async function resolveTicker(ticker, delay = DEFAULT_DELAY) {
|
|
28
|
-
const url =
|
|
31
|
+
const url = ASX_MARKIT_HEADER_URL.replace("{ticker}", ticker.toUpperCase());
|
|
29
32
|
try {
|
|
30
|
-
|
|
33
|
+
const resp = await fetchJson(url, {
|
|
34
|
+
delay,
|
|
35
|
+
userAgent: DEFAULT_USER_AGENT,
|
|
36
|
+
});
|
|
37
|
+
const d = resp.data;
|
|
38
|
+
if (!d)
|
|
39
|
+
return null;
|
|
40
|
+
return {
|
|
41
|
+
name_full: d.displayName ?? undefined,
|
|
42
|
+
name_short: d.symbol ?? undefined,
|
|
43
|
+
industry_group_name: d.industryGroup ?? d.sector ?? undefined,
|
|
44
|
+
listing_date: d.dateListed ?? undefined,
|
|
45
|
+
market_cap: d.marketCap,
|
|
46
|
+
security_type: d.securityType,
|
|
47
|
+
};
|
|
31
48
|
}
|
|
32
49
|
catch (err) {
|
|
33
50
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -36,21 +53,39 @@ export async function resolveTicker(ticker, delay = DEFAULT_DELAY) {
|
|
|
36
53
|
}
|
|
37
54
|
}
|
|
38
55
|
// ── ABR API lookup ───────────────────────────────────────────────
|
|
56
|
+
function getAbrGuid() {
|
|
57
|
+
return (process.env["OPENPLANTER_ABR_GUID"] ??
|
|
58
|
+
process.env["ABR_GUID"] ??
|
|
59
|
+
null);
|
|
60
|
+
}
|
|
39
61
|
export async function queryAbr(abn, delay = DEFAULT_DELAY) {
|
|
62
|
+
const guid = getAbrGuid();
|
|
63
|
+
if (!guid) {
|
|
64
|
+
console.error("[WARN] ABR lookup skipped: no ABR_GUID configured. " +
|
|
65
|
+
"Register at https://abr.business.gov.au to obtain a GUID, " +
|
|
66
|
+
"then set ABR_GUID or OPENPLANTER_ABR_GUID env var.");
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
40
69
|
const clean = cleanAbn(abn);
|
|
41
|
-
const url = `${ABR_API_URL}?abn=${clean}&callback=callback`;
|
|
70
|
+
const url = `${ABR_API_URL}?abn=${clean}&guid=${encodeURIComponent(guid)}&callback=callback`;
|
|
42
71
|
try {
|
|
43
72
|
const resp = await fetchWithDelay(url, { delay });
|
|
44
73
|
if (!resp.ok) {
|
|
45
74
|
throw new Error(`HTTP ${resp.status}`);
|
|
46
75
|
}
|
|
47
76
|
const text = (await resp.text()).trim();
|
|
48
|
-
// Strip JSONP wrapper: callback({...})
|
|
49
77
|
const match = text.match(/^callback\((.+)\)\s*$/s);
|
|
50
|
-
if (match)
|
|
51
|
-
return
|
|
78
|
+
if (!match)
|
|
79
|
+
return null;
|
|
80
|
+
const data = JSON.parse(match[1]);
|
|
81
|
+
if (data.Message && !data.Abn) {
|
|
82
|
+
console.error(`[WARN] ABR API error for ABN ${clean}: ${data.Message}`);
|
|
83
|
+
return null;
|
|
52
84
|
}
|
|
53
|
-
|
|
85
|
+
if (!data.EntityName && !data.Abn) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
return data;
|
|
54
89
|
}
|
|
55
90
|
catch (err) {
|
|
56
91
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -59,33 +94,58 @@ export async function queryAbr(abn, delay = DEFAULT_DELAY) {
|
|
|
59
94
|
}
|
|
60
95
|
}
|
|
61
96
|
// ── ASIC Connect scraping (best-effort) ──────────────────────────
|
|
97
|
+
async function tryAsicUrl(url, delay) {
|
|
98
|
+
try {
|
|
99
|
+
const ch = await fetchHtml(url, { delay });
|
|
100
|
+
const title = ch("title").text().trim().toLowerCase();
|
|
101
|
+
if (title.includes("service availability") || title.includes("maintenance")) {
|
|
102
|
+
console.error(`[WARN] ASIC Connect at ${url} is showing a maintenance page.`);
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
return { ch, url };
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
62
111
|
export async function queryAsic(_searchTerm, delay = DEFAULT_DELAY) {
|
|
63
112
|
const officers = [];
|
|
64
113
|
try {
|
|
65
|
-
|
|
66
|
-
const
|
|
114
|
+
let page = null;
|
|
115
|
+
for (const url of ASIC_SEARCH_URLS) {
|
|
116
|
+
page = await tryAsicUrl(url, delay);
|
|
117
|
+
if (page)
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
if (!page) {
|
|
121
|
+
console.error("[WARN] ASIC Connect is unavailable (all endpoints returned " +
|
|
122
|
+
"maintenance pages). Officer scraping skipped.");
|
|
123
|
+
return officers;
|
|
124
|
+
}
|
|
125
|
+
const { ch, url: activeUrl } = page;
|
|
67
126
|
const viewstateTag = ch('input[name="javax.faces.ViewState"]');
|
|
68
127
|
if (!viewstateTag.length) {
|
|
69
|
-
console.error("[WARN] ASIC Connect: could not locate ViewState
|
|
128
|
+
console.error("[WARN] ASIC Connect: could not locate ViewState on " +
|
|
129
|
+
activeUrl + " – page structure may have changed.");
|
|
70
130
|
return officers;
|
|
71
131
|
}
|
|
72
132
|
const viewstate = viewstateTag.attr("value") ?? "";
|
|
73
|
-
// Step 2: POST a search form submission
|
|
74
|
-
// ASIC Connect form IDs change frequently; this is best-effort.
|
|
75
133
|
const formData = new URLSearchParams({
|
|
76
134
|
"javax.faces.ViewState": viewstate,
|
|
77
135
|
"javax.faces.partial.ajax": "true",
|
|
78
136
|
});
|
|
79
137
|
await sleep(delay * 1000);
|
|
80
|
-
const searchResp = await fetch(
|
|
138
|
+
const searchResp = await fetch(activeUrl, {
|
|
81
139
|
method: "POST",
|
|
82
|
-
headers: {
|
|
140
|
+
headers: {
|
|
141
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
142
|
+
"User-Agent": DEFAULT_USER_AGENT,
|
|
143
|
+
},
|
|
83
144
|
body: formData.toString(),
|
|
84
145
|
});
|
|
85
146
|
if (!searchResp.ok) {
|
|
86
147
|
throw new Error(`HTTP ${searchResp.status}`);
|
|
87
148
|
}
|
|
88
|
-
// Step 3: Parse officer table from results
|
|
89
149
|
const cheerio = await import("cheerio");
|
|
90
150
|
const resultHtml = await searchResp.text();
|
|
91
151
|
const result$ = cheerio.load(resultHtml);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asic-officer-lookup.js","sourceRoot":"","sources":["../../src/investigation-tools/asic-officer-lookup.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"asic-officer-lookup.js","sourceRoot":"","sources":["../../src/investigation-tools/asic-officer-lookup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* asx-reddit-scraper.ts — Australian Finance Reddit Scraper
|
|
3
|
+
*
|
|
4
|
+
* Scrapes r/ASX_Bets, r/AusFinance, r/AusStocks and other Australian
|
|
5
|
+
* finance subreddits for ASX ticker mentions. Extracts sentiment, rumor
|
|
6
|
+
* flags, and pre-announcement timing signals.
|
|
7
|
+
*
|
|
8
|
+
* Uses Reddit's public JSON endpoints (no API key required).
|
|
9
|
+
*/
|
|
10
|
+
export interface RedditPostRecord {
|
|
11
|
+
post_id: string;
|
|
12
|
+
date: string;
|
|
13
|
+
subreddit: string;
|
|
14
|
+
author: string;
|
|
15
|
+
title: string;
|
|
16
|
+
text_snip: string;
|
|
17
|
+
sentiment_score: number;
|
|
18
|
+
sentiment_label: string;
|
|
19
|
+
rumor_score: number;
|
|
20
|
+
pre_ann_flag: boolean;
|
|
21
|
+
url: string;
|
|
22
|
+
score: number;
|
|
23
|
+
num_comments: number;
|
|
24
|
+
}
|
|
25
|
+
export interface AsxRedditResult {
|
|
26
|
+
ticker: string;
|
|
27
|
+
scraped_at: string;
|
|
28
|
+
subreddits: string[];
|
|
29
|
+
period_days: number;
|
|
30
|
+
total_posts: number;
|
|
31
|
+
posts: RedditPostRecord[];
|
|
32
|
+
overall_sentiment: number;
|
|
33
|
+
rumor_count: number;
|
|
34
|
+
pre_ann_count: number;
|
|
35
|
+
}
|
|
36
|
+
export declare function scrapeAsxReddit(opts: {
|
|
37
|
+
ticker: string;
|
|
38
|
+
subreddits?: string[];
|
|
39
|
+
days?: number;
|
|
40
|
+
keywords?: string[];
|
|
41
|
+
}): Promise<AsxRedditResult>;
|
|
42
|
+
export declare function sampleData(ticker: string): AsxRedditResult;
|
|
43
|
+
//# sourceMappingURL=asx-reddit-scraper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asx-reddit-scraper.d.ts","sourceRoot":"","sources":["../../src/investigation-tools/asx-reddit-scraper.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuCH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAqID,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB,GAAG,OAAO,CAAC,eAAe,CAAC,CAgD3B;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CA2D1D"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* asx-reddit-scraper.ts — Australian Finance Reddit Scraper
|
|
3
|
+
*
|
|
4
|
+
* Scrapes r/ASX_Bets, r/AusFinance, r/AusStocks and other Australian
|
|
5
|
+
* finance subreddits for ASX ticker mentions. Extracts sentiment, rumor
|
|
6
|
+
* flags, and pre-announcement timing signals.
|
|
7
|
+
*
|
|
8
|
+
* Uses Reddit's public JSON endpoints (no API key required).
|
|
9
|
+
*/
|
|
10
|
+
import { fetchWithDelay, sentimentScore, sentimentLabel, isRumor, isoNow, normalizeTicker, DEFAULT_USER_AGENT, } from "./shared.js";
|
|
11
|
+
// ── Constants ────────────────────────────────────────────────────
|
|
12
|
+
const REDDIT_SEARCH_JSON = "https://old.reddit.com/r/{subreddit}/search.json?q={query}&sort=new&restrict_sr=1&t=month&limit=100";
|
|
13
|
+
const DEFAULT_SUBREDDITS = ["ASX_Bets", "AusFinance", "AusStocks"];
|
|
14
|
+
const DEFAULT_RUMOR_KEYWORDS = ["leak", "insider", "before ASX", "ptt"];
|
|
15
|
+
const PRE_ANN_KEYWORDS = [
|
|
16
|
+
"before asx",
|
|
17
|
+
"before open",
|
|
18
|
+
"before ann",
|
|
19
|
+
"pre-ann",
|
|
20
|
+
"pre ann",
|
|
21
|
+
"pending announcement",
|
|
22
|
+
"about to drop",
|
|
23
|
+
"imminent",
|
|
24
|
+
"tomorrow morning",
|
|
25
|
+
"before market",
|
|
26
|
+
];
|
|
27
|
+
const MAX_TEXT_SNIP = 400;
|
|
28
|
+
const REQUEST_DELAY_S = 2.0;
|
|
29
|
+
// ── Helpers ──────────────────────────────────────────────────────
|
|
30
|
+
function truncate(text, maxLen = MAX_TEXT_SNIP) {
|
|
31
|
+
if (text.length <= maxLen)
|
|
32
|
+
return text;
|
|
33
|
+
const cut = text.slice(0, maxLen);
|
|
34
|
+
const sp = cut.lastIndexOf(" ");
|
|
35
|
+
return (sp > 0 ? cut.slice(0, sp) : cut) + "…";
|
|
36
|
+
}
|
|
37
|
+
function computeRumorScore(text, keywords) {
|
|
38
|
+
const lower = text.toLowerCase();
|
|
39
|
+
let hits = 0;
|
|
40
|
+
for (const kw of keywords) {
|
|
41
|
+
if (lower.includes(kw.toLowerCase()))
|
|
42
|
+
hits++;
|
|
43
|
+
}
|
|
44
|
+
if (isRumor(text))
|
|
45
|
+
hits += 2;
|
|
46
|
+
return Math.min(1, hits / Math.max(keywords.length, 1));
|
|
47
|
+
}
|
|
48
|
+
function hasPreAnnSignal(text) {
|
|
49
|
+
const lower = text.toLowerCase();
|
|
50
|
+
return PRE_ANN_KEYWORDS.some((kw) => lower.includes(kw));
|
|
51
|
+
}
|
|
52
|
+
function formatDateIso(epoch) {
|
|
53
|
+
const d = new Date(epoch * 1000);
|
|
54
|
+
const y = d.getFullYear();
|
|
55
|
+
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
56
|
+
const day = String(d.getDate()).padStart(2, "0");
|
|
57
|
+
return `${y}-${m}-${day}`;
|
|
58
|
+
}
|
|
59
|
+
function round3(n) {
|
|
60
|
+
return Math.round(n * 1000) / 1000;
|
|
61
|
+
}
|
|
62
|
+
// ── Fetching ─────────────────────────────────────────────────────
|
|
63
|
+
async function fetchSubredditPosts(subreddit, query, cutoffEpoch) {
|
|
64
|
+
const url = REDDIT_SEARCH_JSON
|
|
65
|
+
.replace("{subreddit}", subreddit)
|
|
66
|
+
.replace("{query}", encodeURIComponent(query));
|
|
67
|
+
try {
|
|
68
|
+
const resp = await fetchWithDelay(url, {
|
|
69
|
+
delay: REQUEST_DELAY_S,
|
|
70
|
+
userAgent: DEFAULT_USER_AGENT,
|
|
71
|
+
headers: { Accept: "application/json" },
|
|
72
|
+
});
|
|
73
|
+
if (!resp.ok) {
|
|
74
|
+
console.error(`[WARN] Reddit r/${subreddit} returned HTTP ${resp.status}`);
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
const listing = (await resp.json());
|
|
78
|
+
const children = listing.data?.children ?? [];
|
|
79
|
+
const posts = [];
|
|
80
|
+
for (const child of children) {
|
|
81
|
+
if (child.kind !== "t3")
|
|
82
|
+
continue;
|
|
83
|
+
const d = child.data;
|
|
84
|
+
const created = d.created_utc ?? 0;
|
|
85
|
+
if (created < cutoffEpoch)
|
|
86
|
+
continue;
|
|
87
|
+
const title = d.title ?? "";
|
|
88
|
+
const selftext = d.selftext ?? "";
|
|
89
|
+
const combined = `${title} ${selftext}`;
|
|
90
|
+
posts.push({
|
|
91
|
+
post_id: d.id ?? "",
|
|
92
|
+
date: formatDateIso(created),
|
|
93
|
+
subreddit: d.subreddit ?? subreddit,
|
|
94
|
+
author: d.author ?? "[deleted]",
|
|
95
|
+
title,
|
|
96
|
+
text_snip: truncate(selftext || title),
|
|
97
|
+
sentiment_score: round3(sentimentScore(combined)),
|
|
98
|
+
sentiment_label: sentimentLabel(sentimentScore(combined)),
|
|
99
|
+
rumor_score: round3(computeRumorScore(combined, DEFAULT_RUMOR_KEYWORDS)),
|
|
100
|
+
pre_ann_flag: hasPreAnnSignal(combined),
|
|
101
|
+
url: d.permalink
|
|
102
|
+
? `https://reddit.com${d.permalink}`
|
|
103
|
+
: "",
|
|
104
|
+
score: d.score ?? 0,
|
|
105
|
+
num_comments: d.num_comments ?? 0,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return posts;
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
112
|
+
console.error(`[WARN] Reddit r/${subreddit} scrape failed: ${msg}`);
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// ── Main ─────────────────────────────────────────────────────────
|
|
117
|
+
export async function scrapeAsxReddit(opts) {
|
|
118
|
+
const ticker = normalizeTicker(opts.ticker);
|
|
119
|
+
const subreddits = opts.subreddits ?? DEFAULT_SUBREDDITS;
|
|
120
|
+
const days = opts.days ?? 14;
|
|
121
|
+
const keywords = opts.keywords ?? DEFAULT_RUMOR_KEYWORDS;
|
|
122
|
+
const cutoffEpoch = Math.floor((Date.now() - days * 24 * 60 * 60 * 1000) / 1000);
|
|
123
|
+
const allPosts = [];
|
|
124
|
+
for (const sub of subreddits) {
|
|
125
|
+
const posts = await fetchSubredditPosts(sub, ticker, cutoffEpoch);
|
|
126
|
+
for (const p of posts) {
|
|
127
|
+
p.rumor_score = round3(computeRumorScore(`${p.title} ${p.text_snip}`, keywords));
|
|
128
|
+
}
|
|
129
|
+
allPosts.push(...posts);
|
|
130
|
+
}
|
|
131
|
+
const seen = new Set();
|
|
132
|
+
const unique = allPosts.filter((p) => {
|
|
133
|
+
if (seen.has(p.post_id))
|
|
134
|
+
return false;
|
|
135
|
+
seen.add(p.post_id);
|
|
136
|
+
return true;
|
|
137
|
+
});
|
|
138
|
+
unique.sort((a, b) => b.date.localeCompare(a.date));
|
|
139
|
+
const scores = unique.map((p) => p.sentiment_score);
|
|
140
|
+
const overall = scores.length > 0
|
|
141
|
+
? round3(scores.reduce((a, b) => a + b, 0) / scores.length)
|
|
142
|
+
: 0;
|
|
143
|
+
return {
|
|
144
|
+
ticker,
|
|
145
|
+
scraped_at: isoNow(),
|
|
146
|
+
subreddits,
|
|
147
|
+
period_days: days,
|
|
148
|
+
total_posts: unique.length,
|
|
149
|
+
posts: unique,
|
|
150
|
+
overall_sentiment: overall,
|
|
151
|
+
rumor_count: unique.filter((p) => p.rumor_score > 0.3).length,
|
|
152
|
+
pre_ann_count: unique.filter((p) => p.pre_ann_flag).length,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
export function sampleData(ticker) {
|
|
156
|
+
const t = normalizeTicker(ticker);
|
|
157
|
+
return {
|
|
158
|
+
ticker: t,
|
|
159
|
+
scraped_at: isoNow(),
|
|
160
|
+
subreddits: DEFAULT_SUBREDDITS,
|
|
161
|
+
period_days: 14,
|
|
162
|
+
total_posts: 3,
|
|
163
|
+
posts: [
|
|
164
|
+
{
|
|
165
|
+
post_id: "1abc123",
|
|
166
|
+
date: "2026-02-20",
|
|
167
|
+
subreddit: "ASX_Bets",
|
|
168
|
+
author: "yolo_trader",
|
|
169
|
+
title: `${t} about to rocket? Insider leak before ASX open`,
|
|
170
|
+
text_snip: `Heard from a mate that ${t} has a massive ann dropping before market open tomorrow. NFA.`,
|
|
171
|
+
sentiment_score: 0.667,
|
|
172
|
+
sentiment_label: "bullish",
|
|
173
|
+
rumor_score: 0.75,
|
|
174
|
+
pre_ann_flag: true,
|
|
175
|
+
url: `https://reddit.com/r/ASX_Bets/comments/1abc123/${t.toLowerCase()}_rocket/`,
|
|
176
|
+
score: 42,
|
|
177
|
+
num_comments: 18,
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
post_id: "2def456",
|
|
181
|
+
date: "2026-02-19",
|
|
182
|
+
subreddit: "AusFinance",
|
|
183
|
+
author: "careful_investor",
|
|
184
|
+
title: `${t} valuation analysis — overvalued or undervalued?`,
|
|
185
|
+
text_snip: `Looking at the fundamentals of ${t}, the PE ratio suggests it might be undervalued relative to peers.`,
|
|
186
|
+
sentiment_score: 0.333,
|
|
187
|
+
sentiment_label: "bullish",
|
|
188
|
+
rumor_score: 0.0,
|
|
189
|
+
pre_ann_flag: false,
|
|
190
|
+
url: `https://reddit.com/r/AusFinance/comments/2def456/${t.toLowerCase()}_valuation/`,
|
|
191
|
+
score: 15,
|
|
192
|
+
num_comments: 7,
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
post_id: "3ghi789",
|
|
196
|
+
date: "2026-02-18",
|
|
197
|
+
subreddit: "AusStocks",
|
|
198
|
+
author: "short_seller_99",
|
|
199
|
+
title: `Why I'm shorting ${t} — bearish case`,
|
|
200
|
+
text_snip: `${t} management has been dumping shares. This is a sell signal. Avoid.`,
|
|
201
|
+
sentiment_score: -0.667,
|
|
202
|
+
sentiment_label: "bearish",
|
|
203
|
+
rumor_score: 0.25,
|
|
204
|
+
pre_ann_flag: false,
|
|
205
|
+
url: `https://reddit.com/r/AusStocks/comments/3ghi789/shorting_${t.toLowerCase()}/`,
|
|
206
|
+
score: 8,
|
|
207
|
+
num_comments: 23,
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
overall_sentiment: 0.111,
|
|
211
|
+
rumor_count: 1,
|
|
212
|
+
pre_ann_count: 1,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=asx-reddit-scraper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asx-reddit-scraper.js","sourceRoot":"","sources":["../../src/investigation-tools/asx-reddit-scraper.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,cAAc,EACd,cAAc,EACd,cAAc,EACd,OAAO,EACP,MAAM,EACN,eAAe,EACf,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,oEAAoE;AAEpE,MAAM,kBAAkB,GACtB,qGAAqG,CAAC;AAExG,MAAM,kBAAkB,GAAG,CAAC,UAAU,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;AAEnE,MAAM,sBAAsB,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;AAExE,MAAM,gBAAgB,GAAG;IACvB,YAAY;IACZ,aAAa;IACb,YAAY;IACZ,SAAS;IACT,SAAS;IACT,sBAAsB;IACtB,eAAe;IACf,UAAU;IACV,kBAAkB;IAClB,eAAe;CAChB,CAAC;AAEF,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,MAAM,eAAe,GAAG,GAAG,CAAC;AA2D5B,oEAAoE;AAEpE,SAAS,QAAQ,CAAC,IAAY,EAAE,SAAiB,aAAa;IAC5D,IAAI,IAAI,CAAC,MAAM,IAAI,MAAM;QAAE,OAAO,IAAI,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAClC,MAAM,EAAE,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AACjD,CAAC;AAED,SAAS,iBAAiB,CACxB,IAAY,EACZ,QAAkB;IAElB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC1B,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;YAAE,IAAI,EAAE,CAAC;IAC/C,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,CAAC;QAAE,IAAI,IAAI,CAAC,CAAC;IAC7B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1B,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,MAAM,CAAC,CAAS;IACvB,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;AACrC,CAAC;AAED,oEAAoE;AAEpE,KAAK,UAAU,mBAAmB,CAChC,SAAiB,EACjB,KAAa,EACb,WAAmB;IAEnB,MAAM,GAAG,GAAG,kBAAkB;SAC3B,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC;SACjC,OAAO,CAAC,SAAS,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;IAEjD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE;YACrC,KAAK,EAAE,eAAe;YACtB,SAAS,EAAE,kBAAkB;YAC7B,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;SACxC,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,mBAAmB,SAAS,kBAAkB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAC3E,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAA0B,CAAC;QAC7D,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAuB,EAAE,CAAC;QAErC,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI;gBAAE,SAAS;YAClC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;YACrB,MAAM,OAAO,GAAG,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC;YACnC,IAAI,OAAO,GAAG,WAAW;gBAAE,SAAS;YAEpC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC;YAClC,MAAM,QAAQ,GAAG,GAAG,KAAK,IAAI,QAAQ,EAAE,CAAC;YAExC,KAAK,CAAC,IAAI,CAAC;gBACT,OAAO,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE;gBACnB,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC;gBAC5B,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,SAAS;gBACnC,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,WAAW;gBAC/B,KAAK;gBACL,SAAS,EAAE,QAAQ,CAAC,QAAQ,IAAI,KAAK,CAAC;gBACtC,eAAe,EAAE,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;gBACjD,eAAe,EAAE,cAAc,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;gBACzD,WAAW,EAAE,MAAM,CAAC,iBAAiB,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC;gBACxE,YAAY,EAAE,eAAe,CAAC,QAAQ,CAAC;gBACvC,GAAG,EAAE,CAAC,CAAC,SAAS;oBACd,CAAC,CAAC,qBAAqB,CAAC,CAAC,SAAS,EAAE;oBACpC,CAAC,CAAC,EAAE;gBACN,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;gBACnB,YAAY,EAAE,CAAC,CAAC,YAAY,IAAI,CAAC;aAClC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,CAAC,KAAK,CAAC,mBAAmB,SAAS,mBAAmB,GAAG,EAAE,CAAC,CAAC;QACpE,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,oEAAoE;AAEpE,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAKrC;IACC,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,kBAAkB,CAAC;IACzD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,sBAAsB,CAAC;IAEzD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAC5B,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CACjD,CAAC;IAEF,MAAM,QAAQ,GAAuB,EAAE,CAAC;IAExC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QAClE,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,CAAC,CAAC,WAAW,GAAG,MAAM,CACpB,iBAAiB,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,QAAQ,CAAC,CACzD,CAAC;QACJ,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACnC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;QACtC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEpD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;IACpD,MAAM,OAAO,GACX,MAAM,CAAC,MAAM,GAAG,CAAC;QACf,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QAC3D,CAAC,CAAC,CAAC,CAAC;IAER,OAAO;QACL,MAAM;QACN,UAAU,EAAE,MAAM,EAAE;QACpB,UAAU;QACV,WAAW,EAAE,IAAI;QACjB,WAAW,EAAE,MAAM,CAAC,MAAM;QAC1B,KAAK,EAAE,MAAM;QACb,iBAAiB,EAAE,OAAO;QAC1B,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,MAAM;QAC7D,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM;KAC3D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,MAAM,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAClC,OAAO;QACL,MAAM,EAAE,CAAC;QACT,UAAU,EAAE,MAAM,EAAE;QACpB,UAAU,EAAE,kBAAkB;QAC9B,WAAW,EAAE,EAAE;QACf,WAAW,EAAE,CAAC;QACd,KAAK,EAAE;YACL;gBACE,OAAO,EAAE,SAAS;gBAClB,IAAI,EAAE,YAAY;gBAClB,SAAS,EAAE,UAAU;gBACrB,MAAM,EAAE,aAAa;gBACrB,KAAK,EAAE,GAAG,CAAC,gDAAgD;gBAC3D,SAAS,EAAE,0BAA0B,CAAC,+DAA+D;gBACrG,eAAe,EAAE,KAAK;gBACtB,eAAe,EAAE,SAAS;gBAC1B,WAAW,EAAE,IAAI;gBACjB,YAAY,EAAE,IAAI;gBAClB,GAAG,EAAE,kDAAkD,CAAC,CAAC,WAAW,EAAE,UAAU;gBAChF,KAAK,EAAE,EAAE;gBACT,YAAY,EAAE,EAAE;aACjB;YACD;gBACE,OAAO,EAAE,SAAS;gBAClB,IAAI,EAAE,YAAY;gBAClB,SAAS,EAAE,YAAY;gBACvB,MAAM,EAAE,kBAAkB;gBAC1B,KAAK,EAAE,GAAG,CAAC,kDAAkD;gBAC7D,SAAS,EAAE,kCAAkC,CAAC,oEAAoE;gBAClH,eAAe,EAAE,KAAK;gBACtB,eAAe,EAAE,SAAS;gBAC1B,WAAW,EAAE,GAAG;gBAChB,YAAY,EAAE,KAAK;gBACnB,GAAG,EAAE,oDAAoD,CAAC,CAAC,WAAW,EAAE,aAAa;gBACrF,KAAK,EAAE,EAAE;gBACT,YAAY,EAAE,CAAC;aAChB;YACD;gBACE,OAAO,EAAE,SAAS;gBAClB,IAAI,EAAE,YAAY;gBAClB,SAAS,EAAE,WAAW;gBACtB,MAAM,EAAE,iBAAiB;gBACzB,KAAK,EAAE,oBAAoB,CAAC,iBAAiB;gBAC7C,SAAS,EAAE,GAAG,CAAC,oEAAoE;gBACnF,eAAe,EAAE,CAAC,KAAK;gBACvB,eAAe,EAAE,SAAS;gBAC1B,WAAW,EAAE,IAAI;gBACjB,YAAY,EAAE,KAAK;gBACnB,GAAG,EAAE,4DAA4D,CAAC,CAAC,WAAW,EAAE,GAAG;gBACnF,KAAK,EAAE,CAAC;gBACR,YAAY,EAAE,EAAE;aACjB;SACF;QACD,iBAAiB,EAAE,KAAK;QACxB,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,CAAC;KACjB,CAAC;AACJ,CAAC"}
|
|
@@ -29,5 +29,10 @@ export * as documentProcessing from "./document-processing.js";
|
|
|
29
29
|
export * as investigationAutomation from "./investigation-automation.js";
|
|
30
30
|
export * as monitoringTools from "./monitoring-tools.js";
|
|
31
31
|
export * as cryptoEcosystem from "./crypto-ecosystem.js";
|
|
32
|
+
export * as asxRedditScraper from "./asx-reddit-scraper.js";
|
|
33
|
+
export * as listcorpScraper from "./listcorp-scraper.js";
|
|
34
|
+
export * as yahooFinanceAuScraper from "./yahoo-finance-au-scraper.js";
|
|
35
|
+
export * as seekingAlphaAsxScraper from "./seeking-alpha-asx-scraper.js";
|
|
36
|
+
export * as universalForumScraper from "./universal-forum-scraper.js";
|
|
32
37
|
export { TS_TOOL_REGISTRY, TS_TOOL_NAMES, runTsTool } from "./tool-registry.js";
|
|
33
38
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/investigation-tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,sBAAsB,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,kBAAkB,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,oBAAoB,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,aAAa,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AAGnD,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,aAAa,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,kBAAkB,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,kBAAkB,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,uBAAuB,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/investigation-tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,sBAAsB,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,kBAAkB,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,oBAAoB,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,aAAa,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AAGnD,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,aAAa,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,kBAAkB,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,kBAAkB,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,uBAAuB,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,qBAAqB,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,sBAAsB,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,qBAAqB,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -30,5 +30,10 @@ export * as documentProcessing from "./document-processing.js";
|
|
|
30
30
|
export * as investigationAutomation from "./investigation-automation.js";
|
|
31
31
|
export * as monitoringTools from "./monitoring-tools.js";
|
|
32
32
|
export * as cryptoEcosystem from "./crypto-ecosystem.js";
|
|
33
|
+
export * as asxRedditScraper from "./asx-reddit-scraper.js";
|
|
34
|
+
export * as listcorpScraper from "./listcorp-scraper.js";
|
|
35
|
+
export * as yahooFinanceAuScraper from "./yahoo-finance-au-scraper.js";
|
|
36
|
+
export * as seekingAlphaAsxScraper from "./seeking-alpha-asx-scraper.js";
|
|
37
|
+
export * as universalForumScraper from "./universal-forum-scraper.js";
|
|
33
38
|
export { TS_TOOL_REGISTRY, TS_TOOL_NAMES, runTsTool } from "./tool-registry.js";
|
|
34
39
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/investigation-tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,sBAAsB,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,kBAAkB,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,oBAAoB,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,aAAa,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AAEnD,0BAA0B;AAC1B,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,aAAa,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,kBAAkB,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,kBAAkB,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,uBAAuB,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/investigation-tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,sBAAsB,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,kBAAkB,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,oBAAoB,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,aAAa,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AAEnD,0BAA0B;AAC1B,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,aAAa,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,kBAAkB,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,iBAAiB,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,kBAAkB,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,uBAAuB,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,qBAAqB,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,sBAAsB,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,qBAAqB,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* listcorp-scraper.ts — Listcorp ASX Announcements & Comments Scraper
|
|
3
|
+
*
|
|
4
|
+
* Scrapes Listcorp (https://www.listcorp.com) for ASX company announcements
|
|
5
|
+
* and user comments. Flags comments posted before official ASX lodgement as
|
|
6
|
+
* potential pre-announcement buzz signals.
|
|
7
|
+
*/
|
|
8
|
+
export interface ListcorpAnnouncement {
|
|
9
|
+
title: string;
|
|
10
|
+
date: string;
|
|
11
|
+
ann_type: string | null;
|
|
12
|
+
url: string;
|
|
13
|
+
is_price_sensitive: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface ListcorpComment {
|
|
16
|
+
author: string;
|
|
17
|
+
date: string;
|
|
18
|
+
text: string;
|
|
19
|
+
sentiment_score: number;
|
|
20
|
+
sentiment_label: string;
|
|
21
|
+
is_rumor: boolean;
|
|
22
|
+
pre_lodgement_flag: boolean;
|
|
23
|
+
related_announcement: string | null;
|
|
24
|
+
}
|
|
25
|
+
export interface ListcorpResult {
|
|
26
|
+
ticker: string;
|
|
27
|
+
scraped_at: string;
|
|
28
|
+
period_days: number;
|
|
29
|
+
announcements: ListcorpAnnouncement[];
|
|
30
|
+
comments: ListcorpComment[];
|
|
31
|
+
pre_lodgement_comments: number;
|
|
32
|
+
total_comments: number;
|
|
33
|
+
overall_sentiment: number;
|
|
34
|
+
}
|
|
35
|
+
export declare function scrapeListcorp(opts: {
|
|
36
|
+
ticker: string;
|
|
37
|
+
days?: number;
|
|
38
|
+
ann_types?: string[];
|
|
39
|
+
}): Promise<ListcorpResult>;
|
|
40
|
+
export declare function sampleData(ticker: string): ListcorpResult;
|
|
41
|
+
//# sourceMappingURL=listcorp-scraper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listcorp-scraper.d.ts","sourceRoot":"","sources":["../../src/investigation-tools/listcorp-scraper.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA2BH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,oBAAoB,EAAE,CAAC;IACtC,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AA0ID,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,GAAG,OAAO,CAAC,cAAc,CAAC,CAyC1B;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAgDzD"}
|