@prosopo/types-database 4.1.5 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build$colon$cjs.log +16 -12
- package/.turbo/turbo-build$colon$tsc.log +17 -14
- package/.turbo/turbo-build.log +17 -13
- package/CHANGELOG.md +506 -0
- package/dist/cjs/index.cjs +6 -7
- package/dist/cjs/types/bannedDomain.cjs +8 -0
- package/dist/cjs/types/client.cjs +77 -5
- package/dist/cjs/types/index.cjs +6 -7
- package/dist/cjs/types/provider.cjs +298 -88
- package/dist/cjs/types/spamEmailDomain.cjs +8 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -9
- package/dist/types/bannedDomain.d.ts +15 -0
- package/dist/types/bannedDomain.d.ts.map +1 -0
- package/dist/types/bannedDomain.js +8 -0
- package/dist/types/bannedDomain.js.map +1 -0
- package/dist/types/captcha.d.ts +2 -2
- package/dist/types/captcha.d.ts.map +1 -1
- package/dist/types/captcha.js.map +1 -1
- package/dist/types/client.d.ts +111 -12
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/client.js +78 -6
- package/dist/types/client.js.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +8 -9
- package/dist/types/index.js.map +1 -1
- package/dist/types/mongo.d.ts +1 -1
- package/dist/types/provider.d.ts +59 -463
- package/dist/types/provider.d.ts.map +1 -1
- package/dist/types/provider.js +300 -90
- package/dist/types/provider.js.map +1 -1
- package/dist/types/spamEmailDomain.d.ts +15 -0
- package/dist/types/spamEmailDomain.d.ts.map +1 -0
- package/dist/types/spamEmailDomain.js +8 -0
- package/dist/types/spamEmailDomain.js.map +1 -0
- package/package.json +9 -7
- package/dist/provider/pendingCaptchaRequest.d.ts +0 -14
- package/dist/provider/pendingCaptchaRequest.d.ts.map +0 -1
- package/dist/provider/pendingCaptchaRequest.js +0 -2
- package/dist/provider/pendingCaptchaRequest.js.map +0 -1
package/dist/cjs/types/index.cjs
CHANGED
|
@@ -5,26 +5,23 @@ const provider = require("./provider.cjs");
|
|
|
5
5
|
const client = require("./client.cjs");
|
|
6
6
|
const captcha = require("./captcha.cjs");
|
|
7
7
|
require("./userAgent.cjs");
|
|
8
|
+
const spamEmailDomain = require("./spamEmailDomain.cjs");
|
|
9
|
+
const bannedDomain = require("./bannedDomain.cjs");
|
|
8
10
|
exports.CaptchaRecordSchema = provider.CaptchaRecordSchema;
|
|
9
11
|
exports.ClientContextEntropyRecordSchema = provider.ClientContextEntropyRecordSchema;
|
|
10
12
|
exports.ClientRecordSchema = provider.ClientRecordSchema;
|
|
11
13
|
exports.CompositeIpAddressRecordSchemaObj = provider.CompositeIpAddressRecordSchemaObj;
|
|
12
|
-
exports.CompositeIpAddressSchema = provider.CompositeIpAddressSchema;
|
|
13
14
|
exports.DatasetRecordSchema = provider.DatasetRecordSchema;
|
|
15
|
+
exports.DecisionMachineArtifactRecordSchema = provider.DecisionMachineArtifactRecordSchema;
|
|
14
16
|
exports.DetectorRecordSchema = provider.DetectorRecordSchema;
|
|
15
|
-
exports.IpAddressType = provider.IpAddressType;
|
|
16
|
-
exports.PendingRecordSchema = provider.PendingRecordSchema;
|
|
17
17
|
exports.PoWCaptchaRecordSchema = provider.PoWCaptchaRecordSchema;
|
|
18
|
+
exports.PuzzleCaptchaRecordSchema = provider.PuzzleCaptchaRecordSchema;
|
|
18
19
|
exports.ScheduledTaskRecordSchema = provider.ScheduledTaskRecordSchema;
|
|
19
20
|
exports.ScheduledTaskSchema = provider.ScheduledTaskSchema;
|
|
20
21
|
exports.SessionRecordSchema = provider.SessionRecordSchema;
|
|
21
22
|
exports.SolutionRecordSchema = provider.SolutionRecordSchema;
|
|
22
23
|
exports.UserCommitmentRecordSchema = provider.UserCommitmentRecordSchema;
|
|
23
|
-
exports.UserCommitmentSchema = provider.UserCommitmentSchema;
|
|
24
|
-
exports.UserCommitmentWithSolutionsSchema = provider.UserCommitmentWithSolutionsSchema;
|
|
25
24
|
exports.UserSolutionRecordSchema = provider.UserSolutionRecordSchema;
|
|
26
|
-
exports.UserSolutionSchema = provider.UserSolutionSchema;
|
|
27
|
-
exports.parseMongooseCompositeIpAddress = provider.parseMongooseCompositeIpAddress;
|
|
28
25
|
exports.AccountSchema = client.AccountSchema;
|
|
29
26
|
exports.IPValidationRulesSchema = client.IPValidationRulesSchema;
|
|
30
27
|
exports.TableNames = client.TableNames;
|
|
@@ -33,3 +30,5 @@ exports.UserSettingsSchema = client.UserSettingsSchema;
|
|
|
33
30
|
exports.StoredPoWCaptchaRecordSchema = captcha.StoredPoWCaptchaRecordSchema;
|
|
34
31
|
exports.StoredSessionRecordSchema = captcha.StoredSessionRecordSchema;
|
|
35
32
|
exports.StoredUserCommitmentRecordSchema = captcha.StoredUserCommitmentRecordSchema;
|
|
33
|
+
exports.SpamEmailDomainRecordSchema = spamEmailDomain.SpamEmailDomainRecordSchema;
|
|
34
|
+
exports.BannedDomainRecordSchema = bannedDomain.BannedDomainRecordSchema;
|
|
@@ -9,23 +9,12 @@ const ONE_HOUR = 60 * 60;
|
|
|
9
9
|
const ONE_DAY = ONE_HOUR * 24;
|
|
10
10
|
const ONE_WEEK = ONE_DAY * 7;
|
|
11
11
|
const ONE_MONTH = ONE_WEEK * 4;
|
|
12
|
-
const TEN_MINUTES = 10 * 60;
|
|
13
12
|
const ClientRecordSchema = new mongoose.Schema({
|
|
14
13
|
account: String,
|
|
15
14
|
settings: client.UserSettingsSchema,
|
|
16
15
|
tier: { type: String, enum: types.Tier, required: true }
|
|
17
16
|
});
|
|
18
17
|
ClientRecordSchema.index({ account: 1 });
|
|
19
|
-
var IpAddressType = /* @__PURE__ */ ((IpAddressType2) => {
|
|
20
|
-
IpAddressType2["v4"] = "v4";
|
|
21
|
-
IpAddressType2["v6"] = "v6";
|
|
22
|
-
return IpAddressType2;
|
|
23
|
-
})(IpAddressType || {});
|
|
24
|
-
const CompositeIpAddressSchema = zod.object({
|
|
25
|
-
lower: zod.bigint(),
|
|
26
|
-
upper: zod.bigint().optional(),
|
|
27
|
-
type: zod.nativeEnum(IpAddressType)
|
|
28
|
-
});
|
|
29
18
|
const CompositeIpAddressRecordSchemaObj = {
|
|
30
19
|
lower: {
|
|
31
20
|
// INT64 isn't enough capable - it reserves extra bits for the sign bit, etc, so Decimal128 guarantees no overflow
|
|
@@ -41,40 +30,8 @@ const CompositeIpAddressRecordSchemaObj = {
|
|
|
41
30
|
// without casting to string Mongoose not able to set bigint to Decimal128
|
|
42
31
|
set: (value) => "bigint" === typeof value ? value.toString() : value
|
|
43
32
|
},
|
|
44
|
-
type: { type: String, enum: IpAddressType, required: true }
|
|
45
|
-
};
|
|
46
|
-
const parseMongooseCompositeIpAddress = (ip) => {
|
|
47
|
-
return {
|
|
48
|
-
lower: BigInt(ip.lower.$numberDecimal ?? ip.lower),
|
|
49
|
-
upper: ip.upper ? BigInt(ip.upper?.$numberDecimal ?? ip.upper) : void 0,
|
|
50
|
-
type: ip.type
|
|
51
|
-
};
|
|
33
|
+
type: { type: String, enum: types.IpAddressType, required: true }
|
|
52
34
|
};
|
|
53
|
-
const CaptchaResultSchema = zod.object({
|
|
54
|
-
status: zod.nativeEnum(types.CaptchaStatus),
|
|
55
|
-
reason: locale.TranslationKeysSchema.optional(),
|
|
56
|
-
error: zod.string().optional()
|
|
57
|
-
});
|
|
58
|
-
const UserCommitmentSchema = zod.object({
|
|
59
|
-
userAccount: zod.string(),
|
|
60
|
-
dappAccount: zod.string(),
|
|
61
|
-
datasetId: zod.string(),
|
|
62
|
-
providerAccount: zod.string(),
|
|
63
|
-
id: zod.string(),
|
|
64
|
-
result: CaptchaResultSchema,
|
|
65
|
-
userSignature: zod.string(),
|
|
66
|
-
ipAddress: CompositeIpAddressSchema,
|
|
67
|
-
providedIp: CompositeIpAddressSchema.optional(),
|
|
68
|
-
headers: zod.object({}).catchall(zod.string()),
|
|
69
|
-
ja4: zod.string(),
|
|
70
|
-
userSubmitted: zod.boolean(),
|
|
71
|
-
serverChecked: zod.boolean(),
|
|
72
|
-
storedAtTimestamp: zod.date().optional(),
|
|
73
|
-
requestedAtTimestamp: zod.date(),
|
|
74
|
-
lastUpdatedTimestamp: zod.date().optional(),
|
|
75
|
-
sessionId: zod.string().optional(),
|
|
76
|
-
coords: zod.array(zod.array(zod.array(zod.number()))).optional()
|
|
77
|
-
});
|
|
78
35
|
const CaptchaRecordSchema = new mongoose.Schema({
|
|
79
36
|
captchaId: { type: String, required: true },
|
|
80
37
|
captchaContentId: { type: String, required: true },
|
|
@@ -122,24 +79,38 @@ const PoWCaptchaRecordSchema = new mongoose.Schema({
|
|
|
122
79
|
type: new mongoose.Schema(CompositeIpAddressRecordSchemaObj, { _id: false }),
|
|
123
80
|
required: false
|
|
124
81
|
},
|
|
82
|
+
metadata: {
|
|
83
|
+
type: new mongoose.Schema(
|
|
84
|
+
{ email: { type: String, required: false } },
|
|
85
|
+
{ _id: false }
|
|
86
|
+
),
|
|
87
|
+
required: false
|
|
88
|
+
},
|
|
89
|
+
clientMetaData: {
|
|
90
|
+
type: new mongoose.Schema({ hp: { type: String, required: false } }, { _id: false }),
|
|
91
|
+
required: false
|
|
92
|
+
},
|
|
125
93
|
headers: { type: Object, required: true },
|
|
126
94
|
ja4: { type: String, required: true },
|
|
127
95
|
userSignature: { type: String, required: false },
|
|
128
96
|
userSubmitted: { type: Boolean, required: true },
|
|
129
97
|
serverChecked: { type: Boolean, required: true },
|
|
130
98
|
storedAtTimestamp: { type: Date, required: false, expires: ONE_MONTH },
|
|
131
|
-
|
|
132
|
-
|
|
99
|
+
// See `StoredCaptcha.pendingStage` — `true` while the record has
|
|
100
|
+
// unstaged changes. Indexed via a tiny partial index so the
|
|
101
|
+
// StoreCommitmentsExternal sweep scans only pending rows instead of
|
|
102
|
+
// the whole collection.
|
|
103
|
+
pendingStage: { type: Boolean, required: false },
|
|
104
|
+
// Full ipinfo payload. Replaces the flat `vpn`, `countryCode`,
|
|
105
|
+
// `geolocation` and other per-flag fields — consumers narrow on
|
|
106
|
+
// `ipInfo.isValid` and read whichever sub-field they need.
|
|
107
|
+
ipInfo: { type: Object, required: false },
|
|
133
108
|
parsedUserAgentInfo: { type: Object, required: false },
|
|
134
109
|
sessionId: {
|
|
135
110
|
type: String,
|
|
136
111
|
required: false
|
|
137
112
|
},
|
|
138
113
|
coords: { type: [[[Number]]], required: false },
|
|
139
|
-
// Legacy fields - kept for backward compatibility with existing data
|
|
140
|
-
mouseEvents: { type: [Object], required: false },
|
|
141
|
-
touchEvents: { type: [Object], required: false },
|
|
142
|
-
clickEvents: { type: [Object], required: false },
|
|
143
114
|
// Current behavioral data storage format (packed)
|
|
144
115
|
deviceCapability: { type: String, required: false },
|
|
145
116
|
behavioralDataPacked: {
|
|
@@ -150,14 +121,129 @@ const PoWCaptchaRecordSchema = new mongoose.Schema({
|
|
|
150
121
|
d: { type: String, required: true }
|
|
151
122
|
},
|
|
152
123
|
required: false
|
|
153
|
-
}
|
|
124
|
+
},
|
|
125
|
+
providerSignature: { type: String, required: true },
|
|
126
|
+
// Internal ML labelling applied by superadmins via the audit page.
|
|
127
|
+
label: { type: String, enum: Object.values(types.CaptchaLabel), required: false },
|
|
128
|
+
labelReason: { type: String, required: false },
|
|
129
|
+
labelledBy: { type: String, required: false },
|
|
130
|
+
labelledAt: { type: Date, required: false }
|
|
154
131
|
});
|
|
155
132
|
PoWCaptchaRecordSchema.index({ challenge: 1 });
|
|
133
|
+
PoWCaptchaRecordSchema.index({ label: 1, dappAccount: 1 });
|
|
156
134
|
PoWCaptchaRecordSchema.index({ lastUpdatedTimestamp: 1 });
|
|
157
135
|
PoWCaptchaRecordSchema.index({ dappAccount: 1, requestedAtTimestamp: 1 });
|
|
158
136
|
PoWCaptchaRecordSchema.index({ "ipAddress.lower": 1 });
|
|
159
137
|
PoWCaptchaRecordSchema.index({ "ipAddress.upper": 1 });
|
|
160
138
|
PoWCaptchaRecordSchema.index({ "result.reason": 1 });
|
|
139
|
+
PoWCaptchaRecordSchema.index({ "ipInfo.countryCode": 1 });
|
|
140
|
+
PoWCaptchaRecordSchema.index({ "ipInfo.isVPN": 1 });
|
|
141
|
+
PoWCaptchaRecordSchema.index({ ipInfo: 1 });
|
|
142
|
+
PoWCaptchaRecordSchema.index({ parsedUserAgentInfo: 1 });
|
|
143
|
+
PoWCaptchaRecordSchema.index(
|
|
144
|
+
{ pendingStage: 1 },
|
|
145
|
+
{
|
|
146
|
+
name: "pendingStage_partial",
|
|
147
|
+
partialFilterExpression: { pendingStage: true }
|
|
148
|
+
}
|
|
149
|
+
);
|
|
150
|
+
const PuzzleCaptchaRecordSchema = new mongoose.Schema({
|
|
151
|
+
challenge: { type: String, required: true },
|
|
152
|
+
dappAccount: { type: String, required: true },
|
|
153
|
+
userAccount: { type: String, required: true },
|
|
154
|
+
requestedAtTimestamp: { type: Date, required: true },
|
|
155
|
+
lastUpdatedTimestamp: { type: Date, required: false },
|
|
156
|
+
result: {
|
|
157
|
+
status: { type: String, enum: types.CaptchaStatus, required: true },
|
|
158
|
+
reason: {
|
|
159
|
+
type: String,
|
|
160
|
+
enum: locale.TranslationKeysSchema.options,
|
|
161
|
+
required: false
|
|
162
|
+
},
|
|
163
|
+
error: { type: String, required: false }
|
|
164
|
+
},
|
|
165
|
+
targetX: { type: Number, required: true },
|
|
166
|
+
targetY: { type: Number, required: true },
|
|
167
|
+
originX: { type: Number, required: true },
|
|
168
|
+
originY: { type: Number, required: true },
|
|
169
|
+
tolerance: { type: Number, required: true },
|
|
170
|
+
puzzleEvents: {
|
|
171
|
+
type: [
|
|
172
|
+
new mongoose.Schema(
|
|
173
|
+
{
|
|
174
|
+
x: { type: Number, required: true },
|
|
175
|
+
y: { type: Number, required: true },
|
|
176
|
+
t: { type: Number, required: true }
|
|
177
|
+
},
|
|
178
|
+
{ _id: false }
|
|
179
|
+
)
|
|
180
|
+
],
|
|
181
|
+
required: false
|
|
182
|
+
},
|
|
183
|
+
ipAddress: CompositeIpAddressRecordSchemaObj,
|
|
184
|
+
providedIp: {
|
|
185
|
+
type: new mongoose.Schema(CompositeIpAddressRecordSchemaObj, { _id: false }),
|
|
186
|
+
required: false
|
|
187
|
+
},
|
|
188
|
+
metadata: {
|
|
189
|
+
type: new mongoose.Schema(
|
|
190
|
+
{ email: { type: String, required: false } },
|
|
191
|
+
{ _id: false }
|
|
192
|
+
),
|
|
193
|
+
required: false
|
|
194
|
+
},
|
|
195
|
+
clientMetaData: {
|
|
196
|
+
type: new mongoose.Schema({ hp: { type: String, required: false } }, { _id: false }),
|
|
197
|
+
required: false
|
|
198
|
+
},
|
|
199
|
+
headers: { type: Object, required: true },
|
|
200
|
+
ja4: { type: String, required: true },
|
|
201
|
+
userSignature: { type: String, required: false },
|
|
202
|
+
userSubmitted: { type: Boolean, required: true },
|
|
203
|
+
serverChecked: { type: Boolean, required: true },
|
|
204
|
+
storedAtTimestamp: { type: Date, required: false, expires: ONE_MONTH },
|
|
205
|
+
// See `StoredCaptcha.pendingStage`.
|
|
206
|
+
pendingStage: { type: Boolean, required: false },
|
|
207
|
+
// Full ipinfo payload. Replaces the flat `vpn`, `countryCode`,
|
|
208
|
+
// `geolocation` and other per-flag fields — consumers narrow on
|
|
209
|
+
// `ipInfo.isValid` and read whichever sub-field they need.
|
|
210
|
+
ipInfo: { type: Object, required: false },
|
|
211
|
+
parsedUserAgentInfo: { type: Object, required: false },
|
|
212
|
+
sessionId: {
|
|
213
|
+
type: String,
|
|
214
|
+
required: false
|
|
215
|
+
},
|
|
216
|
+
coords: { type: [[[Number]]], required: false },
|
|
217
|
+
// Current behavioral data storage format (packed)
|
|
218
|
+
deviceCapability: { type: String, required: false },
|
|
219
|
+
behavioralDataPacked: {
|
|
220
|
+
type: {
|
|
221
|
+
c1: { type: [mongoose.Schema.Types.Mixed], required: true },
|
|
222
|
+
c2: { type: [mongoose.Schema.Types.Mixed], required: true },
|
|
223
|
+
c3: { type: [mongoose.Schema.Types.Mixed], required: true },
|
|
224
|
+
d: { type: String, required: true }
|
|
225
|
+
},
|
|
226
|
+
required: false
|
|
227
|
+
},
|
|
228
|
+
providerSignature: { type: String, required: true }
|
|
229
|
+
});
|
|
230
|
+
PuzzleCaptchaRecordSchema.index({ challenge: 1 });
|
|
231
|
+
PuzzleCaptchaRecordSchema.index({ lastUpdatedTimestamp: 1 });
|
|
232
|
+
PuzzleCaptchaRecordSchema.index({ dappAccount: 1, requestedAtTimestamp: 1 });
|
|
233
|
+
PuzzleCaptchaRecordSchema.index({ "ipAddress.lower": 1 });
|
|
234
|
+
PuzzleCaptchaRecordSchema.index({ "ipAddress.upper": 1 });
|
|
235
|
+
PuzzleCaptchaRecordSchema.index({ "result.reason": 1 });
|
|
236
|
+
PuzzleCaptchaRecordSchema.index({ "ipInfo.countryCode": 1 });
|
|
237
|
+
PuzzleCaptchaRecordSchema.index({ "ipInfo.isVPN": 1 });
|
|
238
|
+
PuzzleCaptchaRecordSchema.index({ ipInfo: 1 });
|
|
239
|
+
PuzzleCaptchaRecordSchema.index({ parsedUserAgentInfo: 1 });
|
|
240
|
+
PuzzleCaptchaRecordSchema.index(
|
|
241
|
+
{ pendingStage: 1 },
|
|
242
|
+
{
|
|
243
|
+
name: "pendingStage_partial",
|
|
244
|
+
partialFilterExpression: { pendingStage: true }
|
|
245
|
+
}
|
|
246
|
+
);
|
|
161
247
|
const UserCommitmentRecordSchema = new mongoose.Schema({
|
|
162
248
|
userAccount: { type: String, required: true },
|
|
163
249
|
dappAccount: { type: String, required: true },
|
|
@@ -178,6 +264,17 @@ const UserCommitmentRecordSchema = new mongoose.Schema({
|
|
|
178
264
|
type: new mongoose.Schema(CompositeIpAddressRecordSchemaObj, { _id: false }),
|
|
179
265
|
required: false
|
|
180
266
|
},
|
|
267
|
+
metadata: {
|
|
268
|
+
type: new mongoose.Schema(
|
|
269
|
+
{ email: { type: String, required: false } },
|
|
270
|
+
{ _id: false }
|
|
271
|
+
),
|
|
272
|
+
required: false
|
|
273
|
+
},
|
|
274
|
+
clientMetaData: {
|
|
275
|
+
type: new mongoose.Schema({ hp: { type: String, required: false } }, { _id: false }),
|
|
276
|
+
required: false
|
|
277
|
+
},
|
|
181
278
|
headers: { type: Object, required: true },
|
|
182
279
|
ja4: { type: String, required: true },
|
|
183
280
|
userSignature: { type: String, required: true },
|
|
@@ -186,16 +283,43 @@ const UserCommitmentRecordSchema = new mongoose.Schema({
|
|
|
186
283
|
storedAtTimestamp: { type: Date, required: false, expires: ONE_MONTH },
|
|
187
284
|
requestedAtTimestamp: { type: Date, required: true },
|
|
188
285
|
lastUpdatedTimestamp: { type: Date, required: false },
|
|
189
|
-
|
|
190
|
-
|
|
286
|
+
// See `StoredCaptcha.pendingStage`.
|
|
287
|
+
pendingStage: { type: Boolean, required: false },
|
|
288
|
+
// Full ipinfo payload. Replaces the flat `vpn`, `countryCode`,
|
|
289
|
+
// `geolocation` and other per-flag fields — consumers narrow on
|
|
290
|
+
// `ipInfo.isValid` and read whichever sub-field they need.
|
|
291
|
+
ipInfo: { type: Object, required: false },
|
|
191
292
|
parsedUserAgentInfo: { type: Object, required: false },
|
|
192
293
|
sessionId: {
|
|
193
294
|
type: String,
|
|
194
295
|
required: false
|
|
195
296
|
},
|
|
196
|
-
coords: { type: [[[Number]]], required: false }
|
|
297
|
+
coords: { type: [[[Number]]], required: false },
|
|
298
|
+
// Pending request fields for image captcha workflow
|
|
299
|
+
pending: { type: Boolean, required: true },
|
|
300
|
+
salt: { type: String, required: true },
|
|
301
|
+
requestHash: { type: String, required: true },
|
|
302
|
+
deadlineTimestamp: { type: Date, required: true },
|
|
303
|
+
threshold: { type: Number, required: true },
|
|
304
|
+
// Current behavioral data storage format (packed)
|
|
305
|
+
deviceCapability: { type: String, required: false },
|
|
306
|
+
behavioralDataPacked: {
|
|
307
|
+
type: {
|
|
308
|
+
c1: { type: [mongoose.Schema.Types.Mixed], required: true },
|
|
309
|
+
c2: { type: [mongoose.Schema.Types.Mixed], required: true },
|
|
310
|
+
c3: { type: [mongoose.Schema.Types.Mixed], required: true },
|
|
311
|
+
d: { type: String, required: true }
|
|
312
|
+
},
|
|
313
|
+
required: false
|
|
314
|
+
},
|
|
315
|
+
// Internal ML labelling applied by superadmins via the audit page.
|
|
316
|
+
label: { type: String, enum: Object.values(types.CaptchaLabel), required: false },
|
|
317
|
+
labelReason: { type: String, required: false },
|
|
318
|
+
labelledBy: { type: String, required: false },
|
|
319
|
+
labelledAt: { type: Date, required: false }
|
|
197
320
|
});
|
|
198
321
|
UserCommitmentRecordSchema.index({ id: -1 });
|
|
322
|
+
UserCommitmentRecordSchema.index({ label: 1, dappAccount: 1 });
|
|
199
323
|
UserCommitmentRecordSchema.index({
|
|
200
324
|
lastUpdatedTimestamp: 1
|
|
201
325
|
});
|
|
@@ -203,6 +327,19 @@ UserCommitmentRecordSchema.index({ userAccount: 1, dappAccount: 1 });
|
|
|
203
327
|
UserCommitmentRecordSchema.index({ "ipAddress.lower": 1 });
|
|
204
328
|
UserCommitmentRecordSchema.index({ "ipAddress.upper": 1 });
|
|
205
329
|
UserCommitmentRecordSchema.index({ "result.reason": 1 });
|
|
330
|
+
UserCommitmentRecordSchema.index({ "ipInfo.countryCode": 1 });
|
|
331
|
+
UserCommitmentRecordSchema.index({ "ipInfo.isVPN": 1 });
|
|
332
|
+
UserCommitmentRecordSchema.index({ requestHash: -1 });
|
|
333
|
+
UserCommitmentRecordSchema.index({ pending: 1 });
|
|
334
|
+
UserCommitmentRecordSchema.index({ ipInfo: 1 });
|
|
335
|
+
UserCommitmentRecordSchema.index({ parsedUserAgentInfo: 1 });
|
|
336
|
+
UserCommitmentRecordSchema.index(
|
|
337
|
+
{ pendingStage: 1 },
|
|
338
|
+
{
|
|
339
|
+
name: "pendingStage_partial",
|
|
340
|
+
partialFilterExpression: { pendingStage: true }
|
|
341
|
+
}
|
|
342
|
+
);
|
|
206
343
|
const DatasetRecordSchema = new mongoose.Schema({
|
|
207
344
|
contentTree: { type: [[String]], required: true },
|
|
208
345
|
datasetContentId: { type: String, required: true },
|
|
@@ -220,12 +357,6 @@ const SolutionRecordSchema = new mongoose.Schema({
|
|
|
220
357
|
solution: { type: [String], required: true }
|
|
221
358
|
});
|
|
222
359
|
SolutionRecordSchema.index({ captchaId: 1 });
|
|
223
|
-
const UserSolutionSchema = types.CaptchaSolutionSchema.extend({
|
|
224
|
-
processed: zod.boolean(),
|
|
225
|
-
checked: zod.boolean(),
|
|
226
|
-
commitmentId: zod.string(),
|
|
227
|
-
createdAt: zod.date()
|
|
228
|
-
});
|
|
229
360
|
const UserSolutionRecordSchema = new mongoose.Schema(
|
|
230
361
|
{
|
|
231
362
|
captchaId: { type: String, required: true },
|
|
@@ -241,25 +372,6 @@ const UserSolutionRecordSchema = new mongoose.Schema(
|
|
|
241
372
|
);
|
|
242
373
|
UserSolutionRecordSchema.index({ captchaId: 1 });
|
|
243
374
|
UserSolutionRecordSchema.index({ commitmentId: -1 });
|
|
244
|
-
const UserCommitmentWithSolutionsSchema = UserCommitmentSchema.extend({
|
|
245
|
-
captchas: zod.array(UserSolutionSchema)
|
|
246
|
-
});
|
|
247
|
-
const PendingRecordSchema = new mongoose.Schema({
|
|
248
|
-
accountId: { type: String, required: true },
|
|
249
|
-
pending: { type: Boolean, required: true },
|
|
250
|
-
salt: { type: String, required: true },
|
|
251
|
-
requestHash: { type: String, required: true },
|
|
252
|
-
deadlineTimestamp: { type: Number, required: true },
|
|
253
|
-
// unix timestamp
|
|
254
|
-
requestedAtTimestamp: { type: Date, required: true, expires: ONE_WEEK },
|
|
255
|
-
ipAddress: CompositeIpAddressRecordSchemaObj,
|
|
256
|
-
sessionId: {
|
|
257
|
-
type: String,
|
|
258
|
-
required: false
|
|
259
|
-
},
|
|
260
|
-
threshold: { type: Number, required: true, default: 0.8 }
|
|
261
|
-
});
|
|
262
|
-
PendingRecordSchema.index({ requestHash: -1 });
|
|
263
375
|
const ScheduledTaskSchema = zod.object({
|
|
264
376
|
processName: zod.nativeEnum(types.ScheduledTaskNames),
|
|
265
377
|
datetime: zod.date(),
|
|
@@ -301,28 +413,98 @@ const SessionRecordSchema = new mongoose.Schema({
|
|
|
301
413
|
timeout: { type: Number, required: false },
|
|
302
414
|
accessPolicy: { type: Number, required: false },
|
|
303
415
|
unverifiedHost: { type: Number, required: false },
|
|
304
|
-
webView: { type: Number, required: false }
|
|
416
|
+
webView: { type: Number, required: false },
|
|
417
|
+
triggeredDetectors: { type: [Number], required: false }
|
|
305
418
|
},
|
|
306
419
|
providerSelectEntropy: { type: Number, required: true },
|
|
307
420
|
ipAddress: CompositeIpAddressRecordSchemaObj,
|
|
308
421
|
captchaType: { type: String, enum: types.CaptchaType, required: true },
|
|
422
|
+
mode: { type: String, enum: types.ModeEnum, required: false },
|
|
309
423
|
solvedImagesCount: { type: Number, required: false },
|
|
310
424
|
powDifficulty: { type: Number, required: false },
|
|
311
425
|
storedAtTimestamp: { type: Date, required: false, expires: ONE_DAY },
|
|
312
426
|
lastUpdatedTimestamp: { type: Date, required: false },
|
|
427
|
+
// See `StoredCaptcha.pendingStage` — same semantics on Session records.
|
|
428
|
+
pendingStage: { type: Boolean, required: false },
|
|
313
429
|
deleted: { type: Boolean, required: false },
|
|
314
430
|
userSitekeyIpHash: { type: String, required: false },
|
|
315
431
|
webView: { type: Boolean, required: true, default: false },
|
|
316
432
|
iFrame: { type: Boolean, required: true, default: false },
|
|
317
433
|
decryptedHeadHash: { type: String, required: false, default: "" },
|
|
318
|
-
|
|
434
|
+
siteKey: { type: String, required: false },
|
|
435
|
+
reason: { type: String, required: false },
|
|
436
|
+
blocked: { type: Boolean, required: false },
|
|
437
|
+
// Full ipinfo payload — replaces flat `countryCode` / `geolocation`
|
|
438
|
+
// fields. Mirrors the captcha record schemas (PoW / Puzzle /
|
|
439
|
+
// UserCommitment).
|
|
440
|
+
ipInfo: { type: Object, required: false },
|
|
441
|
+
headers: { type: Object, required: false },
|
|
442
|
+
result: {
|
|
443
|
+
type: new mongoose.Schema(
|
|
444
|
+
{
|
|
445
|
+
status: {
|
|
446
|
+
type: String,
|
|
447
|
+
enum: Object.values(types.CaptchaStatus),
|
|
448
|
+
required: true
|
|
449
|
+
},
|
|
450
|
+
reason: { type: String, required: false },
|
|
451
|
+
error: { type: String, required: false }
|
|
452
|
+
},
|
|
453
|
+
{ _id: false }
|
|
454
|
+
),
|
|
455
|
+
required: false
|
|
456
|
+
},
|
|
457
|
+
userSubmitted: { type: Boolean, required: false },
|
|
458
|
+
serverChecked: { type: Boolean, required: false },
|
|
459
|
+
// WASM SIMD CPU fingerprint readings collected by the catcher client.
|
|
460
|
+
// Stored as a free-form Mixed sub-document because the shape is a
|
|
461
|
+
// discriminated union and the dataset is still evolving — Zod validates
|
|
462
|
+
// at the boundary, Mongoose just persists it.
|
|
463
|
+
simdReadings: { type: mongoose.Schema.Types.Mixed, required: false },
|
|
464
|
+
// Stage at which the SIMD readings first arrived on this session
|
|
465
|
+
// (frictionless / challenge / submit). First-hop-wins.
|
|
466
|
+
simdReadingsStage: { type: String, required: false },
|
|
467
|
+
// DNS observation merge target. Populated by
|
|
468
|
+
// POST /v1/prosopo/provider/admin/dns/event from the dns-event
|
|
469
|
+
// sidecar (see types/provider/database.ts → Session.dnsEvent).
|
|
470
|
+
dnsEvent: {
|
|
471
|
+
type: new mongoose.Schema(
|
|
472
|
+
{
|
|
473
|
+
resolverIp: { type: String, required: false },
|
|
474
|
+
peerIp: { type: String, required: false },
|
|
475
|
+
pathValid: { type: Boolean, required: false },
|
|
476
|
+
receivedAt: { type: Date, required: true }
|
|
477
|
+
},
|
|
478
|
+
{ _id: false }
|
|
479
|
+
),
|
|
480
|
+
required: false
|
|
481
|
+
}
|
|
319
482
|
});
|
|
320
483
|
SessionRecordSchema.index({ createdAt: 1 });
|
|
321
484
|
SessionRecordSchema.index({ deleted: 1 });
|
|
485
|
+
SessionRecordSchema.index({ blocked: 1 });
|
|
322
486
|
SessionRecordSchema.index({ sessionId: 1 }, { unique: true });
|
|
323
487
|
SessionRecordSchema.index({ userSitekeyIpHash: 1 });
|
|
324
488
|
SessionRecordSchema.index({ providerSelectEntropy: 1 });
|
|
325
489
|
SessionRecordSchema.index({ token: 1 });
|
|
490
|
+
SessionRecordSchema.index({ siteKey: 1 }, { background: true, sparse: true });
|
|
491
|
+
SessionRecordSchema.index({
|
|
492
|
+
createdAt: 1,
|
|
493
|
+
captchaType: 1,
|
|
494
|
+
"scoreComponents.baseScore": 1
|
|
495
|
+
});
|
|
496
|
+
SessionRecordSchema.index({ createdAt: 1, deleted: 1 });
|
|
497
|
+
SessionRecordSchema.index(
|
|
498
|
+
{ "result.status": 1 },
|
|
499
|
+
{ background: true, sparse: true }
|
|
500
|
+
);
|
|
501
|
+
SessionRecordSchema.index(
|
|
502
|
+
{ pendingStage: 1 },
|
|
503
|
+
{
|
|
504
|
+
name: "pendingStage_partial",
|
|
505
|
+
partialFilterExpression: { pendingStage: true }
|
|
506
|
+
}
|
|
507
|
+
);
|
|
326
508
|
const DetectorRecordSchema = new mongoose.Schema({
|
|
327
509
|
createdAt: { type: Date, required: true },
|
|
328
510
|
detectorKey: { type: String, required: true },
|
|
@@ -330,6 +512,39 @@ const DetectorRecordSchema = new mongoose.Schema({
|
|
|
330
512
|
});
|
|
331
513
|
DetectorRecordSchema.index({ createdAt: 1 }, { unique: true });
|
|
332
514
|
DetectorRecordSchema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 });
|
|
515
|
+
const DecisionMachineArtifactRecordSchema = new mongoose.Schema({
|
|
516
|
+
scope: {
|
|
517
|
+
type: String,
|
|
518
|
+
enum: Object.values(types.DecisionMachineScope),
|
|
519
|
+
required: true
|
|
520
|
+
},
|
|
521
|
+
dappAccount: { type: String, required: false },
|
|
522
|
+
runtime: {
|
|
523
|
+
type: String,
|
|
524
|
+
enum: Object.values(types.DecisionMachineRuntime),
|
|
525
|
+
required: true
|
|
526
|
+
},
|
|
527
|
+
language: {
|
|
528
|
+
type: String,
|
|
529
|
+
enum: Object.values(types.DecisionMachineLanguage),
|
|
530
|
+
required: false
|
|
531
|
+
},
|
|
532
|
+
source: { type: String, required: true },
|
|
533
|
+
name: { type: String, required: false },
|
|
534
|
+
version: { type: String, required: false },
|
|
535
|
+
captchaType: {
|
|
536
|
+
type: String,
|
|
537
|
+
enum: [types.CaptchaType.pow, types.CaptchaType.image],
|
|
538
|
+
required: false
|
|
539
|
+
},
|
|
540
|
+
createdAt: { type: Date, required: true },
|
|
541
|
+
updatedAt: { type: Date, required: true }
|
|
542
|
+
});
|
|
543
|
+
DecisionMachineArtifactRecordSchema.index(
|
|
544
|
+
{ scope: 1, dappAccount: 1 },
|
|
545
|
+
{ unique: true }
|
|
546
|
+
);
|
|
547
|
+
DecisionMachineArtifactRecordSchema.index({ updatedAt: -1 });
|
|
333
548
|
const ClientContextEntropyRecordSchema = new mongoose.Schema(
|
|
334
549
|
{
|
|
335
550
|
account: { type: String, required: true },
|
|
@@ -350,19 +565,14 @@ exports.CaptchaRecordSchema = CaptchaRecordSchema;
|
|
|
350
565
|
exports.ClientContextEntropyRecordSchema = ClientContextEntropyRecordSchema;
|
|
351
566
|
exports.ClientRecordSchema = ClientRecordSchema;
|
|
352
567
|
exports.CompositeIpAddressRecordSchemaObj = CompositeIpAddressRecordSchemaObj;
|
|
353
|
-
exports.CompositeIpAddressSchema = CompositeIpAddressSchema;
|
|
354
568
|
exports.DatasetRecordSchema = DatasetRecordSchema;
|
|
569
|
+
exports.DecisionMachineArtifactRecordSchema = DecisionMachineArtifactRecordSchema;
|
|
355
570
|
exports.DetectorRecordSchema = DetectorRecordSchema;
|
|
356
|
-
exports.IpAddressType = IpAddressType;
|
|
357
|
-
exports.PendingRecordSchema = PendingRecordSchema;
|
|
358
571
|
exports.PoWCaptchaRecordSchema = PoWCaptchaRecordSchema;
|
|
572
|
+
exports.PuzzleCaptchaRecordSchema = PuzzleCaptchaRecordSchema;
|
|
359
573
|
exports.ScheduledTaskRecordSchema = ScheduledTaskRecordSchema;
|
|
360
574
|
exports.ScheduledTaskSchema = ScheduledTaskSchema;
|
|
361
575
|
exports.SessionRecordSchema = SessionRecordSchema;
|
|
362
576
|
exports.SolutionRecordSchema = SolutionRecordSchema;
|
|
363
577
|
exports.UserCommitmentRecordSchema = UserCommitmentRecordSchema;
|
|
364
|
-
exports.UserCommitmentSchema = UserCommitmentSchema;
|
|
365
|
-
exports.UserCommitmentWithSolutionsSchema = UserCommitmentWithSolutionsSchema;
|
|
366
578
|
exports.UserSolutionRecordSchema = UserSolutionRecordSchema;
|
|
367
|
-
exports.UserSolutionSchema = UserSolutionSchema;
|
|
368
|
-
exports.parseMongooseCompositeIpAddress = parseMongooseCompositeIpAddress;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const mongoose = require("mongoose");
|
|
4
|
+
const SpamEmailDomainRecordSchema = new mongoose.Schema({
|
|
5
|
+
domain: { type: String, required: true, unique: true }
|
|
6
|
+
});
|
|
7
|
+
SpamEmailDomainRecordSchema.index({ domain: 1 });
|
|
8
|
+
exports.SpamEmailDomainRecordSchema = SpamEmailDomainRecordSchema;
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,kBAAkB,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,cAAc,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,34 +1,33 @@
|
|
|
1
1
|
import "./types/index.js";
|
|
2
|
-
import { CaptchaRecordSchema, ClientContextEntropyRecordSchema, ClientRecordSchema, CompositeIpAddressRecordSchemaObj,
|
|
2
|
+
import { CaptchaRecordSchema, ClientContextEntropyRecordSchema, ClientRecordSchema, CompositeIpAddressRecordSchemaObj, DatasetRecordSchema, DecisionMachineArtifactRecordSchema, DetectorRecordSchema, PoWCaptchaRecordSchema, PuzzleCaptchaRecordSchema, ScheduledTaskRecordSchema, ScheduledTaskSchema, SessionRecordSchema, SolutionRecordSchema, UserCommitmentRecordSchema, UserSolutionRecordSchema } from "./types/provider.js";
|
|
3
3
|
import { AccountSchema, IPValidationRulesSchema, TableNames, UserDataSchema, UserSettingsSchema } from "./types/client.js";
|
|
4
4
|
import { StoredPoWCaptchaRecordSchema, StoredSessionRecordSchema, StoredUserCommitmentRecordSchema } from "./types/captcha.js";
|
|
5
|
+
import { SpamEmailDomainRecordSchema } from "./types/spamEmailDomain.js";
|
|
6
|
+
import { BannedDomainRecordSchema } from "./types/bannedDomain.js";
|
|
5
7
|
export {
|
|
6
8
|
AccountSchema,
|
|
9
|
+
BannedDomainRecordSchema,
|
|
7
10
|
CaptchaRecordSchema,
|
|
8
11
|
ClientContextEntropyRecordSchema,
|
|
9
12
|
ClientRecordSchema,
|
|
10
13
|
CompositeIpAddressRecordSchemaObj,
|
|
11
|
-
CompositeIpAddressSchema,
|
|
12
14
|
DatasetRecordSchema,
|
|
15
|
+
DecisionMachineArtifactRecordSchema,
|
|
13
16
|
DetectorRecordSchema,
|
|
14
17
|
IPValidationRulesSchema,
|
|
15
|
-
IpAddressType,
|
|
16
|
-
PendingRecordSchema,
|
|
17
18
|
PoWCaptchaRecordSchema,
|
|
19
|
+
PuzzleCaptchaRecordSchema,
|
|
18
20
|
ScheduledTaskRecordSchema,
|
|
19
21
|
ScheduledTaskSchema,
|
|
20
22
|
SessionRecordSchema,
|
|
21
23
|
SolutionRecordSchema,
|
|
24
|
+
SpamEmailDomainRecordSchema,
|
|
22
25
|
StoredPoWCaptchaRecordSchema,
|
|
23
26
|
StoredSessionRecordSchema,
|
|
24
27
|
StoredUserCommitmentRecordSchema,
|
|
25
28
|
TableNames,
|
|
26
29
|
UserCommitmentRecordSchema,
|
|
27
|
-
UserCommitmentSchema,
|
|
28
|
-
UserCommitmentWithSolutionsSchema,
|
|
29
30
|
UserDataSchema,
|
|
30
31
|
UserSettingsSchema,
|
|
31
|
-
UserSolutionRecordSchema
|
|
32
|
-
UserSolutionSchema,
|
|
33
|
-
parseMongooseCompositeIpAddress
|
|
32
|
+
UserSolutionRecordSchema
|
|
34
33
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type mongoose from "mongoose";
|
|
2
|
+
export type BannedDomain = {
|
|
3
|
+
domain: string;
|
|
4
|
+
};
|
|
5
|
+
export type BannedDomainRecord = mongoose.Document & BannedDomain;
|
|
6
|
+
export declare const BannedDomainRecordSchema: mongoose.Schema<BannedDomainRecord, mongoose.Model<BannedDomainRecord, any, any, any, mongoose.Document<unknown, any, BannedDomainRecord> & mongoose.Document<unknown, any, any> & BannedDomain & Required<{
|
|
7
|
+
_id: unknown;
|
|
8
|
+
}> & {
|
|
9
|
+
__v: number;
|
|
10
|
+
}, any>, {}, {}, {}, {}, mongoose.DefaultSchemaOptions, BannedDomainRecord, mongoose.Document<unknown, {}, mongoose.FlatRecord<BannedDomainRecord>> & mongoose.FlatRecord<BannedDomainRecord> & Required<{
|
|
11
|
+
_id: unknown;
|
|
12
|
+
}> & {
|
|
13
|
+
__v: number;
|
|
14
|
+
}>;
|
|
15
|
+
//# sourceMappingURL=bannedDomain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bannedDomain.d.ts","sourceRoot":"","sources":["../../src/types/bannedDomain.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AAGrC,MAAM,MAAM,YAAY,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC,QAAQ,GAAG,YAAY,CAAC;AAElE,eAAO,MAAM,wBAAwB;;;;;;;;EAEnC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bannedDomain.js","sourceRoot":"","sources":["../../src/types/bannedDomain.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAQlC,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,MAAM,CAAqB;IACtE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;CACtD,CAAC,CAAC;AAEH,wBAAwB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC"}
|
package/dist/types/captcha.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { PoWCaptcha } from "@prosopo/types";
|
|
1
|
+
import type { PoWCaptcha, UserCommitment } from "@prosopo/types";
|
|
2
2
|
import { type RootFilterQuery, Schema } from "mongoose";
|
|
3
3
|
import type { IDatabase } from "./mongo.js";
|
|
4
|
-
import { type PoWCaptchaRecord, type SessionRecord, type
|
|
4
|
+
import { type PoWCaptchaRecord, type SessionRecord, type UserCommitmentRecord } from "./provider.js";
|
|
5
5
|
export type StoredSession = SessionRecord;
|
|
6
6
|
export declare const StoredSessionRecordSchema: Schema;
|
|
7
7
|
export declare const StoredUserCommitmentRecordSchema: Schema;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"captcha.d.ts","sourceRoot":"","sources":["../../src/types/captcha.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"captcha.d.ts","sourceRoot":"","sources":["../../src/types/captcha.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EACN,KAAK,gBAAgB,EAErB,KAAK,aAAa,EAElB,KAAK,oBAAoB,EAEzB,MAAM,eAAe,CAAC;AAGvB,MAAM,MAAM,aAAa,GAAG,aAAa,CAAC;AAE1C,eAAO,MAAM,yBAAyB,EAAE,MAA4B,CAAC;AAErE,eAAO,MAAM,gCAAgC,EAAE,MAE7C,CAAC;AAGH,eAAO,MAAM,4BAA4B,EAAE,MAEzC,CAAC;AAGH,MAAM,WAAW,gBAAiB,SAAQ,SAAS;IAClD,YAAY,CACX,aAAa,EAAE,aAAa,EAAE,EAC9B,kBAAkB,EAAE,oBAAoB,EAAE,EAC1C,gBAAgB,EAAE,gBAAgB,EAAE,GAClC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,WAAW,CACV,MAAM,EAAE,eAAe,CAAC,iBAAiB,CAAC,EAC1C,KAAK,EAAE,MAAM,GACX,OAAO,CAAC;QACV,qBAAqB,EAAE,oBAAoB,EAAE,CAAC;QAC9C,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;KACtC,CAAC,CAAC;CACH;AAED,MAAM,WAAW,iBAChB,SAAQ,OAAO,CAAC,cAAc,GAAG,UAAU,CAAC;CAAG"}
|