xworkmate-app/lib/runtime/runtime_models_settings_snapshot.dart
2026-04-06 19:01:24 +08:00

671 lines
24 KiB
Dart

// ignore_for_file: unused_import, unnecessary_import
import 'dart:convert';
import '../i18n/app_language.dart';
import '../models/app_models.dart';
import 'runtime_models_connection.dart';
import 'runtime_models_profiles.dart';
import 'runtime_models_configs.dart';
import 'runtime_models_runtime_payloads.dart';
import 'runtime_models_gateway_entities.dart';
import 'runtime_models_multi_agent.dart';
class SettingsSnapshot {
const SettingsSnapshot({
required this.appLanguage,
required this.appActive,
required this.launchAtLogin,
required this.showDockIcon,
required this.workspacePath,
required this.remoteProjectRoot,
required this.cliPath,
required this.codeAgentRuntimeMode,
required this.codexCliPath,
required this.defaultModel,
required this.defaultProvider,
required this.gatewayProfiles,
required this.externalAcpEndpoints,
required this.authorizedSkillDirectories,
required this.ollamaLocal,
required this.ollamaCloud,
required this.vault,
required this.aiGateway,
required this.webSessionPersistence,
required this.multiAgent,
required this.experimentalCanvas,
required this.experimentalBridge,
required this.experimentalDebug,
required this.accountBaseUrl,
required this.accountUsername,
required this.accountWorkspace,
required this.accountWorkspaceFollowed,
required this.accountLocalMode,
required this.linuxDesktop,
required this.assistantExecutionTarget,
required this.assistantPermissionLevel,
required this.assistantNavigationDestinations,
required this.assistantCustomTaskTitles,
required this.assistantArchivedTaskKeys,
required this.savedGatewayTargets,
required this.assistantLastSessionKey,
});
final AppLanguage appLanguage;
final bool appActive;
final bool launchAtLogin;
final bool showDockIcon;
final String workspacePath;
final String remoteProjectRoot;
final String cliPath;
final CodeAgentRuntimeMode codeAgentRuntimeMode;
final String codexCliPath;
final String defaultModel;
final String defaultProvider;
final List<GatewayConnectionProfile> gatewayProfiles;
final List<ExternalAcpEndpointProfile> externalAcpEndpoints;
final List<AuthorizedSkillDirectory> authorizedSkillDirectories;
final OllamaLocalConfig ollamaLocal;
final OllamaCloudConfig ollamaCloud;
final VaultConfig vault;
final AiGatewayProfile aiGateway;
final WebSessionPersistenceConfig webSessionPersistence;
final MultiAgentConfig multiAgent;
final bool experimentalCanvas;
final bool experimentalBridge;
final bool experimentalDebug;
final String accountBaseUrl;
final String accountUsername;
final String accountWorkspace;
final bool accountWorkspaceFollowed;
final bool accountLocalMode;
final LinuxDesktopConfig linuxDesktop;
final AssistantExecutionTarget assistantExecutionTarget;
final AssistantPermissionLevel assistantPermissionLevel;
final List<AssistantFocusEntry> assistantNavigationDestinations;
final Map<String, String> assistantCustomTaskTitles;
final List<String> assistantArchivedTaskKeys;
final List<String> savedGatewayTargets;
final String assistantLastSessionKey;
factory SettingsSnapshot.defaults() {
return SettingsSnapshot(
appLanguage: AppLanguage.zh,
appActive: true,
launchAtLogin: false,
showDockIcon: true,
workspacePath: '',
remoteProjectRoot: '',
cliPath: 'openclaw',
codeAgentRuntimeMode: CodeAgentRuntimeMode.externalCli,
codexCliPath: '',
defaultModel: '',
defaultProvider: 'gateway',
gatewayProfiles: normalizeGatewayProfiles(),
externalAcpEndpoints: normalizeExternalAcpEndpoints(),
authorizedSkillDirectories: normalizeAuthorizedSkillDirectories(),
ollamaLocal: OllamaLocalConfig.defaults(),
ollamaCloud: OllamaCloudConfig.defaults(),
vault: VaultConfig.defaults(),
aiGateway: AiGatewayProfile.defaults(),
webSessionPersistence: WebSessionPersistenceConfig.defaults(),
multiAgent: MultiAgentConfig.defaults(),
experimentalCanvas: false,
experimentalBridge: false,
experimentalDebug: false,
accountBaseUrl: 'https://accounts.svc.plus',
accountUsername: '',
accountWorkspace: 'Default Workspace',
accountWorkspaceFollowed: false,
accountLocalMode: true,
linuxDesktop: LinuxDesktopConfig.defaults(),
assistantExecutionTarget: AssistantExecutionTarget.singleAgent,
assistantPermissionLevel: AssistantPermissionLevel.defaultAccess,
assistantNavigationDestinations: kAssistantNavigationDestinationDefaults,
assistantCustomTaskTitles: const <String, String>{},
assistantArchivedTaskKeys: const <String>[],
savedGatewayTargets: const <String>[],
assistantLastSessionKey: '',
);
}
SettingsSnapshot copyWith({
AppLanguage? appLanguage,
bool? appActive,
bool? launchAtLogin,
bool? showDockIcon,
String? workspacePath,
String? remoteProjectRoot,
String? cliPath,
CodeAgentRuntimeMode? codeAgentRuntimeMode,
String? codexCliPath,
String? defaultModel,
String? defaultProvider,
List<GatewayConnectionProfile>? gatewayProfiles,
List<ExternalAcpEndpointProfile>? externalAcpEndpoints,
List<AuthorizedSkillDirectory>? authorizedSkillDirectories,
OllamaLocalConfig? ollamaLocal,
OllamaCloudConfig? ollamaCloud,
VaultConfig? vault,
AiGatewayProfile? aiGateway,
WebSessionPersistenceConfig? webSessionPersistence,
MultiAgentConfig? multiAgent,
bool? experimentalCanvas,
bool? experimentalBridge,
bool? experimentalDebug,
String? accountBaseUrl,
String? accountUsername,
String? accountWorkspace,
bool? accountWorkspaceFollowed,
bool? accountLocalMode,
LinuxDesktopConfig? linuxDesktop,
AssistantExecutionTarget? assistantExecutionTarget,
AssistantPermissionLevel? assistantPermissionLevel,
List<AssistantFocusEntry>? assistantNavigationDestinations,
Map<String, String>? assistantCustomTaskTitles,
List<String>? assistantArchivedTaskKeys,
List<String>? savedGatewayTargets,
String? assistantLastSessionKey,
}) {
final resolvedGatewayProfiles = gatewayProfiles != null
? normalizeGatewayProfiles(profiles: gatewayProfiles)
: this.gatewayProfiles;
final resolvedExternalAcpEndpoints = externalAcpEndpoints != null
? normalizeExternalAcpEndpoints(profiles: externalAcpEndpoints)
: this.externalAcpEndpoints;
final resolvedAuthorizedSkillDirectories =
authorizedSkillDirectories != null
? normalizeAuthorizedSkillDirectories(
directories: authorizedSkillDirectories,
)
: this.authorizedSkillDirectories;
return SettingsSnapshot(
appLanguage: appLanguage ?? this.appLanguage,
appActive: appActive ?? this.appActive,
launchAtLogin: launchAtLogin ?? this.launchAtLogin,
showDockIcon: showDockIcon ?? this.showDockIcon,
workspacePath: workspacePath ?? this.workspacePath,
remoteProjectRoot: remoteProjectRoot ?? this.remoteProjectRoot,
cliPath: cliPath ?? this.cliPath,
codeAgentRuntimeMode: codeAgentRuntimeMode ?? this.codeAgentRuntimeMode,
codexCliPath: codexCliPath ?? this.codexCliPath,
defaultModel: defaultModel ?? this.defaultModel,
defaultProvider: defaultProvider ?? this.defaultProvider,
gatewayProfiles: resolvedGatewayProfiles,
externalAcpEndpoints: resolvedExternalAcpEndpoints,
authorizedSkillDirectories: resolvedAuthorizedSkillDirectories,
ollamaLocal: ollamaLocal ?? this.ollamaLocal,
ollamaCloud: ollamaCloud ?? this.ollamaCloud,
vault: vault ?? this.vault,
aiGateway: aiGateway ?? this.aiGateway,
webSessionPersistence:
webSessionPersistence ?? this.webSessionPersistence,
multiAgent: multiAgent ?? this.multiAgent,
experimentalCanvas: experimentalCanvas ?? this.experimentalCanvas,
experimentalBridge: experimentalBridge ?? this.experimentalBridge,
experimentalDebug: experimentalDebug ?? this.experimentalDebug,
accountBaseUrl: accountBaseUrl ?? this.accountBaseUrl,
accountUsername: accountUsername ?? this.accountUsername,
accountWorkspace: accountWorkspace ?? this.accountWorkspace,
accountWorkspaceFollowed:
accountWorkspaceFollowed ?? this.accountWorkspaceFollowed,
accountLocalMode: accountLocalMode ?? this.accountLocalMode,
linuxDesktop: linuxDesktop ?? this.linuxDesktop,
assistantExecutionTarget:
assistantExecutionTarget ?? this.assistantExecutionTarget,
assistantPermissionLevel:
assistantPermissionLevel ?? this.assistantPermissionLevel,
assistantNavigationDestinations:
assistantNavigationDestinations ??
this.assistantNavigationDestinations,
assistantCustomTaskTitles:
assistantCustomTaskTitles ?? this.assistantCustomTaskTitles,
assistantArchivedTaskKeys:
assistantArchivedTaskKeys ?? this.assistantArchivedTaskKeys,
savedGatewayTargets: normalizeSavedGatewayTargets(
savedGatewayTargets ?? this.savedGatewayTargets,
),
assistantLastSessionKey:
assistantLastSessionKey ?? this.assistantLastSessionKey,
);
}
Map<String, dynamic> toJson() {
return {
'appLanguage': appLanguage.name,
'appActive': appActive,
'launchAtLogin': launchAtLogin,
'showDockIcon': showDockIcon,
'workspacePath': workspacePath,
'remoteProjectRoot': remoteProjectRoot,
'cliPath': cliPath,
'codeAgentRuntimeMode': codeAgentRuntimeMode.name,
'codexCliPath': codexCliPath,
'defaultModel': defaultModel,
'defaultProvider': defaultProvider,
'gatewayProfiles': gatewayProfiles
.map((item) => item.toJson())
.toList(growable: false),
'externalAcpEndpoints': externalAcpEndpoints
.map((item) => item.toJson())
.toList(growable: false),
'authorizedSkillDirectories': authorizedSkillDirectories
.map((item) => item.toJson())
.toList(growable: false),
'ollamaLocal': ollamaLocal.toJson(),
'ollamaCloud': ollamaCloud.toJson(),
'vault': vault.toJson(),
'aiGateway': aiGateway.toJson(),
'webSessionPersistence': webSessionPersistence.toJson(),
'multiAgent': multiAgent.toJson(),
'experimentalCanvas': experimentalCanvas,
'experimentalBridge': experimentalBridge,
'experimentalDebug': experimentalDebug,
'accountBaseUrl': accountBaseUrl,
'accountUsername': accountUsername,
'accountWorkspace': accountWorkspace,
'accountWorkspaceFollowed': accountWorkspaceFollowed,
'accountLocalMode': accountLocalMode,
'linuxDesktop': linuxDesktop.toJson(),
'assistantExecutionTarget': assistantExecutionTarget.name,
'assistantPermissionLevel': assistantPermissionLevel.name,
'assistantNavigationDestinations': assistantNavigationDestinations
.map((item) => item.name)
.toList(growable: false),
'assistantCustomTaskTitles': assistantCustomTaskTitles,
'assistantArchivedTaskKeys': assistantArchivedTaskKeys,
'savedGatewayTargets': savedGatewayTargets,
'assistantLastSessionKey': assistantLastSessionKey,
};
}
factory SettingsSnapshot.fromJson(Map<String, dynamic> json) {
Map<String, String> normalizeTaskTitles(Object? value) {
if (value is! Map) {
return const <String, String>{};
}
final normalized = <String, String>{};
value.forEach((key, title) {
final normalizedKey = key.toString().trim();
final normalizedTitle = title.toString().trim();
if (normalizedKey.isEmpty || normalizedTitle.isEmpty) {
return;
}
normalized[normalizedKey] = normalizedTitle;
});
return normalized;
}
List<String> normalizeTaskKeys(Object? value) {
if (value is! List) {
return const <String>[];
}
final normalized = <String>[];
final seen = <String>{};
for (final item in value) {
final normalizedKey = item?.toString().trim() ?? '';
if (normalizedKey.isEmpty || !seen.add(normalizedKey)) {
continue;
}
normalized.add(normalizedKey);
}
return normalized;
}
List<String> normalizeSavedGatewayTargetsFromJson(Object? value) {
if (value is! List) {
return const <String>[];
}
return normalizeSavedGatewayTargets(
value.map((item) => item?.toString() ?? ''),
);
}
final rawAssistantNavigationDestinations =
json['assistantNavigationDestinations'];
final assistantNavigationDestinations =
rawAssistantNavigationDestinations is List
? normalizeAssistantNavigationDestinations(
rawAssistantNavigationDestinations
.map(
(item) =>
AssistantFocusEntryCopy.fromJsonValue(item?.toString()),
)
.whereType<AssistantFocusEntry>(),
)
: kAssistantNavigationDestinationDefaults;
final gatewayProfiles = normalizeGatewayProfiles(
profiles: ((json['gatewayProfiles'] as List?) ?? const <Object>[])
.whereType<Map>()
.map(
(item) =>
GatewayConnectionProfile.fromJson(item.cast<String, dynamic>()),
),
);
final externalAcpEndpoints = normalizeExternalAcpEndpoints(
profiles: ((json['externalAcpEndpoints'] as List?) ?? const <Object>[])
.whereType<Map>()
.map(
(item) => ExternalAcpEndpointProfile.fromJson(
item.cast<String, dynamic>(),
),
),
);
final authorizedSkillDirectories = normalizeAuthorizedSkillDirectories(
directories:
((json['authorizedSkillDirectories'] as List?) ?? const <Object>[])
.whereType<Map>()
.map(
(item) => AuthorizedSkillDirectory.fromJson(
item.cast<String, dynamic>(),
),
),
);
return SettingsSnapshot(
appLanguage: AppLanguageCopy.fromJsonValue(
json['appLanguage'] as String?,
),
appActive: json['appActive'] as bool? ?? true,
launchAtLogin: json['launchAtLogin'] as bool? ?? false,
showDockIcon: json['showDockIcon'] as bool? ?? true,
workspacePath:
json['workspacePath'] as String? ??
SettingsSnapshot.defaults().workspacePath,
remoteProjectRoot:
json['remoteProjectRoot'] as String? ??
SettingsSnapshot.defaults().remoteProjectRoot,
cliPath:
json['cliPath'] as String? ?? SettingsSnapshot.defaults().cliPath,
codeAgentRuntimeMode: CodeAgentRuntimeModeCopy.fromJsonValue(
json['codeAgentRuntimeMode'] as String?,
),
codexCliPath:
json['codexCliPath'] as String? ??
SettingsSnapshot.defaults().codexCliPath,
defaultModel:
json['defaultModel'] as String? ??
SettingsSnapshot.defaults().defaultModel,
defaultProvider:
json['defaultProvider'] as String? ??
SettingsSnapshot.defaults().defaultProvider,
gatewayProfiles: gatewayProfiles,
externalAcpEndpoints: externalAcpEndpoints,
authorizedSkillDirectories: authorizedSkillDirectories,
ollamaLocal: OllamaLocalConfig.fromJson(
(json['ollamaLocal'] as Map?)?.cast<String, dynamic>() ?? const {},
),
ollamaCloud: OllamaCloudConfig.fromJson(
(json['ollamaCloud'] as Map?)?.cast<String, dynamic>() ?? const {},
),
vault: VaultConfig.fromJson(
(json['vault'] as Map?)?.cast<String, dynamic>() ?? const {},
),
aiGateway: AiGatewayProfile.fromJson(
(json['aiGateway'] as Map?)?.cast<String, dynamic>() ??
(json['apisix'] as Map?)?.cast<String, dynamic>() ??
const {},
),
webSessionPersistence: WebSessionPersistenceConfig.fromJson(
(json['webSessionPersistence'] as Map?)?.cast<String, dynamic>() ??
const {},
),
multiAgent: MultiAgentConfig.fromJson(
(json['multiAgent'] as Map?)?.cast<String, dynamic>() ?? const {},
),
experimentalCanvas: json['experimentalCanvas'] as bool? ?? false,
experimentalBridge: json['experimentalBridge'] as bool? ?? false,
experimentalDebug: json['experimentalDebug'] as bool? ?? false,
accountBaseUrl:
json['accountBaseUrl'] as String? ??
SettingsSnapshot.defaults().accountBaseUrl,
accountUsername: json['accountUsername'] as String? ?? '',
accountWorkspace:
json['accountWorkspace'] as String? ??
SettingsSnapshot.defaults().accountWorkspace,
accountWorkspaceFollowed:
json['accountWorkspaceFollowed'] as bool? ?? false,
accountLocalMode: json['accountLocalMode'] as bool? ?? true,
linuxDesktop: LinuxDesktopConfig.fromJson(
(json['linuxDesktop'] as Map?)?.cast<String, dynamic>() ?? const {},
),
assistantExecutionTarget: AssistantExecutionTargetCopy.fromJsonValue(
json['assistantExecutionTarget'] as String?,
),
assistantPermissionLevel: AssistantPermissionLevelCopy.fromJsonValue(
json['assistantPermissionLevel'] as String?,
),
assistantNavigationDestinations: assistantNavigationDestinations,
assistantCustomTaskTitles: normalizeTaskTitles(
json['assistantCustomTaskTitles'],
),
assistantArchivedTaskKeys: normalizeTaskKeys(
json['assistantArchivedTaskKeys'],
),
savedGatewayTargets: normalizeSavedGatewayTargetsFromJson(
json['savedGatewayTargets'],
),
assistantLastSessionKey: json['assistantLastSessionKey'] as String? ?? '',
);
}
static SettingsSnapshot fromJsonString(String? raw) {
if (raw == null || raw.trim().isEmpty) {
return SettingsSnapshot.defaults();
}
try {
final decoded = jsonDecode(raw) as Map<String, dynamic>;
return SettingsSnapshot.fromJson(decoded);
} catch (_) {
return SettingsSnapshot.defaults();
}
}
String toJsonString() => jsonEncode(toJson());
GatewayConnectionProfile get primaryLocalGatewayProfile =>
gatewayProfiles[kGatewayLocalProfileIndex];
GatewayConnectionProfile get primaryRemoteGatewayProfile =>
gatewayProfiles[kGatewayRemoteProfileIndex];
GatewayConnectionProfile? gatewayProfileForExecutionTarget(
AssistantExecutionTarget target,
) {
return switch (target) {
AssistantExecutionTarget.singleAgent => null,
AssistantExecutionTarget.local => primaryLocalGatewayProfile,
AssistantExecutionTarget.remote => primaryRemoteGatewayProfile,
};
}
SettingsSnapshot copyWithGatewayProfileAt(
int index,
GatewayConnectionProfile profile,
) {
return copyWith(
gatewayProfiles: replaceGatewayProfileAt(gatewayProfiles, index, profile),
);
}
SettingsSnapshot copyWithGatewayProfileForExecutionTarget(
AssistantExecutionTarget target,
GatewayConnectionProfile profile,
) {
final index = switch (target) {
AssistantExecutionTarget.local => kGatewayLocalProfileIndex,
AssistantExecutionTarget.remote => kGatewayRemoteProfileIndex,
AssistantExecutionTarget.singleAgent => null,
};
if (index == null) {
return this;
}
return copyWithGatewayProfileAt(index, profile);
}
ExternalAcpEndpointProfile externalAcpEndpointForProvider(
SingleAgentProvider provider,
) {
return externalAcpEndpointForProviderId(provider.providerId) ??
ExternalAcpEndpointProfile.defaultsForProvider(provider);
}
ExternalAcpEndpointProfile? externalAcpEndpointForProviderId(
String providerId,
) {
final normalized = normalizeSingleAgentProviderId(providerId);
if (normalized.isEmpty) {
return null;
}
for (final item in externalAcpEndpoints) {
if (item.providerKey == normalized) {
return item;
}
}
return null;
}
SingleAgentProvider resolveSingleAgentProvider(SingleAgentProvider provider) {
if (provider.isAuto) {
return SingleAgentProvider.auto;
}
final profile = externalAcpEndpointForProviderId(provider.providerId);
if (profile != null) {
return profile.toProvider();
}
return provider;
}
SingleAgentProvider singleAgentProviderForId(String providerId) {
final resolved = normalizeSingleAgentProviderId(providerId);
if (resolved.isEmpty || resolved == SingleAgentProvider.auto.providerId) {
return SingleAgentProvider.auto;
}
final normalizedSelection = SingleAgentProvider.fromJsonValue(resolved);
final profile = externalAcpEndpointForProviderId(
normalizedSelection.providerId,
);
if (profile != null) {
return profile.toProvider();
}
return normalizedSelection;
}
SingleAgentProvider sanitizeSingleAgentProviderSelection(
SingleAgentProvider provider,
) {
final resolved = resolveSingleAgentProvider(provider);
if (resolved.isAuto) {
return SingleAgentProvider.auto;
}
for (final saved in savedSingleAgentProviders) {
if (saved.providerId == resolved.providerId) {
return saved;
}
}
if (kKnownSingleAgentProviders.any(
(item) => item.providerId == resolved.providerId,
)) {
return resolved;
}
if (savedSingleAgentProviders.isNotEmpty) {
return savedSingleAgentProviders.first;
}
return SingleAgentProvider.auto;
}
List<SingleAgentProvider> get availableSingleAgentProviders =>
normalizeSingleAgentProviderList(
externalAcpEndpoints.map((item) => item.toProvider()),
);
List<SingleAgentProvider> get savedSingleAgentProviders =>
normalizeSingleAgentProviderList(
externalAcpEndpoints
.where((item) => item.enabled && item.endpoint.trim().isNotEmpty)
.map((item) => item.toProvider()),
);
bool isGatewayTargetSaved(AssistantExecutionTarget target) {
final targetKey = switch (target) {
AssistantExecutionTarget.local => 'local',
AssistantExecutionTarget.remote => 'remote',
_ => '',
};
return targetKey.isNotEmpty && savedGatewayTargets.contains(targetKey);
}
SettingsSnapshot markGatewayTargetSaved(AssistantExecutionTarget target) {
final targetKey = switch (target) {
AssistantExecutionTarget.local => 'local',
AssistantExecutionTarget.remote => 'remote',
_ => '',
};
if (targetKey.isEmpty || savedGatewayTargets.contains(targetKey)) {
return this;
}
return copyWith(
savedGatewayTargets: <String>[...savedGatewayTargets, targetKey],
);
}
List<SingleAgentProvider> visibleSingleAgentProviders(
Iterable<SingleAgentProvider> availableProviders,
) {
final allowedProviderIds = savedSingleAgentProviders
.map((item) => item.providerId)
.toSet();
return normalizeSingleAgentProviderList(
availableProviders.where(
(item) => allowedProviderIds.contains(item.providerId),
),
);
}
List<AssistantExecutionTarget> visibleAssistantExecutionTargets({
required Iterable<AssistantExecutionTarget> supportedTargets,
required Iterable<SingleAgentProvider> availableSingleAgentProviders,
}) {
final supported = supportedTargets.toSet();
final visible = <AssistantExecutionTarget>[];
if (supported.contains(AssistantExecutionTarget.singleAgent) &&
visibleSingleAgentProviders(availableSingleAgentProviders).isNotEmpty) {
visible.add(AssistantExecutionTarget.singleAgent);
}
if (supported.contains(AssistantExecutionTarget.local) &&
isGatewayTargetSaved(AssistantExecutionTarget.local)) {
visible.add(AssistantExecutionTarget.local);
}
if (supported.contains(AssistantExecutionTarget.remote) &&
isGatewayTargetSaved(AssistantExecutionTarget.remote)) {
visible.add(AssistantExecutionTarget.remote);
}
return List<AssistantExecutionTarget>.unmodifiable(visible);
}
SettingsSnapshot copyWithExternalAcpEndpointForProvider(
SingleAgentProvider provider,
ExternalAcpEndpointProfile profile,
) {
return copyWith(
externalAcpEndpoints: replaceExternalAcpEndpointForProvider(
externalAcpEndpoints,
provider,
profile,
),
);
}
}
List<String> normalizeSavedGatewayTargets(Iterable<String> rawTargets) {
final normalized = <String>[];
final seen = <String>{};
for (final item in rawTargets) {
final normalizedTarget = item.trim().toLowerCase();
if ((normalizedTarget != 'local' && normalizedTarget != 'remote') ||
!seen.add(normalizedTarget)) {
continue;
}
normalized.add(normalizedTarget);
}
return List<String>.unmodifiable(normalized);
}