@mostfeatured/dbi 0.2.13 → 0.2.15
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/dist/src/types/Components/HTMLComponentsV2/index.d.ts +33 -1
- package/dist/src/types/Components/HTMLComponentsV2/index.d.ts.map +1 -1
- package/dist/src/types/Components/HTMLComponentsV2/index.js +408 -82
- package/dist/src/types/Components/HTMLComponentsV2/index.js.map +1 -1
- package/dist/src/types/Components/HTMLComponentsV2/parser.d.ts +52 -0
- package/dist/src/types/Components/HTMLComponentsV2/parser.d.ts.map +1 -1
- package/dist/src/types/Components/HTMLComponentsV2/parser.js +275 -0
- package/dist/src/types/Components/HTMLComponentsV2/parser.js.map +1 -1
- package/dist/src/types/Components/HTMLComponentsV2/svelteParser.d.ts +26 -0
- package/dist/src/types/Components/HTMLComponentsV2/svelteParser.d.ts.map +1 -1
- package/dist/src/types/Components/HTMLComponentsV2/svelteParser.js +509 -34
- package/dist/src/types/Components/HTMLComponentsV2/svelteParser.js.map +1 -1
- package/dist/src/types/Components/HTMLComponentsV2/svelteRenderer.d.ts +10 -0
- package/dist/src/types/Components/HTMLComponentsV2/svelteRenderer.d.ts.map +1 -1
- package/dist/src/types/Components/HTMLComponentsV2/svelteRenderer.js +76 -11
- package/dist/src/types/Components/HTMLComponentsV2/svelteRenderer.js.map +1 -1
- package/dist/test/index.js +76 -3
- package/dist/test/index.js.map +1 -1
- package/docs/ADVANCED_FEATURES.md +4 -0
- package/docs/API_REFERENCE.md +4 -0
- package/docs/CHAT_INPUT.md +4 -0
- package/docs/COMPONENTS.md +4 -0
- package/docs/EVENTS.md +4 -0
- package/docs/GETTING_STARTED.md +4 -0
- package/docs/LOCALIZATION.md +4 -0
- package/docs/README.md +4 -0
- package/docs/SVELTE_COMPONENTS.md +162 -6
- package/docs/llm/ADVANCED_FEATURES.txt +521 -0
- package/docs/llm/API_REFERENCE.txt +659 -0
- package/docs/llm/CHAT_INPUT.txt +514 -0
- package/docs/llm/COMPONENTS.txt +595 -0
- package/docs/llm/EVENTS.txt +449 -0
- package/docs/llm/GETTING_STARTED.txt +296 -0
- package/docs/llm/LOCALIZATION.txt +501 -0
- package/docs/llm/README.txt +193 -0
- package/docs/llm/SVELTE_COMPONENTS.txt +566 -0
- package/generated/svelte-dbi.d.ts +122 -0
- package/package.json +1 -1
- package/src/types/Components/HTMLComponentsV2/index.ts +466 -94
- package/src/types/Components/HTMLComponentsV2/parser.ts +317 -0
- package/src/types/Components/HTMLComponentsV2/svelteParser.ts +567 -35
- package/src/types/Components/HTMLComponentsV2/svelteRenderer.ts +91 -13
- package/test/index.ts +76 -3
- package/test/product-showcase.svelte +380 -24
- package/llm.txt +0 -1088
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
================================================================================
|
|
2
|
+
DBI - EVENTS GUIDE - LLM REFERENCE DOCUMENT
|
|
3
|
+
================================================================================
|
|
4
|
+
|
|
5
|
+
DOCUMENT TYPE: Event System Reference
|
|
6
|
+
PACKAGE: @mostfeatured/dbi
|
|
7
|
+
|
|
8
|
+
================================================================================
|
|
9
|
+
SECTION 1: BASIC EVENTS
|
|
10
|
+
================================================================================
|
|
11
|
+
|
|
12
|
+
SIMPLE EVENT HANDLER:
|
|
13
|
+
---------------------
|
|
14
|
+
dbi.register(({ Event }) => {
|
|
15
|
+
Event({
|
|
16
|
+
name: "clientReady",
|
|
17
|
+
id: "ready-logger",
|
|
18
|
+
onExecute({ client }) {
|
|
19
|
+
console.log(`Bot is online as ${client.user.tag}`);
|
|
20
|
+
console.log(`Serving ${client.guilds.cache.size} guilds`);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
EVENT PARAMETERS FORMAT:
|
|
26
|
+
------------------------
|
|
27
|
+
Event parameters are received in an object format:
|
|
28
|
+
|
|
29
|
+
// Message events
|
|
30
|
+
Event({
|
|
31
|
+
name: "messageCreate",
|
|
32
|
+
id: "message-logger",
|
|
33
|
+
onExecute({ message }) {
|
|
34
|
+
if (message.author.bot) return;
|
|
35
|
+
console.log(`${message.author.tag}: ${message.content}`);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Member events
|
|
40
|
+
Event({
|
|
41
|
+
name: "guildMemberAdd",
|
|
42
|
+
id: "welcome-handler",
|
|
43
|
+
async onExecute({ member }) {
|
|
44
|
+
const channel = member.guild.systemChannel;
|
|
45
|
+
if (channel) {
|
|
46
|
+
await channel.send(`Welcome ${member}!`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Reaction events
|
|
52
|
+
Event({
|
|
53
|
+
name: "messageReactionAdd",
|
|
54
|
+
id: "reaction-roles",
|
|
55
|
+
onExecute({ reaction, user }) {
|
|
56
|
+
if (user.bot) return;
|
|
57
|
+
console.log(`${user.tag} reacted with ${reaction.emoji.name}`);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
================================================================================
|
|
62
|
+
SECTION 2: COMMON EVENTS REFERENCE
|
|
63
|
+
================================================================================
|
|
64
|
+
|
|
65
|
+
EVENT NAME | PARAMETERS | DESCRIPTION
|
|
66
|
+
--------------------|-------------------------------|------------------------
|
|
67
|
+
clientReady | { client } | Bot connected and ready
|
|
68
|
+
messageCreate | { message } | New message received
|
|
69
|
+
messageDelete | { message } | Message was deleted
|
|
70
|
+
messageUpdate | { oldMessage, newMessage } | Message was edited
|
|
71
|
+
guildCreate | { guild } | Bot joined a guild
|
|
72
|
+
guildDelete | { guild } | Bot left a guild
|
|
73
|
+
guildMemberAdd | { member } | Member joined guild
|
|
74
|
+
guildMemberRemove | { member } | Member left guild
|
|
75
|
+
guildMemberUpdate | { oldMember, newMember } | Member updated
|
|
76
|
+
interactionCreate | { interaction } | Any interaction received
|
|
77
|
+
voiceStateUpdate | { oldState, newState } | Voice state changed
|
|
78
|
+
channelCreate | { channel } | Channel created
|
|
79
|
+
channelDelete | { channel } | Channel deleted
|
|
80
|
+
roleCreate | { role } | Role created
|
|
81
|
+
roleDelete | { role } | Role deleted
|
|
82
|
+
|
|
83
|
+
================================================================================
|
|
84
|
+
SECTION 3: MULTIPLE EVENT HANDLERS
|
|
85
|
+
================================================================================
|
|
86
|
+
|
|
87
|
+
You can register multiple handlers for the same event using unique IDs:
|
|
88
|
+
|
|
89
|
+
dbi.register(({ Event }) => {
|
|
90
|
+
// First handler - logging
|
|
91
|
+
Event({
|
|
92
|
+
name: "messageCreate",
|
|
93
|
+
id: "message-logger",
|
|
94
|
+
onExecute({ message }) {
|
|
95
|
+
console.log(`Message: ${message.id}`);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Second handler - auto-moderation
|
|
100
|
+
Event({
|
|
101
|
+
name: "messageCreate",
|
|
102
|
+
id: "auto-mod",
|
|
103
|
+
onExecute({ message }) {
|
|
104
|
+
if (containsBadWords(message.content)) {
|
|
105
|
+
message.delete();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Third handler - leveling system
|
|
111
|
+
Event({
|
|
112
|
+
name: "messageCreate",
|
|
113
|
+
id: "leveling",
|
|
114
|
+
async onExecute({ message }) {
|
|
115
|
+
if (message.author.bot) return;
|
|
116
|
+
await addXP(message.author.id, 10);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
TOGGLING EVENT HANDLERS:
|
|
122
|
+
------------------------
|
|
123
|
+
const handler = dbi.event("togglable-logger");
|
|
124
|
+
|
|
125
|
+
handler.toggle(); // Toggle state
|
|
126
|
+
handler.toggle(true); // Disable
|
|
127
|
+
handler.toggle(false); // Enable
|
|
128
|
+
|
|
129
|
+
console.log(handler.disabled); // Check state
|
|
130
|
+
|
|
131
|
+
================================================================================
|
|
132
|
+
SECTION 4: EVENT CONFIGURATION
|
|
133
|
+
================================================================================
|
|
134
|
+
|
|
135
|
+
TRIGGER TYPES (for multi-client):
|
|
136
|
+
---------------------------------
|
|
137
|
+
Event({
|
|
138
|
+
name: "messageCreate",
|
|
139
|
+
id: "my-handler",
|
|
140
|
+
triggerType: "OneByOneGlobal", // Default
|
|
141
|
+
onExecute({ message, nextClient }) {
|
|
142
|
+
console.log(`Handled by: ${nextClient?.namespace}`);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
TRIGGER TYPE OPTIONS:
|
|
147
|
+
---------------------
|
|
148
|
+
TYPE | DESCRIPTION
|
|
149
|
+
----------------|------------------------------------------
|
|
150
|
+
OneByOne | Each client triggers sequentially
|
|
151
|
+
OneByOneGlobal | Global sequential (default)
|
|
152
|
+
Random | Random client handles
|
|
153
|
+
First | First client only
|
|
154
|
+
|
|
155
|
+
ORDERED EXECUTION:
|
|
156
|
+
------------------
|
|
157
|
+
Event({
|
|
158
|
+
name: "messageCreate",
|
|
159
|
+
id: "ordered-handler",
|
|
160
|
+
ordered: {
|
|
161
|
+
await: true, // Wait for async completion
|
|
162
|
+
delayBefore: 100, // Wait 100ms before executing
|
|
163
|
+
delayAfter: 50 // Wait 50ms after executing
|
|
164
|
+
},
|
|
165
|
+
async onExecute({ message }) {
|
|
166
|
+
await doAsyncWork(message);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
CONDITIONAL LOADING WITH FLAGS:
|
|
171
|
+
-------------------------------
|
|
172
|
+
Event({
|
|
173
|
+
name: "messageCreate",
|
|
174
|
+
id: "debug-logger",
|
|
175
|
+
flag: "debug",
|
|
176
|
+
onExecute({ message }) {
|
|
177
|
+
console.log("[DEBUG]", message);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Load with debug events
|
|
182
|
+
await dbi.load("debug");
|
|
183
|
+
|
|
184
|
+
// Load without debug events
|
|
185
|
+
await dbi.load();
|
|
186
|
+
|
|
187
|
+
EVENT TTL (INLINE EVENTS):
|
|
188
|
+
--------------------------
|
|
189
|
+
createInlineEvent({
|
|
190
|
+
name: "messageCreate",
|
|
191
|
+
ttl: 60000, // Auto-remove after 1 minute
|
|
192
|
+
onExecute({ message }) {
|
|
193
|
+
if (message.content === "special") {
|
|
194
|
+
message.reply("You found it!");
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
================================================================================
|
|
200
|
+
SECTION 5: CUSTOM EVENTS
|
|
201
|
+
================================================================================
|
|
202
|
+
|
|
203
|
+
DEFINING CUSTOM EVENTS:
|
|
204
|
+
-----------------------
|
|
205
|
+
dbi.register(({ CustomEvent, Event }) => {
|
|
206
|
+
// Define custom event structure
|
|
207
|
+
CustomEvent({
|
|
208
|
+
name: "userLevelUp",
|
|
209
|
+
map: {
|
|
210
|
+
userId: "userId",
|
|
211
|
+
newLevel: "newLevel",
|
|
212
|
+
guild: "guild"
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// Listen for custom event
|
|
217
|
+
Event({
|
|
218
|
+
name: "userLevelUp",
|
|
219
|
+
id: "levelup-announcer",
|
|
220
|
+
onExecute({ userId, newLevel, guild }) {
|
|
221
|
+
const channel = guild.systemChannel;
|
|
222
|
+
if (channel) {
|
|
223
|
+
channel.send(`<@${userId}> reached level ${newLevel}!`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
TRIGGERING CUSTOM EVENTS:
|
|
230
|
+
-------------------------
|
|
231
|
+
dbi.emit("userLevelUp", {
|
|
232
|
+
userId: "123456789",
|
|
233
|
+
newLevel: 10,
|
|
234
|
+
guild: someGuild
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
// Or using the returned object
|
|
238
|
+
const levelUpEvent = CustomEvent({
|
|
239
|
+
name: "playerLevelUp",
|
|
240
|
+
map: { playerId: "playerId", level: "level", rewards: "rewards" }
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
levelUpEvent.trigger({
|
|
244
|
+
playerId: "12345",
|
|
245
|
+
level: 5,
|
|
246
|
+
rewards: ["gold", "exp_boost"]
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
================================================================================
|
|
250
|
+
SECTION 6: DBI INTERNAL EVENTS
|
|
251
|
+
================================================================================
|
|
252
|
+
|
|
253
|
+
AVAILABLE DBI EVENTS:
|
|
254
|
+
---------------------
|
|
255
|
+
EVENT | DESCRIPTION
|
|
256
|
+
-----------------------------------------|----------------------------
|
|
257
|
+
clientsReady | All clients connected
|
|
258
|
+
beforeInteraction | Before handling interaction
|
|
259
|
+
afterInteraction | After handling interaction
|
|
260
|
+
interactionError | Error during interaction
|
|
261
|
+
interactionRateLimit | Rate limit triggered
|
|
262
|
+
beforeEvent | Before event handler
|
|
263
|
+
afterEvent | After event handler
|
|
264
|
+
eventError | Error during event
|
|
265
|
+
messageCommandArgumentError | Invalid message command arg
|
|
266
|
+
messageCommandDirectMessageUsageError | DM command not allowed
|
|
267
|
+
messageCommandDefaultMemberPermissionsError | Missing permissions
|
|
268
|
+
|
|
269
|
+
BEFORE/AFTER INTERACTION:
|
|
270
|
+
-------------------------
|
|
271
|
+
dbi.events.on("beforeInteraction", async (ctx) => {
|
|
272
|
+
console.log(`Interaction: ${ctx.dbiInteraction.name}`);
|
|
273
|
+
console.log(`User: ${ctx.interaction.user.tag}`);
|
|
274
|
+
return true; // Return true to continue, false to stop
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
dbi.events.on("afterInteraction", async (ctx) => {
|
|
278
|
+
console.log(`Completed: ${ctx.dbiInteraction.name}`);
|
|
279
|
+
return true;
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
ERROR HANDLING:
|
|
283
|
+
---------------
|
|
284
|
+
dbi.events.on("interactionError", async ({ interaction, dbiInteraction, error }) => {
|
|
285
|
+
console.error(`Error in ${dbiInteraction.name}:`, error);
|
|
286
|
+
|
|
287
|
+
try {
|
|
288
|
+
if (interaction.replied || interaction.deferred) {
|
|
289
|
+
await interaction.followUp({
|
|
290
|
+
content: "An error occurred.",
|
|
291
|
+
ephemeral: true
|
|
292
|
+
});
|
|
293
|
+
} else {
|
|
294
|
+
await interaction.reply({
|
|
295
|
+
content: "An error occurred.",
|
|
296
|
+
ephemeral: true
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
} catch (e) {
|
|
300
|
+
console.error("Could not send error message:", e);
|
|
301
|
+
}
|
|
302
|
+
return true;
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
dbi.events.on("eventError", async ({ eventName, dbiEvent, error }) => {
|
|
306
|
+
console.error(`Error in event ${eventName}:`, error);
|
|
307
|
+
return true;
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
RATE LIMITING:
|
|
311
|
+
--------------
|
|
312
|
+
dbi.events.on("interactionRateLimit", async ({
|
|
313
|
+
interaction,
|
|
314
|
+
dbiInteraction,
|
|
315
|
+
rateLimit,
|
|
316
|
+
remainingTime
|
|
317
|
+
}) => {
|
|
318
|
+
const seconds = Math.ceil(remainingTime / 1000);
|
|
319
|
+
|
|
320
|
+
await interaction.reply({
|
|
321
|
+
content: `Slow down! Try again in ${seconds} seconds.`,
|
|
322
|
+
ephemeral: true
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
return false; // Don't execute the interaction
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
MESSAGE COMMAND ERRORS:
|
|
329
|
+
-----------------------
|
|
330
|
+
const { ApplicationCommandOptionType } = require("discord.js");
|
|
331
|
+
|
|
332
|
+
dbi.events.on("messageCommandArgumentError", ({
|
|
333
|
+
message, interaction, dbiInteraction, error
|
|
334
|
+
}) => {
|
|
335
|
+
message.reply(
|
|
336
|
+
`Invalid argument \`${error.option.name}\` (Index: ${error.index}).\n` +
|
|
337
|
+
`Error: \`${error.type}\`\n` +
|
|
338
|
+
`Expected: \`${ApplicationCommandOptionType[error.option.type]}\``
|
|
339
|
+
);
|
|
340
|
+
return false;
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
dbi.events.on("messageCommandDirectMessageUsageError", ({ message }) => {
|
|
344
|
+
message.reply("This command cannot be used in DMs.");
|
|
345
|
+
return false;
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
dbi.events.on("messageCommandDefaultMemberPermissionsError", ({ message, permissions }) => {
|
|
349
|
+
message.reply(`You need these permissions: ${permissions.join(", ")}`);
|
|
350
|
+
return false;
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
ONE-TIME EVENT HANDLERS:
|
|
354
|
+
------------------------
|
|
355
|
+
dbi.events.on("clientsReady", () => {
|
|
356
|
+
console.log("Bot is ready!");
|
|
357
|
+
}, { once: true });
|
|
358
|
+
|
|
359
|
+
REMOVING EVENT HANDLERS:
|
|
360
|
+
------------------------
|
|
361
|
+
const removeHandler = dbi.events.on("beforeInteraction", (ctx) => {
|
|
362
|
+
console.log("Interaction received");
|
|
363
|
+
return true;
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// Later, remove the handler
|
|
367
|
+
removeHandler();
|
|
368
|
+
|
|
369
|
+
================================================================================
|
|
370
|
+
SECTION 7: EVENT FLOW
|
|
371
|
+
================================================================================
|
|
372
|
+
|
|
373
|
+
INTERACTION FLOW:
|
|
374
|
+
1. Discord sends interaction
|
|
375
|
+
2. beforeInteraction event fires
|
|
376
|
+
3. Rate limit check
|
|
377
|
+
4. interactionRateLimit event if limited
|
|
378
|
+
5. Interaction handler executes
|
|
379
|
+
6. afterInteraction event fires
|
|
380
|
+
7. If error: interactionError event fires
|
|
381
|
+
|
|
382
|
+
EVENT FLOW:
|
|
383
|
+
1. Discord sends event
|
|
384
|
+
2. beforeEvent event fires
|
|
385
|
+
3. Event handler executes
|
|
386
|
+
4. afterEvent event fires
|
|
387
|
+
5. If error: eventError event fires
|
|
388
|
+
|
|
389
|
+
================================================================================
|
|
390
|
+
SECTION 8: BEST PRACTICES
|
|
391
|
+
================================================================================
|
|
392
|
+
|
|
393
|
+
// GOOD - Use specific event IDs
|
|
394
|
+
Event({
|
|
395
|
+
name: "messageCreate",
|
|
396
|
+
id: "spam-filter-v1",
|
|
397
|
+
onExecute({ message }) { /* ... */ }
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
// BAD - Missing ID causes conflicts
|
|
401
|
+
Event({
|
|
402
|
+
name: "messageCreate",
|
|
403
|
+
// No ID - will throw error if strict mode is on
|
|
404
|
+
onExecute({ message }) { /* ... */ }
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
// GOOD - Return early from bot messages
|
|
408
|
+
Event({
|
|
409
|
+
name: "messageCreate",
|
|
410
|
+
id: "my-handler",
|
|
411
|
+
onExecute({ message }) {
|
|
412
|
+
if (message.author.bot) return;
|
|
413
|
+
// Handle user messages
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
// GOOD - Use async/await properly
|
|
418
|
+
Event({
|
|
419
|
+
name: "guildMemberAdd",
|
|
420
|
+
id: "welcome",
|
|
421
|
+
async onExecute({ member }) {
|
|
422
|
+
try {
|
|
423
|
+
await member.send("Welcome!");
|
|
424
|
+
} catch (error) {
|
|
425
|
+
console.error("Could not DM member:", error);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
================================================================================
|
|
431
|
+
SECTION 9: GUILD LOCALE IN EVENTS
|
|
432
|
+
================================================================================
|
|
433
|
+
|
|
434
|
+
dbi.register(({ Event }) => {
|
|
435
|
+
Event({
|
|
436
|
+
name: "messageCreate",
|
|
437
|
+
id: "localized-response",
|
|
438
|
+
onExecute({ message, locale }) {
|
|
439
|
+
if (message.content === "!hello") {
|
|
440
|
+
const greeting = locale?.guild?.data?.greeting?.() || "Hello!";
|
|
441
|
+
message.reply(greeting);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
================================================================================
|
|
448
|
+
END OF DOCUMENT
|
|
449
|
+
================================================================================
|