better-auth 0.3.5-beta.8 → 0.3.6
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/adapters/drizzle.d.ts +2 -2
- package/dist/adapters/drizzle.js +4 -6
- package/dist/adapters/mongodb.d.ts +8 -2
- package/dist/adapters/mongodb.js +2 -2
- package/dist/adapters/prisma.d.ts +2 -2
- package/dist/adapters/prisma.js +9 -2
- package/dist/api.d.ts +2 -2
- package/dist/api.js +41 -28
- package/dist/cli.js +8 -1
- package/dist/client/plugins.d.ts +11 -6
- package/dist/client/plugins.js +13 -2
- package/dist/client.d.ts +2 -2
- package/dist/{index-Bkb3x6r0.d.ts → index-Bh0h0nFa.d.ts} +113 -291
- package/dist/{index-JGsMiE1o.d.ts → index-DI8FMfhr.d.ts} +735 -6
- package/dist/index.d.ts +2 -2
- package/dist/index.js +116 -49
- package/dist/next-js.d.ts +3 -3
- package/dist/node.d.ts +2 -2
- package/dist/plugins.d.ts +5 -5
- package/dist/plugins.js +421 -21
- package/dist/react.d.ts +2 -2
- package/dist/social.d.ts +1 -1
- package/dist/solid-start.d.ts +2 -2
- package/dist/solid.d.ts +2 -2
- package/dist/svelte-kit.d.ts +2 -2
- package/dist/svelte.d.ts +2 -2
- package/dist/{index-QaO4zgiz.d.ts → types-Bs23H3QM.d.ts} +42 -42
- package/dist/types.d.ts +19 -16
- package/dist/vue.d.ts +2 -2
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { A as Adapter } from '../index-
|
|
1
|
+
import { A as Adapter } from '../index-Bh0h0nFa.js';
|
|
2
2
|
import 'zod';
|
|
3
3
|
import 'kysely';
|
|
4
|
-
import '../
|
|
4
|
+
import '../types-Bs23H3QM.js';
|
|
5
5
|
import 'arctic';
|
|
6
6
|
import '../helper-DPDj8Nix.js';
|
|
7
7
|
import 'better-call';
|
package/dist/adapters/drizzle.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/adapters/drizzle-adapter/index.ts
|
|
2
|
-
import { and, eq, or } from "drizzle-orm";
|
|
2
|
+
import { and, asc, desc, eq, or } from "drizzle-orm";
|
|
3
3
|
|
|
4
4
|
// src/db/get-tables.ts
|
|
5
5
|
var getAuthTables = (options) => {
|
|
@@ -295,16 +295,14 @@ var drizzleAdapter = (db, options) => {
|
|
|
295
295
|
else return null;
|
|
296
296
|
},
|
|
297
297
|
async findMany(data) {
|
|
298
|
-
const { model, where } = data;
|
|
298
|
+
const { model, where, limit, offset, sortBy } = data;
|
|
299
299
|
const schemaModel = getSchema(model, {
|
|
300
300
|
schema,
|
|
301
301
|
usePlural: options.usePlural
|
|
302
302
|
});
|
|
303
303
|
const wheres = where ? whereConvertor(where, schemaModel) : [];
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
}
|
|
307
|
-
const res = await db.select().from(schemaModel).where(...wheres);
|
|
304
|
+
const fn = sortBy?.direction === "desc" ? desc : asc;
|
|
305
|
+
const res = await db.select().from(schemaModel).limit(limit || 100).offset(offset || 0).orderBy(fn(schemaModel[sortBy?.field || "id"])).where(...wheres.length ? wheres : []);
|
|
308
306
|
return res;
|
|
309
307
|
},
|
|
310
308
|
async update(data) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Db } from 'mongodb';
|
|
2
|
-
import { W as Where } from '../index-
|
|
2
|
+
import { W as Where } from '../index-Bh0h0nFa.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
import 'kysely';
|
|
5
|
-
import '../
|
|
5
|
+
import '../types-Bs23H3QM.js';
|
|
6
6
|
import 'arctic';
|
|
7
7
|
import '../helper-DPDj8Nix.js';
|
|
8
8
|
import 'better-call';
|
|
@@ -24,6 +24,12 @@ declare const mongodbAdapter: (mongo: Db) => {
|
|
|
24
24
|
findMany<T>(data: {
|
|
25
25
|
model: string;
|
|
26
26
|
where?: Where[];
|
|
27
|
+
limit?: number;
|
|
28
|
+
sortBy?: {
|
|
29
|
+
field: string;
|
|
30
|
+
direction: "asc" | "desc";
|
|
31
|
+
};
|
|
32
|
+
offset?: number;
|
|
27
33
|
}): Promise<any[]>;
|
|
28
34
|
update<T>(data: {
|
|
29
35
|
model: string;
|
package/dist/adapters/mongodb.js
CHANGED
|
@@ -72,9 +72,9 @@ var mongodbAdapter = (mongo) => {
|
|
|
72
72
|
return removeMongoId(result);
|
|
73
73
|
},
|
|
74
74
|
async findMany(data) {
|
|
75
|
-
const { model, where } = data;
|
|
75
|
+
const { model, where, limit, offset, sortBy } = data;
|
|
76
76
|
const wheres = whereConvertor(where);
|
|
77
|
-
const toReturn = await db.collection(model).find().filter(wheres).toArray();
|
|
77
|
+
const toReturn = await db.collection(model).find().filter(wheres).skip(offset || 0).limit(limit || 100).sort(sortBy?.field || "id", sortBy?.direction === "desc" ? -1 : 1).toArray();
|
|
78
78
|
return toReturn.map(removeMongoId);
|
|
79
79
|
},
|
|
80
80
|
async update(data) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { A as Adapter } from '../index-
|
|
1
|
+
import { A as Adapter } from '../index-Bh0h0nFa.js';
|
|
2
2
|
import 'zod';
|
|
3
3
|
import 'kysely';
|
|
4
|
-
import '../
|
|
4
|
+
import '../types-Bs23H3QM.js';
|
|
5
5
|
import 'arctic';
|
|
6
6
|
import '../helper-DPDj8Nix.js';
|
|
7
7
|
import 'better-call';
|
package/dist/adapters/prisma.js
CHANGED
|
@@ -67,9 +67,16 @@ var prismaAdapter = (prisma, {
|
|
|
67
67
|
});
|
|
68
68
|
},
|
|
69
69
|
async findMany(data) {
|
|
70
|
-
const { model, where } = data;
|
|
70
|
+
const { model, where, limit, offset, sortBy } = data;
|
|
71
71
|
const whereClause = whereConvertor(where);
|
|
72
|
-
return await db[model].findMany({
|
|
72
|
+
return await db[model].findMany({
|
|
73
|
+
where: whereClause,
|
|
74
|
+
take: limit || 100,
|
|
75
|
+
skip: offset || 0,
|
|
76
|
+
orderBy: sortBy?.field ? {
|
|
77
|
+
[sortBy.field]: sortBy.direction === "desc" ? "desc" : "asc"
|
|
78
|
+
} : void 0
|
|
79
|
+
});
|
|
73
80
|
},
|
|
74
81
|
async update(data) {
|
|
75
82
|
const { model, where, update } = data;
|
package/dist/api.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { e as AuthEndpoint, f as AuthMiddleware, v as callbackOAuth, T as changePassword, d as createAuthEndpoint, c as createAuthMiddleware, M as createEmailVerificationToken, $ as csrfMiddleware, V as deleteUser, Y as error, J as forgetPassword, K as forgetPasswordCallback, X as getCSRFToken, r as getEndpoints, w as getSession, x as getSessionFromCtx, z as listSessions, Z as ok, o as optionsMiddleware, L as resetPassword, C as revokeSession, D as revokeSessions, s as router, N as sendVerificationEmail, y as sessionMiddleware, U as setPassword, u as signInEmail, t as signInOAuth, E as signOut, _ as signUpEmail, Q as updateUser, O as verifyEmail } from './index-
|
|
1
|
+
export { e as AuthEndpoint, f as AuthMiddleware, v as callbackOAuth, T as changePassword, d as createAuthEndpoint, c as createAuthMiddleware, M as createEmailVerificationToken, $ as csrfMiddleware, V as deleteUser, Y as error, J as forgetPassword, K as forgetPasswordCallback, X as getCSRFToken, r as getEndpoints, w as getSession, x as getSessionFromCtx, z as listSessions, Z as ok, o as optionsMiddleware, L as resetPassword, C as revokeSession, D as revokeSessions, s as router, N as sendVerificationEmail, y as sessionMiddleware, U as setPassword, u as signInEmail, t as signInOAuth, E as signOut, _ as signUpEmail, Q as updateUser, O as verifyEmail } from './index-Bh0h0nFa.js';
|
|
2
2
|
import './helper-DPDj8Nix.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
export { APIError } from 'better-call';
|
|
5
5
|
import 'kysely';
|
|
6
|
-
import './
|
|
6
|
+
import './types-Bs23H3QM.js';
|
|
7
7
|
import 'arctic';
|
|
8
8
|
import 'better-sqlite3';
|
|
9
9
|
import 'mysql2';
|
package/dist/api.js
CHANGED
|
@@ -934,15 +934,9 @@ var listSessions = () => createAuthEndpoint(
|
|
|
934
934
|
requireHeaders: true
|
|
935
935
|
},
|
|
936
936
|
async (ctx) => {
|
|
937
|
-
const sessions = await ctx.context.
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
{
|
|
941
|
-
field: "userId",
|
|
942
|
-
value: ctx.context.session.user.id
|
|
943
|
-
}
|
|
944
|
-
]
|
|
945
|
-
});
|
|
937
|
+
const sessions = await ctx.context.internalAdapter.listSessions(
|
|
938
|
+
ctx.context.session.user.id
|
|
939
|
+
);
|
|
946
940
|
const activeSessions = sessions.filter((session) => {
|
|
947
941
|
return session.expiresAt > /* @__PURE__ */ new Date();
|
|
948
942
|
});
|
|
@@ -1166,7 +1160,9 @@ var signInEmail = createAuthEndpoint(
|
|
|
1166
1160
|
);
|
|
1167
1161
|
if (!session) {
|
|
1168
1162
|
ctx.context.logger.error("Failed to create session");
|
|
1169
|
-
throw new APIError3("
|
|
1163
|
+
throw new APIError3("UNAUTHORIZED", {
|
|
1164
|
+
message: "Failed to create session"
|
|
1165
|
+
});
|
|
1170
1166
|
}
|
|
1171
1167
|
await setSessionCookie(ctx, session.id, ctx.body.dontRememberMe);
|
|
1172
1168
|
return ctx.json({
|
|
@@ -1369,6 +1365,26 @@ var callbackOAuth = createAuthEndpoint(
|
|
|
1369
1365
|
`${c.context.baseURL}/error?error=oauth_provider_not_found`
|
|
1370
1366
|
);
|
|
1371
1367
|
}
|
|
1368
|
+
const parsedState = parseState(c.query.state);
|
|
1369
|
+
if (!parsedState.success) {
|
|
1370
|
+
c.context.logger.error("Unable to parse state");
|
|
1371
|
+
throw c.redirect(
|
|
1372
|
+
`${c.context.baseURL}/error?error=please_restart_the_process`
|
|
1373
|
+
);
|
|
1374
|
+
}
|
|
1375
|
+
const {
|
|
1376
|
+
data: { callbackURL, currentURL, dontRememberMe, code }
|
|
1377
|
+
} = parsedState;
|
|
1378
|
+
const storedCode = await c.getSignedCookie(
|
|
1379
|
+
c.context.authCookies.state.name,
|
|
1380
|
+
c.context.secret
|
|
1381
|
+
);
|
|
1382
|
+
if (storedCode !== code) {
|
|
1383
|
+
logger.error("Oauth code mismatch", storedCode, code);
|
|
1384
|
+
throw c.redirect(
|
|
1385
|
+
`${c.context.baseURL}/error?error=please_restart_the_process`
|
|
1386
|
+
);
|
|
1387
|
+
}
|
|
1372
1388
|
const codeVerifier = await c.getSignedCookie(
|
|
1373
1389
|
c.context.authCookies.pkCodeVerifier.name,
|
|
1374
1390
|
c.context.secret
|
|
@@ -1383,7 +1399,7 @@ var callbackOAuth = createAuthEndpoint(
|
|
|
1383
1399
|
} catch (e) {
|
|
1384
1400
|
c.context.logger.error(e);
|
|
1385
1401
|
throw c.redirect(
|
|
1386
|
-
`${c.context.baseURL}/error?error=
|
|
1402
|
+
`${c.context.baseURL}/error?error=please_restart_the_process`
|
|
1387
1403
|
);
|
|
1388
1404
|
}
|
|
1389
1405
|
const user = await provider.getUserInfo(tokens).then((res) => res?.user);
|
|
@@ -1392,23 +1408,15 @@ var callbackOAuth = createAuthEndpoint(
|
|
|
1392
1408
|
...user,
|
|
1393
1409
|
id
|
|
1394
1410
|
});
|
|
1395
|
-
const parsedState = parseState(c.query.state);
|
|
1396
|
-
if (!parsedState.success) {
|
|
1397
|
-
c.context.logger.error("Unable to parse state");
|
|
1398
|
-
throw c.redirect(
|
|
1399
|
-
`${c.context.baseURL}/error?error=invalid_state_parameter`
|
|
1400
|
-
);
|
|
1401
|
-
}
|
|
1402
|
-
const { callbackURL, currentURL, dontRememberMe } = parsedState.data;
|
|
1403
1411
|
if (!user || data.success === false) {
|
|
1404
1412
|
logger.error("Unable to get user info", data.error);
|
|
1405
1413
|
throw c.redirect(
|
|
1406
|
-
`${c.context.baseURL}/error?error=
|
|
1414
|
+
`${c.context.baseURL}/error?error=please_restart_the_process`
|
|
1407
1415
|
);
|
|
1408
1416
|
}
|
|
1409
1417
|
if (!callbackURL) {
|
|
1410
1418
|
throw c.redirect(
|
|
1411
|
-
`${c.context.baseURL}/error?error=
|
|
1419
|
+
`${c.context.baseURL}/error?error=please_restart_the_process`
|
|
1412
1420
|
);
|
|
1413
1421
|
}
|
|
1414
1422
|
const dbUser = await c.context.internalAdapter.findUserByEmail(user.email).catch((e) => {
|
|
@@ -1495,7 +1503,7 @@ var callbackOAuth = createAuthEndpoint(
|
|
|
1495
1503
|
throw c.redirect(url.toString());
|
|
1496
1504
|
}
|
|
1497
1505
|
} catch {
|
|
1498
|
-
const url = new URL(currentURL || callbackURL);
|
|
1506
|
+
const url = new URL(currentURL || callbackURL || "");
|
|
1499
1507
|
url.searchParams.set("error", "unable_to_create_session");
|
|
1500
1508
|
throw c.redirect(url.toString());
|
|
1501
1509
|
}
|
|
@@ -1857,7 +1865,9 @@ var updateUser = createAuthEndpoint(
|
|
|
1857
1865
|
const { name, image } = ctx.body;
|
|
1858
1866
|
const session = ctx.context.session;
|
|
1859
1867
|
if (!image && !name) {
|
|
1860
|
-
return ctx.json(
|
|
1868
|
+
return ctx.json({
|
|
1869
|
+
user: session.user
|
|
1870
|
+
});
|
|
1861
1871
|
}
|
|
1862
1872
|
const user = await ctx.context.internalAdapter.updateUserByEmail(
|
|
1863
1873
|
session.user.email,
|
|
@@ -1866,7 +1876,9 @@ var updateUser = createAuthEndpoint(
|
|
|
1866
1876
|
image
|
|
1867
1877
|
}
|
|
1868
1878
|
);
|
|
1869
|
-
return ctx.json(
|
|
1879
|
+
return ctx.json({
|
|
1880
|
+
user
|
|
1881
|
+
});
|
|
1870
1882
|
}
|
|
1871
1883
|
);
|
|
1872
1884
|
var changePassword = createAuthEndpoint(
|
|
@@ -2221,8 +2233,9 @@ var signUpEmail = () => createAuthEndpoint(
|
|
|
2221
2233
|
}
|
|
2222
2234
|
const dbUser = await ctx.context.internalAdapter.findUserByEmail(email);
|
|
2223
2235
|
if (dbUser?.user) {
|
|
2224
|
-
|
|
2225
|
-
|
|
2236
|
+
ctx.context.logger.info(`Sign-up attempt for existing email: ${email}`);
|
|
2237
|
+
throw new APIError9("UNPROCESSABLE_ENTITY", {
|
|
2238
|
+
message: "The email has already been taken"
|
|
2226
2239
|
});
|
|
2227
2240
|
}
|
|
2228
2241
|
const additionalData = parseAdditionalUserInput(
|
|
@@ -2238,7 +2251,7 @@ var signUpEmail = () => createAuthEndpoint(
|
|
|
2238
2251
|
});
|
|
2239
2252
|
if (!createdUser) {
|
|
2240
2253
|
throw new APIError9("BAD_REQUEST", {
|
|
2241
|
-
message: "
|
|
2254
|
+
message: "Failed to create user"
|
|
2242
2255
|
});
|
|
2243
2256
|
}
|
|
2244
2257
|
const hash = await ctx.context.password.hash(password);
|
|
@@ -2255,7 +2268,7 @@ var signUpEmail = () => createAuthEndpoint(
|
|
|
2255
2268
|
);
|
|
2256
2269
|
if (!session) {
|
|
2257
2270
|
throw new APIError9("BAD_REQUEST", {
|
|
2258
|
-
message: "
|
|
2271
|
+
message: "Failed to create session"
|
|
2259
2272
|
});
|
|
2260
2273
|
}
|
|
2261
2274
|
await setSessionCookie(ctx, session.id);
|
package/dist/cli.js
CHANGED
|
@@ -880,7 +880,7 @@ var kyselyAdapter = (db, config) => {
|
|
|
880
880
|
return res || null;
|
|
881
881
|
},
|
|
882
882
|
async findMany(data) {
|
|
883
|
-
const { model, where } = data;
|
|
883
|
+
const { model, where, limit, offset, sortBy } = data;
|
|
884
884
|
let query = db.selectFrom(model);
|
|
885
885
|
const { and, or } = convertWhere(where);
|
|
886
886
|
if (and) {
|
|
@@ -889,6 +889,13 @@ var kyselyAdapter = (db, config) => {
|
|
|
889
889
|
if (or) {
|
|
890
890
|
query = query.where((eb) => eb.or(or));
|
|
891
891
|
}
|
|
892
|
+
query = query.limit(limit || 100);
|
|
893
|
+
if (offset) {
|
|
894
|
+
query = query.offset(offset);
|
|
895
|
+
}
|
|
896
|
+
if (sortBy) {
|
|
897
|
+
query = query.orderBy(sortBy.field, sortBy.direction);
|
|
898
|
+
}
|
|
892
899
|
const res = await query.selectAll().execute();
|
|
893
900
|
if (config?.transform) {
|
|
894
901
|
const schema = config.transform.schema[model];
|
package/dist/client/plugins.d.ts
CHANGED
|
@@ -2,13 +2,13 @@ import * as nanostores from 'nanostores';
|
|
|
2
2
|
import { A as AccessControl, S as StatementsPrimitive, R as Role } from '../statement-CfnyN34h.js';
|
|
3
3
|
import * as _better_fetch_fetch from '@better-fetch/fetch';
|
|
4
4
|
import { BetterFetchOption } from '@better-fetch/fetch';
|
|
5
|
-
import { o as organization,
|
|
6
|
-
export { g as getPasskeyActions, c as passkeyClient, a as twoFactorClient } from '../index-
|
|
5
|
+
import { o as organization, j as Organization, M as Member, I as Invitation, u as username, m as magicLink, d as phoneNumber, e as anonymous, i as admin } from '../index-DI8FMfhr.js';
|
|
6
|
+
export { g as getPasskeyActions, c as passkeyClient, a as twoFactorClient } from '../index-DI8FMfhr.js';
|
|
7
7
|
import { P as Prettify } from '../helper-DPDj8Nix.js';
|
|
8
|
-
import { F as FieldAttribute, B as BetterAuthOptions, b as BetterAuthPlugin } from '../index-
|
|
9
|
-
import '../
|
|
10
|
-
import 'arctic';
|
|
8
|
+
import { F as FieldAttribute, B as BetterAuthOptions, b as BetterAuthPlugin } from '../index-Bh0h0nFa.js';
|
|
9
|
+
import '../types-Bs23H3QM.js';
|
|
11
10
|
import 'zod';
|
|
11
|
+
import 'arctic';
|
|
12
12
|
import 'better-call';
|
|
13
13
|
import '@simplewebauthn/types';
|
|
14
14
|
import 'kysely';
|
|
@@ -251,4 +251,9 @@ declare const inferAdditionalFields: <T, S extends {
|
|
|
251
251
|
} : never : undefined;
|
|
252
252
|
};
|
|
253
253
|
|
|
254
|
-
|
|
254
|
+
declare const adminClient: () => {
|
|
255
|
+
id: "better-auth-client";
|
|
256
|
+
$InferServerPlugin: ReturnType<typeof admin>;
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
export { adminClient, anonymousClient, inferAdditionalFields, magicLinkClient, organizationClient, phoneNumberClient, usernameClient };
|
package/dist/client/plugins.js
CHANGED
|
@@ -300,7 +300,8 @@ var getPasskeyActions = ($fetch, {
|
|
|
300
300
|
response: res
|
|
301
301
|
},
|
|
302
302
|
...opts?.fetchOptions,
|
|
303
|
-
...options
|
|
303
|
+
...options,
|
|
304
|
+
method: "POST"
|
|
304
305
|
});
|
|
305
306
|
if (!verified.data) {
|
|
306
307
|
return verified;
|
|
@@ -327,7 +328,8 @@ var getPasskeyActions = ($fetch, {
|
|
|
327
328
|
body: {
|
|
328
329
|
response: res,
|
|
329
330
|
name: opts?.name
|
|
330
|
-
}
|
|
331
|
+
},
|
|
332
|
+
method: "POST"
|
|
331
333
|
});
|
|
332
334
|
if (!verified.data) {
|
|
333
335
|
return verified;
|
|
@@ -512,7 +514,16 @@ var inferAdditionalFields = (schema) => {
|
|
|
512
514
|
$InferServerPlugin: {}
|
|
513
515
|
};
|
|
514
516
|
};
|
|
517
|
+
|
|
518
|
+
// src/plugins/admin/client.ts
|
|
519
|
+
var adminClient = () => {
|
|
520
|
+
return {
|
|
521
|
+
id: "better-auth-client",
|
|
522
|
+
$InferServerPlugin: {}
|
|
523
|
+
};
|
|
524
|
+
};
|
|
515
525
|
export {
|
|
526
|
+
adminClient,
|
|
516
527
|
anonymousClient,
|
|
517
528
|
getPasskeyActions,
|
|
518
529
|
inferAdditionalFields,
|
package/dist/client.d.ts
CHANGED
|
@@ -6,9 +6,9 @@ import { BetterFetch, BetterFetchError, BetterFetchOption } from '@better-fetch/
|
|
|
6
6
|
import { U as UnionToIntersection, P as Prettify, S as StripEmptyObjects } from './helper-DPDj8Nix.js';
|
|
7
7
|
import { ClientOptions, InferClientAPI, InferActions, InferAdditionalFromClient, InferSessionFromClient, InferUserFromClient, BetterAuthClientPlugin, IsSignal } from './types.js';
|
|
8
8
|
export { AtomListener, InferPluginsFromClient } from './types.js';
|
|
9
|
-
import './index-
|
|
9
|
+
import './index-Bh0h0nFa.js';
|
|
10
10
|
import 'kysely';
|
|
11
|
-
import './
|
|
11
|
+
import './types-Bs23H3QM.js';
|
|
12
12
|
import 'arctic';
|
|
13
13
|
import 'better-call';
|
|
14
14
|
import 'better-sqlite3';
|