@rsbuild/core 2.2.0-beta.1 → 2.2.0-beta.2
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/626.js +103 -55
- package/dist/helpers/restartManager.d.ts +2 -0
- package/dist/server/helper.d.ts +1 -1
- package/package.json +1 -1
package/dist/626.js
CHANGED
|
@@ -2996,7 +2996,7 @@ let withDefaultConfig = async (rootPath, userConfig)=>{
|
|
|
2996
2996
|
await isFileExists(tsconfigPath) && (config.source.tsconfigPath = tsconfigPath);
|
|
2997
2997
|
}
|
|
2998
2998
|
return config;
|
|
2999
|
-
}, exitHook_callbacks = new Set(), isCalled = !1, isRegistered = !1;
|
|
2999
|
+
}, restartPorts = new WeakMap(), exitHook_callbacks = new Set(), isCalled = !1, isRegistered = !1;
|
|
3000
3000
|
function exit(exitCode, type) {
|
|
3001
3001
|
if (!isCalled) {
|
|
3002
3002
|
for (let callback of (isCalled = !0, exitHook_callbacks))callback(exitCode);
|
|
@@ -3425,7 +3425,7 @@ function createPublicContext(context) {
|
|
|
3425
3425
|
async function createContext(options, userConfig, logger, loadConfigResult) {
|
|
3426
3426
|
let { cwd } = options, rootPath = userConfig.root ? ensureAbsolutePath(cwd, userConfig.root) : cwd, rsbuildConfig = await withDefaultConfig(rootPath, userConfig), cachePath = join(rootPath, 'node_modules', '.cache'), specifiedEnvironments = options.environment && options.environment.length > 0 ? options.environment : void 0, hooks = initHooks();
|
|
3427
3427
|
return {
|
|
3428
|
-
version: "2.2.0-beta.
|
|
3428
|
+
version: "2.2.0-beta.2",
|
|
3429
3429
|
rootPath,
|
|
3430
3430
|
configFile: loadConfigResult?.filePath ?? userConfig._privateMeta?.configFilePath,
|
|
3431
3431
|
configFileDependencies: loadConfigResult?.dependencies ?? userConfig._privateMeta?.configFileDependencies ?? [],
|
|
@@ -3439,9 +3439,16 @@ async function createContext(options, userConfig, logger, loadConfigResult) {
|
|
|
3439
3439
|
publicPathnames: [],
|
|
3440
3440
|
hooks,
|
|
3441
3441
|
restartManager: (({ onRestart, restart })=>{
|
|
3442
|
-
let cleanups = new Set();
|
|
3442
|
+
let port, cleanups = new Set();
|
|
3443
3443
|
return {
|
|
3444
3444
|
canRestart: !!restart,
|
|
3445
|
+
setPort (nextPort) {
|
|
3446
|
+
port = nextPort;
|
|
3447
|
+
},
|
|
3448
|
+
inheritPort (options) {
|
|
3449
|
+
let inheritedPort = options ? restartPorts.get(options) : void 0;
|
|
3450
|
+
return options && restartPorts.delete(options), inheritedPort;
|
|
3451
|
+
},
|
|
3445
3452
|
registerCleanup: (cleanup)=>(cleanups.add(cleanup), ()=>{
|
|
3446
3453
|
cleanups.delete(cleanup);
|
|
3447
3454
|
}),
|
|
@@ -3462,7 +3469,13 @@ async function createContext(options, userConfig, logger, loadConfigResult) {
|
|
|
3462
3469
|
hasError || (hasError = !0, firstError = error);
|
|
3463
3470
|
}
|
|
3464
3471
|
if (hasError) throw firstError;
|
|
3465
|
-
return restart(context);
|
|
3472
|
+
if ('dev' !== context.action || void 0 === port) return restart(context);
|
|
3473
|
+
restartPorts.set(context.options, port);
|
|
3474
|
+
try {
|
|
3475
|
+
return await restart(context);
|
|
3476
|
+
} finally{
|
|
3477
|
+
restartPorts.delete(context.options);
|
|
3478
|
+
}
|
|
3466
3479
|
}
|
|
3467
3480
|
};
|
|
3468
3481
|
})({
|
|
@@ -5846,6 +5859,10 @@ let getPort = async ({ host, port, strictPort, tryLimits = 20 })=>{
|
|
|
5846
5859
|
port,
|
|
5847
5860
|
host
|
|
5848
5861
|
}, ()=>{
|
|
5862
|
+
if (0 === port) {
|
|
5863
|
+
let address = server.address();
|
|
5864
|
+
address && 'string' != typeof address && (port = address.port);
|
|
5865
|
+
}
|
|
5849
5866
|
found = !0, server.close(resolve);
|
|
5850
5867
|
});
|
|
5851
5868
|
});
|
|
@@ -5854,14 +5871,14 @@ let getPort = async ({ host, port, strictPort, tryLimits = 20 })=>{
|
|
|
5854
5871
|
port++, attempts++;
|
|
5855
5872
|
}
|
|
5856
5873
|
if (!found) throw Error(`${color.dim('[rsbuild:server]')} Failed to find an available port after ${tryLimits + 1} attempts, starting from ${color.yellow(original)}.`);
|
|
5857
|
-
if (port !== original && strictPort) throw Error(`${color.dim('[rsbuild:server]')} Port ${color.yellow(original)} is occupied, please choose another one.`);
|
|
5874
|
+
if (0 !== original && port !== original && strictPort) throw Error(`${color.dim('[rsbuild:server]')} Port ${color.yellow(original)} is occupied, please choose another one.`);
|
|
5858
5875
|
return port;
|
|
5859
|
-
}, resolvePort = async (config)=>{
|
|
5860
|
-
let { host, port: originalPort, strictPort } = config.server, port = await getPort({
|
|
5876
|
+
}, resolvePort = async (config, lastPort)=>{
|
|
5877
|
+
let { host, port: originalPort, strictPort } = config.server, preferredPort = 0 === originalPort ? lastPort : void 0, port = await getPort({
|
|
5861
5878
|
host,
|
|
5862
|
-
port: originalPort,
|
|
5863
|
-
strictPort
|
|
5864
|
-
}), portTip = port !== originalPort ? `port ${originalPort} is in use, ${color.yellow(`using port ${port}.`)}` : void 0;
|
|
5879
|
+
port: preferredPort ?? originalPort,
|
|
5880
|
+
strictPort: void 0 === preferredPort && strictPort
|
|
5881
|
+
}), portTip = 0 !== originalPort && port !== originalPort ? `port ${originalPort} is in use, ${color.yellow(`using port ${port}.`)}` : void 0;
|
|
5865
5882
|
return {
|
|
5866
5883
|
port,
|
|
5867
5884
|
portTip
|
|
@@ -6017,7 +6034,7 @@ async function open_open({ port, routes, config, protocol, clearCache, logger })
|
|
|
6017
6034
|
})(config);
|
|
6018
6035
|
clearCache && (openedURLs = []);
|
|
6019
6036
|
let urls = [], host = await getHostInUrl(config.server.host), baseUrl = `${protocol}://${host}:${port}`;
|
|
6020
|
-
for (let url of (targets.length ? urls.push(...targets.map((target)=>resolveUrl(replacePortPlaceholder(target, port), baseUrl))) : routes.length ? urls.push(`${baseUrl}${routes[0].pathname}`) : urls.push(baseUrl), before && await before(), urls))openedURLs.includes(url) || (openBrowser(url, logger), openedURLs.push(url));
|
|
6037
|
+
for (let url of (targets.length ? urls.push(...targets.map((target)=>resolveUrl(replacePortPlaceholder(target, port), baseUrl))) : routes.length ? urls.push(`${baseUrl}${routes[0].pathname}`) : urls.push(baseUrl), before && await before(), urls))openedURLs.includes(url) || (await openBrowser(url, logger), openedURLs.push(url));
|
|
6021
6038
|
}
|
|
6022
6039
|
let getServerUrlFromClientConfig = async (config, context)=>{
|
|
6023
6040
|
let { assetPrefix } = config.dev;
|
|
@@ -6072,7 +6089,7 @@ function pluginModuleFederation() {
|
|
|
6072
6089
|
let { moduleFederation } = config;
|
|
6073
6090
|
if (moduleFederation?.options && moduleFederation.options.exposes) {
|
|
6074
6091
|
let userConfig = api.getRsbuildConfig('original');
|
|
6075
|
-
config.dev ||= {}, config.server ||= {}, userConfig.server?.cors === void 0 && (config.server.cors = !0), config.server?.port
|
|
6092
|
+
config.dev ||= {}, config.server ||= {}, userConfig.server?.cors === void 0 && (config.server.cors = !0), config.server?.port === void 0 || config.dev.client?.port || (config.dev.client ||= {}, config.dev.client.port = 0 === config.server.port ? '<port>' : config.server.port), userConfig.dev?.assetPrefix === void 0 && config.dev.assetPrefix === config.server?.base && (config.dev.assetPrefix = !0);
|
|
6076
6093
|
}
|
|
6077
6094
|
}), api.modifyEnvironmentConfig((config)=>{
|
|
6078
6095
|
config.moduleFederation?.options && (config.source.include = [
|
|
@@ -8174,7 +8191,9 @@ async function devServer_createDevServer(options, createCompiler, config, devSer
|
|
|
8174
8191
|
])
|
|
8175
8192
|
}, { context } = options, { logger } = context;
|
|
8176
8193
|
logger.debug('create dev server');
|
|
8177
|
-
let
|
|
8194
|
+
let isDynamicPort = 0 === config.server.port, lastPort = isDynamicPort ? context.restartManager.inheritPort(devServerOptions) : void 0, { port, portTip } = await resolvePort(config, lastPort);
|
|
8195
|
+
isDynamicPort && context.restartManager.setPort(port);
|
|
8196
|
+
let { middlewareMode, host } = config.server, isHttps = !!config.server.https, routes = getRoutes(context), fallbackPathname = 0 === routes.length && context.environmentList.some((item)=>'web' === item.config.output.target) ? config.server.base : void 0;
|
|
8178
8197
|
context.devServer = {
|
|
8179
8198
|
hostname: host,
|
|
8180
8199
|
port,
|
|
@@ -8321,14 +8340,24 @@ async function devServer_createDevServer(options, createCompiler, config, devSer
|
|
|
8321
8340
|
listen: async ()=>{
|
|
8322
8341
|
if (!httpServer) throw Error(`${color.dim('[rsbuild:server]')} Can not listen dev server as ${color.yellow('server.middlewareMode')} is enabled.`);
|
|
8323
8342
|
let serverTerminator = getServerTerminator(httpServer);
|
|
8324
|
-
|
|
8325
|
-
|
|
8326
|
-
|
|
8327
|
-
|
|
8328
|
-
|
|
8329
|
-
|
|
8330
|
-
|
|
8331
|
-
|
|
8343
|
+
logger.debug('listen dev server'), context.hooks.onCloseDevServer.tap(serverTerminator);
|
|
8344
|
+
try {
|
|
8345
|
+
return httpServer.listen({
|
|
8346
|
+
host,
|
|
8347
|
+
port
|
|
8348
|
+
}), await once(httpServer, 'listening'), middlewares.use(optionsFallbackMiddleware), middlewares.use(notFoundMiddleware), state.devMiddlewares && httpServer.on('upgrade', state.devMiddlewares.onUpgrade), logger.debug('listen dev server done'), await devServer.afterListen(), {
|
|
8349
|
+
port,
|
|
8350
|
+
urls: urls.map((item)=>item.url),
|
|
8351
|
+
server: devServer
|
|
8352
|
+
};
|
|
8353
|
+
} catch (error) {
|
|
8354
|
+
try {
|
|
8355
|
+
await closeServer();
|
|
8356
|
+
} catch (closeError) {
|
|
8357
|
+
logger.error('Failed to close dev server after startup error.'), logger.error(closeError);
|
|
8358
|
+
}
|
|
8359
|
+
throw error;
|
|
8360
|
+
}
|
|
8332
8361
|
},
|
|
8333
8362
|
afterListen: async ()=>{
|
|
8334
8363
|
await context.hooks.onAfterStartDevServer.callBatch({
|
|
@@ -8446,32 +8475,42 @@ async function startPreviewServer(context, config, { getPortSilently } = {}) {
|
|
|
8446
8475
|
for (let callback of (base && '/' !== base && middlewares.use(getBaseUrlMiddleware({
|
|
8447
8476
|
base
|
|
8448
8477
|
})), middlewares.use(assetsMiddleware), middlewares.use(getHtmlCompletionMiddleware(htmlMiddlewareOptions)), historyApiFallback && (middlewares.use(historyApiFallback_historyApiFallbackMiddleware(logger, !0 === historyApiFallback ? {} : historyApiFallback)), middlewares.use(assetsMiddleware)), postSetupCallbacks))await callback();
|
|
8449
|
-
|
|
8478
|
+
serverConfig.htmlFallback && middlewares.use(getHtmlFallbackMiddleware({
|
|
8450
8479
|
...htmlMiddlewareOptions,
|
|
8451
8480
|
logger
|
|
8452
|
-
})), middlewares.use(faviconFallbackMiddleware), middlewares.use(optionsFallbackMiddleware), middlewares.use(notFoundMiddleware)
|
|
8453
|
-
|
|
8454
|
-
|
|
8455
|
-
|
|
8456
|
-
|
|
8457
|
-
|
|
8458
|
-
|
|
8459
|
-
|
|
8460
|
-
|
|
8461
|
-
|
|
8462
|
-
|
|
8463
|
-
|
|
8464
|
-
|
|
8465
|
-
|
|
8466
|
-
|
|
8467
|
-
|
|
8468
|
-
|
|
8481
|
+
})), middlewares.use(faviconFallbackMiddleware), middlewares.use(optionsFallbackMiddleware), middlewares.use(notFoundMiddleware);
|
|
8482
|
+
try {
|
|
8483
|
+
if (httpServer.listen({
|
|
8484
|
+
host,
|
|
8485
|
+
port
|
|
8486
|
+
}), await once(httpServer, 'listening'), await context.hooks.onAfterStartPreviewServer.callBatch({
|
|
8487
|
+
port,
|
|
8488
|
+
routes,
|
|
8489
|
+
environments: context.environments
|
|
8490
|
+
}), registerCleanup(closeServer), printUrls(), cliShortcutsEnabled) {
|
|
8491
|
+
let shortcutsOptions = 'boolean' == typeof config.dev.cliShortcuts ? {} : config.dev.cliShortcuts;
|
|
8492
|
+
await setupCliShortcuts({
|
|
8493
|
+
openPage,
|
|
8494
|
+
closeServer,
|
|
8495
|
+
printUrls,
|
|
8496
|
+
help: shortcutsOptions.help,
|
|
8497
|
+
customShortcuts: shortcutsOptions.custom,
|
|
8498
|
+
logger
|
|
8499
|
+
});
|
|
8500
|
+
}
|
|
8501
|
+
return !getPortSilently && portTip && logger.info(portTip), {
|
|
8502
|
+
port,
|
|
8503
|
+
urls: urls.map((item)=>item.url),
|
|
8504
|
+
server: previewServer
|
|
8505
|
+
};
|
|
8506
|
+
} catch (error) {
|
|
8507
|
+
try {
|
|
8508
|
+
await closeServer();
|
|
8509
|
+
} catch (closeError) {
|
|
8510
|
+
logger.error('Failed to close preview server after startup error.'), logger.error(closeError);
|
|
8511
|
+
}
|
|
8512
|
+
throw error;
|
|
8469
8513
|
}
|
|
8470
|
-
return !getPortSilently && portTip && logger.info(portTip), {
|
|
8471
|
-
port,
|
|
8472
|
-
urls: urls.map((item)=>item.url),
|
|
8473
|
-
server: previewServer
|
|
8474
|
-
};
|
|
8475
8514
|
}
|
|
8476
8515
|
function applyDefaultPlugins(pluginManager, context) {
|
|
8477
8516
|
pluginManager.addPlugins([
|
|
@@ -8486,7 +8525,6 @@ function applyDefaultPlugins(pluginManager, context) {
|
|
|
8486
8525
|
aggregateTimeout: 0
|
|
8487
8526
|
}), chain.performance.hints(!1), chain.experiments({
|
|
8488
8527
|
...chain.get('experiments'),
|
|
8489
|
-
nativeWatcher: !0,
|
|
8490
8528
|
sourceImport: !0
|
|
8491
8529
|
}), chain.module.parser.merge({
|
|
8492
8530
|
javascript: {
|
|
@@ -9336,7 +9374,19 @@ try {
|
|
|
9336
9374
|
javascript: {
|
|
9337
9375
|
dynamicImportMode: 'eager'
|
|
9338
9376
|
}
|
|
9339
|
-
}), isServer
|
|
9377
|
+
}), isServer) {
|
|
9378
|
+
if (!1 === splitChunks) chain.optimization.splitChunks(!1);
|
|
9379
|
+
else {
|
|
9380
|
+
let { preset = 'none', ...rest } = splitChunks;
|
|
9381
|
+
chain.optimization.splitChunks({
|
|
9382
|
+
chunks: 'all',
|
|
9383
|
+
...getSplitChunksByPreset(config, preset),
|
|
9384
|
+
...rest
|
|
9385
|
+
});
|
|
9386
|
+
}
|
|
9387
|
+
return;
|
|
9388
|
+
}
|
|
9389
|
+
if (isWebWorker) {
|
|
9340
9390
|
if (!1 === splitChunks || 0 === Object.keys(splitChunks).length) chain.optimization.splitChunks(!1);
|
|
9341
9391
|
else {
|
|
9342
9392
|
let { preset = 'none', ...rest } = splitChunks;
|
|
@@ -9534,11 +9584,11 @@ try {
|
|
|
9534
9584
|
{
|
|
9535
9585
|
name: 'rsbuild:server',
|
|
9536
9586
|
setup (api) {
|
|
9537
|
-
let onStartServer = ({ port, routes })=>{
|
|
9587
|
+
let onStartServer = async ({ port, routes })=>{
|
|
9538
9588
|
let config = api.getNormalizedConfig();
|
|
9539
9589
|
if (config.server.open) {
|
|
9540
9590
|
let protocol = config.server.https ? 'https' : 'http';
|
|
9541
|
-
open_open({
|
|
9591
|
+
await open_open({
|
|
9542
9592
|
port,
|
|
9543
9593
|
routes,
|
|
9544
9594
|
config,
|
|
@@ -9845,9 +9895,7 @@ async function createRsbuild(options = {}) {
|
|
|
9845
9895
|
context,
|
|
9846
9896
|
pluginManager,
|
|
9847
9897
|
rsbuildOptions: resolvedOptions
|
|
9848
|
-
}, createCompiler, config,
|
|
9849
|
-
...options
|
|
9850
|
-
})).listen();
|
|
9898
|
+
}, createCompiler, config, options)).listen();
|
|
9851
9899
|
}, createDevServer = async (options)=>{
|
|
9852
9900
|
context.action = 'dev', process.env.NODE_ENV || setNodeEnv('development');
|
|
9853
9901
|
let config = await initRsbuildConfig({
|
|
@@ -10088,7 +10136,7 @@ let cliState = {
|
|
|
10088
10136
|
loader: options.configLoader,
|
|
10089
10137
|
command
|
|
10090
10138
|
}), { content: config } = result;
|
|
10091
|
-
if (config.dev ||= {}, config.source ||= {}, config.server ||= {}, options.base && (config.server.base = options.base), options.root && (config.root = root), options.mode && (config.mode = options.mode), options.logLevel && (config.logLevel = options.logLevel), options.open && !config.server?.open && (config.server.open = options.open), void 0 !== options.host && (config.server.host = options.host), options.port && (config.server.port = options.port), void 0 !== options.strictPort && (config.server.strictPort = options.strictPort), void 0 !== options.distPath) {
|
|
10139
|
+
if (config.dev ||= {}, config.source ||= {}, config.server ||= {}, options.base && (config.server.base = options.base), options.root && (config.root = root), options.mode && (config.mode = options.mode), options.logLevel && (config.logLevel = options.logLevel), options.open && !config.server?.open && (config.server.open = options.open), void 0 !== options.host && (config.server.host = options.host), void 0 !== options.port && (config.server.port = options.port), void 0 !== options.strictPort && (config.server.strictPort = options.strictPort), void 0 !== options.distPath) {
|
|
10092
10140
|
config.output ||= {};
|
|
10093
10141
|
let { distPath } = config.output;
|
|
10094
10142
|
config.output.distPath = distPath && 'object' == typeof distPath ? {
|
|
@@ -10135,7 +10183,7 @@ let applyServerOptions = (command)=>{
|
|
|
10135
10183
|
};
|
|
10136
10184
|
function setupCommands(argv) {
|
|
10137
10185
|
let cli = ((name = "")=>new CAC(name))('rsbuild');
|
|
10138
|
-
cli.version("2.2.0-beta.
|
|
10186
|
+
cli.version("2.2.0-beta.2"), cli.option('--base <base>', 'Set the base path of the server').option('-c, --config <config>', 'Set the configuration file (relative or absolute path)').option('--config-loader <loader>', 'Set the config file loader (auto | jiti | native)', {
|
|
10139
10187
|
default: 'auto'
|
|
10140
10188
|
}).option('--dist-path <dir>', 'Set the root directory of output files').option('--source-map', 'Enable source map').option('--env-dir <dir>', 'Set the directory for loading `.env` files').option('--env-mode <mode>', 'Set the env mode to load the `.env.[mode]` file').option('--environment <name>', 'Set the environment name(s) to build', {
|
|
10141
10189
|
type: [
|
|
@@ -10200,7 +10248,7 @@ function setupCommands(argv) {
|
|
|
10200
10248
|
}
|
|
10201
10249
|
function showGreeting() {
|
|
10202
10250
|
let { npm_execpath, npm_lifecycle_event, NODE_RUN_SCRIPT_NAME } = process.env, isBun = npm_execpath?.includes('.bun');
|
|
10203
|
-
src_logger.greet(`${'npx' === npm_lifecycle_event || isBun || NODE_RUN_SCRIPT_NAME ? '\n' : ''}Rsbuild v2.2.0-beta.
|
|
10251
|
+
src_logger.greet(`${'npx' === npm_lifecycle_event || isBun || NODE_RUN_SCRIPT_NAME ? '\n' : ''}Rsbuild v2.2.0-beta.2\n`);
|
|
10204
10252
|
}
|
|
10205
10253
|
function setupLogLevel(argv) {
|
|
10206
10254
|
if (argv.length <= 3) return;
|
|
@@ -10222,5 +10270,5 @@ function runCLI({ argv = process.argv } = {}) {
|
|
|
10222
10270
|
src_logger.error('Failed to start Rsbuild CLI.'), src_logger.error(err), process.exit(1);
|
|
10223
10271
|
}
|
|
10224
10272
|
}
|
|
10225
|
-
let src_version = "2.2.0-beta.
|
|
10273
|
+
let src_version = "2.2.0-beta.2";
|
|
10226
10274
|
export { PLUGIN_CSS_NAME, PLUGIN_SWC_NAME, core_rspack as rspack, createRsbuild, defaultAllowedOrigins, defineConfig, ensureAssetPrefix, loadConfig_loadConfig as loadConfig, loadEnv, logger_createLogger as createLogger, mergeRsbuildConfig, mrmime_lookup, runCLI, src_logger as logger, src_version as version };
|
|
@@ -3,6 +3,8 @@ import type { MaybePromise } from '../types/utils.js';
|
|
|
3
3
|
type Cleanup = () => MaybePromise<void>;
|
|
4
4
|
export type RestartManager = {
|
|
5
5
|
/** Whether a restart executor is available. */ readonly canRestart: boolean;
|
|
6
|
+
/** Store the dynamic port for the next restart. */ setPort(port: number): void;
|
|
7
|
+
/** Consume the dynamic port associated with restart options. */ inheritPort(options?: object): number | undefined;
|
|
6
8
|
/** Register a cleanup callback and return a function that unregisters it. */ registerCleanup(cleanup: Cleanup): () => void;
|
|
7
9
|
/** Handle a restart request and return whether the restart succeeded. */ requestRestart(context: RestartContext): Promise<boolean>;
|
|
8
10
|
};
|
package/dist/server/helper.d.ts
CHANGED
|
@@ -60,7 +60,7 @@ export declare function printServerURLs({ urls: originalUrls, port, routes, prot
|
|
|
60
60
|
strictPort: boolean;
|
|
61
61
|
tryLimits?: number;
|
|
62
62
|
}) => Promise<number>;
|
|
63
|
-
export declare const resolvePort: (config: NormalizedConfig) => Promise<{
|
|
63
|
+
export declare const resolvePort: (config: NormalizedConfig, lastPort?: number) => Promise<{
|
|
64
64
|
port: number;
|
|
65
65
|
portTip: string | undefined;
|
|
66
66
|
}>;
|