@logtape/windows-eventlog 1.0.0-dev.225
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/LICENSE +20 -0
- package/README.md +129 -0
- package/dist/_virtual/rolldown_runtime.cjs +30 -0
- package/dist/ffi.bun.cjs +102 -0
- package/dist/ffi.bun.js +102 -0
- package/dist/ffi.bun.js.map +1 -0
- package/dist/ffi.deno.cjs +116 -0
- package/dist/ffi.deno.js +113 -0
- package/dist/ffi.deno.js.map +1 -0
- package/dist/ffi.node.cjs +78 -0
- package/dist/ffi.node.js +78 -0
- package/dist/ffi.node.js.map +1 -0
- package/dist/mod.cjs +12 -0
- package/dist/mod.d.cts +3 -0
- package/dist/mod.d.ts +3 -0
- package/dist/mod.js +4 -0
- package/dist/platform.cjs +30 -0
- package/dist/platform.js +30 -0
- package/dist/platform.js.map +1 -0
- package/dist/sink.bun.cjs +102 -0
- package/dist/sink.bun.d.cts +34 -0
- package/dist/sink.bun.d.cts.map +1 -0
- package/dist/sink.bun.d.ts +34 -0
- package/dist/sink.bun.d.ts.map +1 -0
- package/dist/sink.bun.js +102 -0
- package/dist/sink.bun.js.map +1 -0
- package/dist/sink.deno.cjs +116 -0
- package/dist/sink.deno.d.cts +34 -0
- package/dist/sink.deno.d.cts.map +1 -0
- package/dist/sink.deno.d.ts +34 -0
- package/dist/sink.deno.d.ts.map +1 -0
- package/dist/sink.deno.js +116 -0
- package/dist/sink.deno.js.map +1 -0
- package/dist/sink.node.cjs +112 -0
- package/dist/sink.node.d.cts +33 -0
- package/dist/sink.node.d.cts.map +1 -0
- package/dist/sink.node.d.ts +33 -0
- package/dist/sink.node.d.ts.map +1 -0
- package/dist/sink.node.js +112 -0
- package/dist/sink.node.js.map +1 -0
- package/dist/types.cjs +55 -0
- package/dist/types.d.cts +79 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.ts +79 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +52 -0
- package/dist/types.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const __logtape_logtape = require_rolldown_runtime.__toESM(require("@logtape/logtape"));
|
|
3
|
+
|
|
4
|
+
//#region ffi.node.ts
|
|
5
|
+
/**
|
|
6
|
+
* Node.js FFI implementation for Windows Event Log API using koffi
|
|
7
|
+
*/
|
|
8
|
+
var WindowsEventLogFFI = class {
|
|
9
|
+
eventSource = null;
|
|
10
|
+
koffi = null;
|
|
11
|
+
sourceName;
|
|
12
|
+
initialized = false;
|
|
13
|
+
lib = null;
|
|
14
|
+
metaLogger = (0, __logtape_logtape.getLogger)([
|
|
15
|
+
"logtape",
|
|
16
|
+
"meta",
|
|
17
|
+
"windows-eventlog"
|
|
18
|
+
]);
|
|
19
|
+
constructor(sourceName) {
|
|
20
|
+
this.sourceName = sourceName;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Initialize the FFI bindings and register event source
|
|
24
|
+
*/
|
|
25
|
+
async initialize() {
|
|
26
|
+
if (this.initialized) return;
|
|
27
|
+
try {
|
|
28
|
+
const koffiModule = await import("koffi");
|
|
29
|
+
this.koffi = koffiModule.default || koffiModule;
|
|
30
|
+
this.lib = this.koffi.load("advapi32.dll");
|
|
31
|
+
const RegisterEventSourceA = this.lib.func("uintptr __stdcall RegisterEventSourceA(uintptr lpUNCServerName, str lpSourceName)");
|
|
32
|
+
const ReportEventA = this.lib.func("bool __stdcall ReportEventA(uintptr hEventLog, uint16 wType, uint16 wCategory, uint32 dwEventID, uintptr lpUserSid, uint16 wNumStrings, uint32 dwDataSize, char** lpStrings, uint8* lpRawData)");
|
|
33
|
+
const DeregisterEventSource = this.lib.func("bool __stdcall DeregisterEventSource(uintptr hEventLog)");
|
|
34
|
+
this.RegisterEventSourceA = RegisterEventSourceA;
|
|
35
|
+
this.ReportEventA = ReportEventA;
|
|
36
|
+
this.DeregisterEventSource = DeregisterEventSource;
|
|
37
|
+
this.eventSource = this.RegisterEventSourceA(0, this.sourceName);
|
|
38
|
+
if (!this.eventSource || this.eventSource === 0) throw new Error(`Failed to register event source: ${this.sourceName}`);
|
|
39
|
+
this.initialized = true;
|
|
40
|
+
} catch (error) {
|
|
41
|
+
throw new Error(`Failed to initialize Windows Event Log FFI: ${error}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
RegisterEventSourceA = null;
|
|
45
|
+
ReportEventA = null;
|
|
46
|
+
DeregisterEventSource = null;
|
|
47
|
+
/**
|
|
48
|
+
* Write an event to Windows Event Log
|
|
49
|
+
*/
|
|
50
|
+
writeEvent(eventType, eventId, message) {
|
|
51
|
+
if (!this.initialized || !this.eventSource || !this.ReportEventA) return;
|
|
52
|
+
try {
|
|
53
|
+
const messageWithNull = message + "\0";
|
|
54
|
+
const messages = [messageWithNull];
|
|
55
|
+
const success = this.ReportEventA(this.eventSource, eventType, 0, eventId, 0, 1, 0, messages, null);
|
|
56
|
+
if (!success) throw new Error("ReportEventA() returned false.");
|
|
57
|
+
} catch (error) {
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Clean up resources
|
|
63
|
+
*/
|
|
64
|
+
dispose() {
|
|
65
|
+
if (this.initialized && this.eventSource && this.DeregisterEventSource) {
|
|
66
|
+
try {
|
|
67
|
+
this.DeregisterEventSource(this.eventSource);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
this.metaLogger.error("Failed to deregister event source during cleanup: {error}", { error });
|
|
70
|
+
}
|
|
71
|
+
this.eventSource = null;
|
|
72
|
+
this.initialized = false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
exports.WindowsEventLogFFI = WindowsEventLogFFI;
|
package/dist/ffi.node.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { getLogger } from "@logtape/logtape";
|
|
2
|
+
|
|
3
|
+
//#region ffi.node.ts
|
|
4
|
+
/**
|
|
5
|
+
* Node.js FFI implementation for Windows Event Log API using koffi
|
|
6
|
+
*/
|
|
7
|
+
var WindowsEventLogFFI = class {
|
|
8
|
+
eventSource = null;
|
|
9
|
+
koffi = null;
|
|
10
|
+
sourceName;
|
|
11
|
+
initialized = false;
|
|
12
|
+
lib = null;
|
|
13
|
+
metaLogger = getLogger([
|
|
14
|
+
"logtape",
|
|
15
|
+
"meta",
|
|
16
|
+
"windows-eventlog"
|
|
17
|
+
]);
|
|
18
|
+
constructor(sourceName) {
|
|
19
|
+
this.sourceName = sourceName;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Initialize the FFI bindings and register event source
|
|
23
|
+
*/
|
|
24
|
+
async initialize() {
|
|
25
|
+
if (this.initialized) return;
|
|
26
|
+
try {
|
|
27
|
+
const koffiModule = await import("koffi");
|
|
28
|
+
this.koffi = koffiModule.default || koffiModule;
|
|
29
|
+
this.lib = this.koffi.load("advapi32.dll");
|
|
30
|
+
const RegisterEventSourceA = this.lib.func("uintptr __stdcall RegisterEventSourceA(uintptr lpUNCServerName, str lpSourceName)");
|
|
31
|
+
const ReportEventA = this.lib.func("bool __stdcall ReportEventA(uintptr hEventLog, uint16 wType, uint16 wCategory, uint32 dwEventID, uintptr lpUserSid, uint16 wNumStrings, uint32 dwDataSize, char** lpStrings, uint8* lpRawData)");
|
|
32
|
+
const DeregisterEventSource = this.lib.func("bool __stdcall DeregisterEventSource(uintptr hEventLog)");
|
|
33
|
+
this.RegisterEventSourceA = RegisterEventSourceA;
|
|
34
|
+
this.ReportEventA = ReportEventA;
|
|
35
|
+
this.DeregisterEventSource = DeregisterEventSource;
|
|
36
|
+
this.eventSource = this.RegisterEventSourceA(0, this.sourceName);
|
|
37
|
+
if (!this.eventSource || this.eventSource === 0) throw new Error(`Failed to register event source: ${this.sourceName}`);
|
|
38
|
+
this.initialized = true;
|
|
39
|
+
} catch (error) {
|
|
40
|
+
throw new Error(`Failed to initialize Windows Event Log FFI: ${error}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
RegisterEventSourceA = null;
|
|
44
|
+
ReportEventA = null;
|
|
45
|
+
DeregisterEventSource = null;
|
|
46
|
+
/**
|
|
47
|
+
* Write an event to Windows Event Log
|
|
48
|
+
*/
|
|
49
|
+
writeEvent(eventType, eventId, message) {
|
|
50
|
+
if (!this.initialized || !this.eventSource || !this.ReportEventA) return;
|
|
51
|
+
try {
|
|
52
|
+
const messageWithNull = message + "\0";
|
|
53
|
+
const messages = [messageWithNull];
|
|
54
|
+
const success = this.ReportEventA(this.eventSource, eventType, 0, eventId, 0, 1, 0, messages, null);
|
|
55
|
+
if (!success) throw new Error("ReportEventA() returned false.");
|
|
56
|
+
} catch (error) {
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Clean up resources
|
|
62
|
+
*/
|
|
63
|
+
dispose() {
|
|
64
|
+
if (this.initialized && this.eventSource && this.DeregisterEventSource) {
|
|
65
|
+
try {
|
|
66
|
+
this.DeregisterEventSource(this.eventSource);
|
|
67
|
+
} catch (error) {
|
|
68
|
+
this.metaLogger.error("Failed to deregister event source during cleanup: {error}", { error });
|
|
69
|
+
}
|
|
70
|
+
this.eventSource = null;
|
|
71
|
+
this.initialized = false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
//#endregion
|
|
77
|
+
export { WindowsEventLogFFI };
|
|
78
|
+
//# sourceMappingURL=ffi.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ffi.node.js","names":["sourceName: string","eventType: EventType","eventId: number","message: string"],"sources":["../ffi.node.ts"],"sourcesContent":["import { getLogger } from \"@logtape/logtape\";\nimport type { EventType } from \"./types.ts\";\n\n/**\n * Node.js FFI implementation for Windows Event Log API using koffi\n */\nexport class WindowsEventLogFFI {\n private eventSource: unknown = null;\n private koffi: unknown = null;\n private sourceName: string;\n private initialized = false;\n private lib: unknown = null;\n private metaLogger = getLogger([\"logtape\", \"meta\", \"windows-eventlog\"]);\n\n constructor(sourceName: string) {\n this.sourceName = sourceName;\n }\n\n /**\n * Initialize the FFI bindings and register event source\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n try {\n // Dynamic import for koffi\n const koffiModule = await import(\"koffi\");\n this.koffi = koffiModule.default || koffiModule;\n\n // Load advapi32.dll\n this.lib = (this.koffi as unknown as { load: (lib: string) => unknown })\n .load(\"advapi32.dll\");\n\n // Define Windows API functions with correct koffi types using __stdcall convention\n const RegisterEventSourceA =\n (this.lib as unknown as { func: (sig: string) => unknown }).func(\n \"uintptr __stdcall RegisterEventSourceA(uintptr lpUNCServerName, str lpSourceName)\",\n );\n // ReportEventA expects LPCSTR* (array of string pointers) for lpStrings\n // Use char** for null-terminated array of strings\n const ReportEventA =\n (this.lib as unknown as { func: (sig: string) => unknown }).func(\n \"bool __stdcall ReportEventA(uintptr hEventLog, uint16 wType, uint16 wCategory, uint32 dwEventID, uintptr lpUserSid, uint16 wNumStrings, uint32 dwDataSize, char** lpStrings, uint8* lpRawData)\",\n );\n const DeregisterEventSource =\n (this.lib as unknown as { func: (sig: string) => unknown }).func(\n \"bool __stdcall DeregisterEventSource(uintptr hEventLog)\",\n );\n\n // Store functions\n this.RegisterEventSourceA = RegisterEventSourceA;\n this.ReportEventA = ReportEventA;\n this.DeregisterEventSource = DeregisterEventSource;\n\n // Register event source\n this.eventSource = (this.RegisterEventSourceA as unknown as (\n ...args: unknown[]\n ) => unknown)(0, this.sourceName);\n\n if (!this.eventSource || this.eventSource === 0) {\n throw new Error(\n `Failed to register event source: ${this.sourceName}`,\n );\n }\n\n this.initialized = true;\n } catch (error) {\n throw new Error(\n `Failed to initialize Windows Event Log FFI: ${error}`,\n );\n }\n }\n\n private RegisterEventSourceA: unknown = null;\n private ReportEventA: unknown = null;\n private DeregisterEventSource: unknown = null;\n\n /**\n * Write an event to Windows Event Log\n */\n writeEvent(eventType: EventType, eventId: number, message: string): void {\n if (!this.initialized || !this.eventSource || !this.ReportEventA) {\n return;\n }\n\n try {\n // Create null-terminated string\n const messageWithNull = message + \"\\0\";\n\n // Create an array with a single string pointer\n // In koffi, we pass an array of strings for char**\n const messages = [messageWithNull];\n\n // Report the event using strings array approach\n const success =\n (this.ReportEventA as unknown as (...args: unknown[]) => unknown)(\n this.eventSource,\n eventType,\n 0, // category\n eventId,\n 0, // user SID (null)\n 1, // number of strings (1 - we have one message)\n 0, // data size (0 - not using raw data)\n messages, // strings array with our message\n null, // raw data (null - not using)\n );\n\n if (!success) {\n throw new Error(\"ReportEventA() returned false.\");\n }\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * Clean up resources\n */\n dispose(): void {\n if (this.initialized && this.eventSource && this.DeregisterEventSource) {\n try {\n (this.DeregisterEventSource as unknown as (\n ...args: unknown[]\n ) => unknown)(this.eventSource);\n } catch (error) {\n this.metaLogger.error(\n \"Failed to deregister event source during cleanup: {error}\",\n { error },\n );\n }\n this.eventSource = null;\n this.initialized = false;\n }\n }\n}\n"],"mappings":";;;;;;AAMA,IAAa,qBAAb,MAAgC;CAC9B,AAAQ,cAAuB;CAC/B,AAAQ,QAAiB;CACzB,AAAQ;CACR,AAAQ,cAAc;CACtB,AAAQ,MAAe;CACvB,AAAQ,aAAa,UAAU;EAAC;EAAW;EAAQ;CAAmB,EAAC;CAEvE,YAAYA,YAAoB;AAC9B,OAAK,aAAa;CACnB;;;;CAKD,MAAM,aAA4B;AAChC,MAAI,KAAK,YAAa;AAEtB,MAAI;GAEF,MAAM,cAAc,MAAM,OAAO;AACjC,QAAK,QAAQ,YAAY,WAAW;AAGpC,QAAK,MAAM,AAAC,KAAK,MACd,KAAK,eAAe;GAGvB,MAAM,uBACJ,AAAC,KAAK,IAAsD,KAC1D,oFACD;GAGH,MAAM,eACJ,AAAC,KAAK,IAAsD,KAC1D,iMACD;GACH,MAAM,wBACJ,AAAC,KAAK,IAAsD,KAC1D,0DACD;AAGH,QAAK,uBAAuB;AAC5B,QAAK,eAAe;AACpB,QAAK,wBAAwB;AAG7B,QAAK,cAAc,AAAC,KAAK,qBAEX,GAAG,KAAK,WAAW;AAEjC,QAAK,KAAK,eAAe,KAAK,gBAAgB,EAC5C,OAAM,IAAI,OACP,mCAAmC,KAAK,WAAW;AAIxD,QAAK,cAAc;EACpB,SAAQ,OAAO;AACd,SAAM,IAAI,OACP,8CAA8C,MAAM;EAExD;CACF;CAED,AAAQ,uBAAgC;CACxC,AAAQ,eAAwB;CAChC,AAAQ,wBAAiC;;;;CAKzC,WAAWC,WAAsBC,SAAiBC,SAAuB;AACvE,OAAK,KAAK,gBAAgB,KAAK,gBAAgB,KAAK,aAClD;AAGF,MAAI;GAEF,MAAM,kBAAkB,UAAU;GAIlC,MAAM,WAAW,CAAC,eAAgB;GAGlC,MAAM,UACJ,AAAC,KAAK,aACJ,KAAK,aACL,WACA,GACA,SACA,GACA,GACA,GACA,UACA,KACD;AAEH,QAAK,QACH,OAAM,IAAI,MAAM;EAEnB,SAAQ,OAAO;AACd,SAAM;EACP;CACF;;;;CAKD,UAAgB;AACd,MAAI,KAAK,eAAe,KAAK,eAAe,KAAK,uBAAuB;AACtE,OAAI;AACF,IAAC,KAAK,sBAEQ,KAAK,YAAY;GAChC,SAAQ,OAAO;AACd,SAAK,WAAW,MACd,6DACA,EAAE,MAAO,EACV;GACF;AACD,QAAK,cAAc;AACnB,QAAK,cAAc;EACpB;CACF;AACF"}
|
package/dist/mod.cjs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_types = require('./types.cjs');
|
|
3
|
+
const __wineventlog = require_rolldown_runtime.__toESM(require("#wineventlog"));
|
|
4
|
+
|
|
5
|
+
exports.WindowsEventLogError = require_types.WindowsEventLogError;
|
|
6
|
+
exports.WindowsPlatformError = require_types.WindowsPlatformError;
|
|
7
|
+
Object.defineProperty(exports, 'getWindowsEventLogSink', {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () {
|
|
10
|
+
return __wineventlog.getWindowsEventLogSink;
|
|
11
|
+
}
|
|
12
|
+
});
|
package/dist/mod.d.cts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { WindowsEventLogError, WindowsEventLogSinkOptions, WindowsLogName, WindowsPlatformError } from "./types.cjs";
|
|
2
|
+
import { getWindowsEventLogSink } from "#wineventlog";
|
|
3
|
+
export { WindowsEventLogError, WindowsEventLogSinkOptions, WindowsLogName, WindowsPlatformError, getWindowsEventLogSink };
|
package/dist/mod.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { WindowsEventLogError, WindowsEventLogSinkOptions, WindowsLogName, WindowsPlatformError } from "./types.js";
|
|
2
|
+
import { getWindowsEventLogSink } from "#wineventlog";
|
|
3
|
+
export { WindowsEventLogError, WindowsEventLogSinkOptions, WindowsLogName, WindowsPlatformError, getWindowsEventLogSink };
|
package/dist/mod.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_types = require('./types.cjs');
|
|
3
|
+
const node_process = require_rolldown_runtime.__toESM(require("node:process"));
|
|
4
|
+
|
|
5
|
+
//#region platform.ts
|
|
6
|
+
/**
|
|
7
|
+
* Validates that the current platform is Windows.
|
|
8
|
+
* Throws a WindowsPlatformError if running on a non-Windows platform.
|
|
9
|
+
*
|
|
10
|
+
* @throws {WindowsPlatformError} When running on non-Windows platforms
|
|
11
|
+
* @since 1.0.0
|
|
12
|
+
*/
|
|
13
|
+
function validateWindowsPlatform() {
|
|
14
|
+
const platform = getPlatform();
|
|
15
|
+
if (platform !== "windows" && platform !== "win32") throw new require_types.WindowsPlatformError(platform);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Gets the current platform in a cross-runtime compatible way.
|
|
19
|
+
*
|
|
20
|
+
* @returns The platform identifier
|
|
21
|
+
* @since 1.0.0
|
|
22
|
+
*/
|
|
23
|
+
function getPlatform() {
|
|
24
|
+
if (typeof Deno !== "undefined" && Deno.build?.os) return Deno.build.os;
|
|
25
|
+
if (typeof node_process.default !== "undefined" && node_process.default.platform) return node_process.default.platform;
|
|
26
|
+
return "unknown";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
//#endregion
|
|
30
|
+
exports.validateWindowsPlatform = validateWindowsPlatform;
|
package/dist/platform.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { WindowsPlatformError } from "./types.js";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
|
|
4
|
+
//#region platform.ts
|
|
5
|
+
/**
|
|
6
|
+
* Validates that the current platform is Windows.
|
|
7
|
+
* Throws a WindowsPlatformError if running on a non-Windows platform.
|
|
8
|
+
*
|
|
9
|
+
* @throws {WindowsPlatformError} When running on non-Windows platforms
|
|
10
|
+
* @since 1.0.0
|
|
11
|
+
*/
|
|
12
|
+
function validateWindowsPlatform() {
|
|
13
|
+
const platform = getPlatform();
|
|
14
|
+
if (platform !== "windows" && platform !== "win32") throw new WindowsPlatformError(platform);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Gets the current platform in a cross-runtime compatible way.
|
|
18
|
+
*
|
|
19
|
+
* @returns The platform identifier
|
|
20
|
+
* @since 1.0.0
|
|
21
|
+
*/
|
|
22
|
+
function getPlatform() {
|
|
23
|
+
if (typeof Deno !== "undefined" && Deno.build?.os) return Deno.build.os;
|
|
24
|
+
if (typeof process !== "undefined" && process.platform) return process.platform;
|
|
25
|
+
return "unknown";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
export { validateWindowsPlatform };
|
|
30
|
+
//# sourceMappingURL=platform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.js","names":[],"sources":["../platform.ts"],"sourcesContent":["import process from \"node:process\";\nimport { WindowsPlatformError } from \"./types.ts\";\n\n/**\n * Validates that the current platform is Windows.\n * Throws a WindowsPlatformError if running on a non-Windows platform.\n *\n * @throws {WindowsPlatformError} When running on non-Windows platforms\n * @since 1.0.0\n */\nexport function validateWindowsPlatform(): void {\n const platform = getPlatform();\n\n if (platform !== \"windows\" && platform !== \"win32\") {\n throw new WindowsPlatformError(platform);\n }\n}\n\n/**\n * Gets the current platform in a cross-runtime compatible way.\n *\n * @returns The platform identifier\n * @since 1.0.0\n */\nexport function getPlatform(): string {\n // Deno\n if (typeof Deno !== \"undefined\" && Deno.build?.os) {\n return Deno.build.os;\n }\n\n // Node.js/Bun\n if (typeof process !== \"undefined\" && process.platform) {\n return process.platform;\n }\n\n // Fallback - assume non-Windows\n return \"unknown\";\n}\n\n/**\n * Checks if the current platform is Windows without throwing.\n *\n * @returns true if running on Windows, false otherwise\n * @since 1.0.0\n */\nexport function isWindows(): boolean {\n try {\n validateWindowsPlatform();\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Gets the current JavaScript runtime.\n *\n * @returns The runtime identifier (\"deno\", \"node\", \"bun\", or \"unknown\")\n * @since 1.0.0\n */\nexport function getRuntime(): \"deno\" | \"node\" | \"bun\" | \"unknown\" {\n // Deno\n if (typeof Deno !== \"undefined\") {\n return \"deno\";\n }\n\n // Bun\n if (typeof globalThis !== \"undefined\" && \"Bun\" in globalThis) {\n return \"bun\";\n }\n\n // Node.js (check process exists and is not Deno/Bun)\n if (typeof process !== \"undefined\" && process.versions?.node) {\n return \"node\";\n }\n\n return \"unknown\";\n}\n"],"mappings":";;;;;;;;;;;AAUA,SAAgB,0BAAgC;CAC9C,MAAM,WAAW,aAAa;AAE9B,KAAI,aAAa,aAAa,aAAa,QACzC,OAAM,IAAI,qBAAqB;AAElC;;;;;;;AAQD,SAAgB,cAAsB;AAEpC,YAAW,SAAS,eAAe,KAAK,OAAO,GAC7C,QAAO,KAAK,MAAM;AAIpB,YAAW,YAAY,eAAe,QAAQ,SAC5C,QAAO,QAAQ;AAIjB,QAAO;AACR"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_types = require('./types.cjs');
|
|
3
|
+
const require_platform = require('./platform.cjs');
|
|
4
|
+
const require_ffi_bun = require('./ffi.bun.cjs');
|
|
5
|
+
const __logtape_logtape = require_rolldown_runtime.__toESM(require("@logtape/logtape"));
|
|
6
|
+
|
|
7
|
+
//#region sink.bun.ts
|
|
8
|
+
/**
|
|
9
|
+
* Formats a log record message into a string suitable for Windows Event Log.
|
|
10
|
+
* Combines the template and arguments into a readable message.
|
|
11
|
+
*/
|
|
12
|
+
function formatMessage(record) {
|
|
13
|
+
let message = "";
|
|
14
|
+
for (let i = 0; i < record.message.length; i++) if (i % 2 === 0) message += record.message[i];
|
|
15
|
+
else {
|
|
16
|
+
const arg = record.message[i];
|
|
17
|
+
if (typeof arg === "string") message += arg;
|
|
18
|
+
else message += JSON.stringify(arg);
|
|
19
|
+
}
|
|
20
|
+
return message;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Formats additional context information for the log entry.
|
|
24
|
+
* Includes category, properties, and other metadata.
|
|
25
|
+
*/
|
|
26
|
+
function formatContext(record) {
|
|
27
|
+
const context = [];
|
|
28
|
+
if (record.category && record.category.length > 0) context.push(`Category: ${record.category.join(".")}`);
|
|
29
|
+
if (record.properties && Object.keys(record.properties).length > 0) context.push(`Properties: ${JSON.stringify(record.properties)}`);
|
|
30
|
+
context.push(`Timestamp: ${new Date(record.timestamp).toISOString()}`);
|
|
31
|
+
return context.length > 0 ? `\n\n${context.join("\n")}` : "";
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Creates a Windows Event Log sink for Bun environments using FFI.
|
|
35
|
+
*
|
|
36
|
+
* This implementation uses Bun's native Foreign Function Interface to directly
|
|
37
|
+
* call Windows Event Log APIs, providing high performance logging optimized
|
|
38
|
+
* for the Bun runtime.
|
|
39
|
+
*
|
|
40
|
+
* @param options Configuration options for the sink
|
|
41
|
+
* @returns A LogTape sink that writes to Windows Event Log
|
|
42
|
+
* @throws {WindowsPlatformError} If not running on Windows
|
|
43
|
+
* @throws {WindowsEventLogError} If Event Log operations fail
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* import { getWindowsEventLogSink } from "@logtape/windows-eventlog";
|
|
48
|
+
*
|
|
49
|
+
* const sink = getWindowsEventLogSink({
|
|
50
|
+
* sourceName: "MyApp",
|
|
51
|
+
* logName: "Application"
|
|
52
|
+
* });
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @since 1.0.0
|
|
56
|
+
*/
|
|
57
|
+
function getWindowsEventLogSink(options) {
|
|
58
|
+
require_platform.validateWindowsPlatform();
|
|
59
|
+
const { sourceName, logName: _logName = "Application", eventIdMapping = {} } = options;
|
|
60
|
+
const eventIds = {
|
|
61
|
+
...require_types.DEFAULT_EVENT_ID_MAPPING,
|
|
62
|
+
...eventIdMapping
|
|
63
|
+
};
|
|
64
|
+
let ffi = null;
|
|
65
|
+
const metaLogger = (0, __logtape_logtape.getLogger)([
|
|
66
|
+
"logtape",
|
|
67
|
+
"meta",
|
|
68
|
+
"windows-eventlog"
|
|
69
|
+
]);
|
|
70
|
+
const sink = (record) => {
|
|
71
|
+
if (!ffi) {
|
|
72
|
+
ffi = new require_ffi_bun.WindowsEventLogFFI(sourceName);
|
|
73
|
+
try {
|
|
74
|
+
ffi.initialize();
|
|
75
|
+
} catch (error) {
|
|
76
|
+
metaLogger.error("Failed to initialize Windows Event Log FFI: {error}", { error });
|
|
77
|
+
ffi = null;
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const message = formatMessage(record);
|
|
82
|
+
const context = formatContext(record);
|
|
83
|
+
const fullMessage = message + context;
|
|
84
|
+
const eventType = require_types.mapLogLevelToEventType(record.level);
|
|
85
|
+
const eventId = eventIds[record.level];
|
|
86
|
+
if (ffi) try {
|
|
87
|
+
ffi.writeEvent(eventType, eventId, fullMessage);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
metaLogger.error("Failed to write to Windows Event Log: {error}", { error });
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
sink[Symbol.dispose] = () => {
|
|
93
|
+
if (ffi) {
|
|
94
|
+
ffi.dispose();
|
|
95
|
+
ffi = null;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
return sink;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
//#endregion
|
|
102
|
+
exports.getWindowsEventLogSink = getWindowsEventLogSink;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { WindowsEventLogSinkOptions } from "./types.cjs";
|
|
2
|
+
import { Sink } from "@logtape/logtape";
|
|
3
|
+
|
|
4
|
+
//#region sink.bun.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a Windows Event Log sink for Bun environments using FFI.
|
|
8
|
+
*
|
|
9
|
+
* This implementation uses Bun's native Foreign Function Interface to directly
|
|
10
|
+
* call Windows Event Log APIs, providing high performance logging optimized
|
|
11
|
+
* for the Bun runtime.
|
|
12
|
+
*
|
|
13
|
+
* @param options Configuration options for the sink
|
|
14
|
+
* @returns A LogTape sink that writes to Windows Event Log
|
|
15
|
+
* @throws {WindowsPlatformError} If not running on Windows
|
|
16
|
+
* @throws {WindowsEventLogError} If Event Log operations fail
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { getWindowsEventLogSink } from "@logtape/windows-eventlog";
|
|
21
|
+
*
|
|
22
|
+
* const sink = getWindowsEventLogSink({
|
|
23
|
+
* sourceName: "MyApp",
|
|
24
|
+
* logName: "Application"
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @since 1.0.0
|
|
29
|
+
*/
|
|
30
|
+
declare function getWindowsEventLogSink(options: WindowsEventLogSinkOptions): Sink & Disposable;
|
|
31
|
+
//# sourceMappingURL=sink.bun.d.ts.map
|
|
32
|
+
//#endregion
|
|
33
|
+
export { getWindowsEventLogSink };
|
|
34
|
+
//# sourceMappingURL=sink.bun.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sink.bun.d.cts","names":[],"sources":["../sink.bun.ts"],"sourcesContent":[],"mappings":";;;;;;;AAgFA;;;;;AAEoB;;;;;;;;;;;;;;;;;iBAFJ,sBAAA,UACL,6BACR,OAAO"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { WindowsEventLogSinkOptions } from "./types.js";
|
|
2
|
+
import { Sink } from "@logtape/logtape";
|
|
3
|
+
|
|
4
|
+
//#region sink.bun.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a Windows Event Log sink for Bun environments using FFI.
|
|
8
|
+
*
|
|
9
|
+
* This implementation uses Bun's native Foreign Function Interface to directly
|
|
10
|
+
* call Windows Event Log APIs, providing high performance logging optimized
|
|
11
|
+
* for the Bun runtime.
|
|
12
|
+
*
|
|
13
|
+
* @param options Configuration options for the sink
|
|
14
|
+
* @returns A LogTape sink that writes to Windows Event Log
|
|
15
|
+
* @throws {WindowsPlatformError} If not running on Windows
|
|
16
|
+
* @throws {WindowsEventLogError} If Event Log operations fail
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { getWindowsEventLogSink } from "@logtape/windows-eventlog";
|
|
21
|
+
*
|
|
22
|
+
* const sink = getWindowsEventLogSink({
|
|
23
|
+
* sourceName: "MyApp",
|
|
24
|
+
* logName: "Application"
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @since 1.0.0
|
|
29
|
+
*/
|
|
30
|
+
declare function getWindowsEventLogSink(options: WindowsEventLogSinkOptions): Sink & Disposable;
|
|
31
|
+
//# sourceMappingURL=sink.bun.d.ts.map
|
|
32
|
+
//#endregion
|
|
33
|
+
export { getWindowsEventLogSink };
|
|
34
|
+
//# sourceMappingURL=sink.bun.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sink.bun.d.ts","names":[],"sources":["../sink.bun.ts"],"sourcesContent":[],"mappings":";;;;;;;AAgFA;;;;;AAEoB;;;;;;;;;;;;;;;;;iBAFJ,sBAAA,UACL,6BACR,OAAO"}
|
package/dist/sink.bun.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { DEFAULT_EVENT_ID_MAPPING, mapLogLevelToEventType } from "./types.js";
|
|
2
|
+
import { validateWindowsPlatform } from "./platform.js";
|
|
3
|
+
import { WindowsEventLogFFI } from "./ffi.bun.js";
|
|
4
|
+
import { getLogger } from "@logtape/logtape";
|
|
5
|
+
|
|
6
|
+
//#region sink.bun.ts
|
|
7
|
+
/**
|
|
8
|
+
* Formats a log record message into a string suitable for Windows Event Log.
|
|
9
|
+
* Combines the template and arguments into a readable message.
|
|
10
|
+
*/
|
|
11
|
+
function formatMessage(record) {
|
|
12
|
+
let message = "";
|
|
13
|
+
for (let i = 0; i < record.message.length; i++) if (i % 2 === 0) message += record.message[i];
|
|
14
|
+
else {
|
|
15
|
+
const arg = record.message[i];
|
|
16
|
+
if (typeof arg === "string") message += arg;
|
|
17
|
+
else message += JSON.stringify(arg);
|
|
18
|
+
}
|
|
19
|
+
return message;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Formats additional context information for the log entry.
|
|
23
|
+
* Includes category, properties, and other metadata.
|
|
24
|
+
*/
|
|
25
|
+
function formatContext(record) {
|
|
26
|
+
const context = [];
|
|
27
|
+
if (record.category && record.category.length > 0) context.push(`Category: ${record.category.join(".")}`);
|
|
28
|
+
if (record.properties && Object.keys(record.properties).length > 0) context.push(`Properties: ${JSON.stringify(record.properties)}`);
|
|
29
|
+
context.push(`Timestamp: ${new Date(record.timestamp).toISOString()}`);
|
|
30
|
+
return context.length > 0 ? `\n\n${context.join("\n")}` : "";
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Creates a Windows Event Log sink for Bun environments using FFI.
|
|
34
|
+
*
|
|
35
|
+
* This implementation uses Bun's native Foreign Function Interface to directly
|
|
36
|
+
* call Windows Event Log APIs, providing high performance logging optimized
|
|
37
|
+
* for the Bun runtime.
|
|
38
|
+
*
|
|
39
|
+
* @param options Configuration options for the sink
|
|
40
|
+
* @returns A LogTape sink that writes to Windows Event Log
|
|
41
|
+
* @throws {WindowsPlatformError} If not running on Windows
|
|
42
|
+
* @throws {WindowsEventLogError} If Event Log operations fail
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* import { getWindowsEventLogSink } from "@logtape/windows-eventlog";
|
|
47
|
+
*
|
|
48
|
+
* const sink = getWindowsEventLogSink({
|
|
49
|
+
* sourceName: "MyApp",
|
|
50
|
+
* logName: "Application"
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @since 1.0.0
|
|
55
|
+
*/
|
|
56
|
+
function getWindowsEventLogSink(options) {
|
|
57
|
+
validateWindowsPlatform();
|
|
58
|
+
const { sourceName, logName: _logName = "Application", eventIdMapping = {} } = options;
|
|
59
|
+
const eventIds = {
|
|
60
|
+
...DEFAULT_EVENT_ID_MAPPING,
|
|
61
|
+
...eventIdMapping
|
|
62
|
+
};
|
|
63
|
+
let ffi = null;
|
|
64
|
+
const metaLogger = getLogger([
|
|
65
|
+
"logtape",
|
|
66
|
+
"meta",
|
|
67
|
+
"windows-eventlog"
|
|
68
|
+
]);
|
|
69
|
+
const sink = (record) => {
|
|
70
|
+
if (!ffi) {
|
|
71
|
+
ffi = new WindowsEventLogFFI(sourceName);
|
|
72
|
+
try {
|
|
73
|
+
ffi.initialize();
|
|
74
|
+
} catch (error) {
|
|
75
|
+
metaLogger.error("Failed to initialize Windows Event Log FFI: {error}", { error });
|
|
76
|
+
ffi = null;
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const message = formatMessage(record);
|
|
81
|
+
const context = formatContext(record);
|
|
82
|
+
const fullMessage = message + context;
|
|
83
|
+
const eventType = mapLogLevelToEventType(record.level);
|
|
84
|
+
const eventId = eventIds[record.level];
|
|
85
|
+
if (ffi) try {
|
|
86
|
+
ffi.writeEvent(eventType, eventId, fullMessage);
|
|
87
|
+
} catch (error) {
|
|
88
|
+
metaLogger.error("Failed to write to Windows Event Log: {error}", { error });
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
sink[Symbol.dispose] = () => {
|
|
92
|
+
if (ffi) {
|
|
93
|
+
ffi.dispose();
|
|
94
|
+
ffi = null;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
return sink;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
//#endregion
|
|
101
|
+
export { getWindowsEventLogSink };
|
|
102
|
+
//# sourceMappingURL=sink.bun.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sink.bun.js","names":["record: LogRecord","context: string[]","options: WindowsEventLogSinkOptions","ffi: WindowsEventLogFFI | null","sink: Sink & Disposable"],"sources":["../sink.bun.ts"],"sourcesContent":["import type { LogRecord, Sink } from \"@logtape/logtape\";\nimport { getLogger } from \"@logtape/logtape\";\nimport type { WindowsEventLogSinkOptions } from \"./types.ts\";\nimport { DEFAULT_EVENT_ID_MAPPING, mapLogLevelToEventType } from \"./types.ts\";\nimport { validateWindowsPlatform } from \"./platform.ts\";\nimport { WindowsEventLogFFI } from \"./ffi.bun.ts\";\n\n/**\n * Formats a log record message into a string suitable for Windows Event Log.\n * Combines the template and arguments into a readable message.\n */\nfunction formatMessage(record: LogRecord): string {\n let message = \"\";\n\n // Combine template parts with arguments\n for (let i = 0; i < record.message.length; i++) {\n if (i % 2 === 0) {\n // Template part\n message += record.message[i];\n } else {\n // Argument - serialize it\n const arg = record.message[i];\n if (typeof arg === \"string\") {\n message += arg;\n } else {\n message += JSON.stringify(arg);\n }\n }\n }\n\n return message;\n}\n\n/**\n * Formats additional context information for the log entry.\n * Includes category, properties, and other metadata.\n */\nfunction formatContext(record: LogRecord): string {\n const context: string[] = [];\n\n // Add category if present\n if (record.category && record.category.length > 0) {\n context.push(`Category: ${record.category.join(\".\")}`);\n }\n\n // Add properties if present\n if (record.properties && Object.keys(record.properties).length > 0) {\n context.push(`Properties: ${JSON.stringify(record.properties)}`);\n }\n\n // Add timestamp\n context.push(`Timestamp: ${new Date(record.timestamp).toISOString()}`);\n\n return context.length > 0 ? `\\n\\n${context.join(\"\\n\")}` : \"\";\n}\n\n/**\n * Creates a Windows Event Log sink for Bun environments using FFI.\n *\n * This implementation uses Bun's native Foreign Function Interface to directly\n * call Windows Event Log APIs, providing high performance logging optimized\n * for the Bun runtime.\n *\n * @param options Configuration options for the sink\n * @returns A LogTape sink that writes to Windows Event Log\n * @throws {WindowsPlatformError} If not running on Windows\n * @throws {WindowsEventLogError} If Event Log operations fail\n *\n * @example\n * ```typescript\n * import { getWindowsEventLogSink } from \"@logtape/windows-eventlog\";\n *\n * const sink = getWindowsEventLogSink({\n * sourceName: \"MyApp\",\n * logName: \"Application\"\n * });\n * ```\n *\n * @since 1.0.0\n */\nexport function getWindowsEventLogSink(\n options: WindowsEventLogSinkOptions,\n): Sink & Disposable {\n // Validate platform early\n validateWindowsPlatform();\n\n const {\n sourceName,\n logName: _logName = \"Application\",\n eventIdMapping = {},\n } = options;\n\n // Merge with default event ID mapping\n const eventIds = { ...DEFAULT_EVENT_ID_MAPPING, ...eventIdMapping };\n\n let ffi: WindowsEventLogFFI | null = null;\n const metaLogger = getLogger([\"logtape\", \"meta\", \"windows-eventlog\"]);\n\n const sink: Sink & Disposable = (record: LogRecord) => {\n if (!ffi) {\n ffi = new WindowsEventLogFFI(sourceName);\n try {\n ffi.initialize();\n } catch (error) {\n metaLogger.error(\n \"Failed to initialize Windows Event Log FFI: {error}\",\n { error },\n );\n ffi = null; // Reset FFI on error\n return;\n }\n }\n\n // Format the complete message\n const message = formatMessage(record);\n const context = formatContext(record);\n const fullMessage = message + context;\n\n // Get event type and ID for this log level\n const eventType = mapLogLevelToEventType(record.level);\n const eventId = eventIds[record.level];\n\n // Write to Event Log using FFI (synchronously since Bun FFI initializes synchronously)\n if (ffi) {\n try {\n ffi.writeEvent(eventType, eventId, fullMessage);\n } catch (error) {\n metaLogger.error(\n \"Failed to write to Windows Event Log: {error}\",\n { error },\n );\n }\n }\n };\n\n // Implement Disposable for cleanup\n sink[Symbol.dispose] = () => {\n if (ffi) {\n ffi.dispose();\n ffi = null;\n }\n };\n\n return sink;\n}\n"],"mappings":";;;;;;;;;;AAWA,SAAS,cAAcA,QAA2B;CAChD,IAAI,UAAU;AAGd,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,QAAQ,IACzC,KAAI,IAAI,MAAM,EAEZ,YAAW,OAAO,QAAQ;MACrB;EAEL,MAAM,MAAM,OAAO,QAAQ;AAC3B,aAAW,QAAQ,SACjB,YAAW;MAEX,YAAW,KAAK,UAAU,IAAI;CAEjC;AAGH,QAAO;AACR;;;;;AAMD,SAAS,cAAcA,QAA2B;CAChD,MAAMC,UAAoB,CAAE;AAG5B,KAAI,OAAO,YAAY,OAAO,SAAS,SAAS,EAC9C,SAAQ,MAAM,YAAY,OAAO,SAAS,KAAK,IAAI,CAAC,EAAE;AAIxD,KAAI,OAAO,cAAc,OAAO,KAAK,OAAO,WAAW,CAAC,SAAS,EAC/D,SAAQ,MAAM,cAAc,KAAK,UAAU,OAAO,WAAW,CAAC,EAAE;AAIlE,SAAQ,MAAM,aAAa,IAAI,KAAK,OAAO,WAAW,aAAa,CAAC,EAAE;AAEtE,QAAO,QAAQ,SAAS,KAAK,MAAM,QAAQ,KAAK,KAAK,CAAC,IAAI;AAC3D;;;;;;;;;;;;;;;;;;;;;;;;;AA0BD,SAAgB,uBACdC,SACmB;AAEnB,0BAAyB;CAEzB,MAAM,EACJ,YACA,SAAS,WAAW,eACpB,iBAAiB,CAAE,GACpB,GAAG;CAGJ,MAAM,WAAW;EAAE,GAAG;EAA0B,GAAG;CAAgB;CAEnE,IAAIC,MAAiC;CACrC,MAAM,aAAa,UAAU;EAAC;EAAW;EAAQ;CAAmB,EAAC;CAErE,MAAMC,OAA0B,CAACJ,WAAsB;AACrD,OAAK,KAAK;AACR,SAAM,IAAI,mBAAmB;AAC7B,OAAI;AACF,QAAI,YAAY;GACjB,SAAQ,OAAO;AACd,eAAW,MACT,uDACA,EAAE,MAAO,EACV;AACD,UAAM;AACN;GACD;EACF;EAGD,MAAM,UAAU,cAAc,OAAO;EACrC,MAAM,UAAU,cAAc,OAAO;EACrC,MAAM,cAAc,UAAU;EAG9B,MAAM,YAAY,uBAAuB,OAAO,MAAM;EACtD,MAAM,UAAU,SAAS,OAAO;AAGhC,MAAI,IACF,KAAI;AACF,OAAI,WAAW,WAAW,SAAS,YAAY;EAChD,SAAQ,OAAO;AACd,cAAW,MACT,iDACA,EAAE,MAAO,EACV;EACF;CAEJ;AAGD,MAAK,OAAO,WAAW,MAAM;AAC3B,MAAI,KAAK;AACP,OAAI,SAAS;AACb,SAAM;EACP;CACF;AAED,QAAO;AACR"}
|