@nice2dev/ui-tools 1.0.11 → 1.0.12
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/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/api-designer.ts","../src/download-manager.ts","../src/torrent-client.ts","../src/traceless.ts","../src/accessibility-i18n.ts","../src/icon-tools.ts"],"sourcesContent":["/**\r\n * @file api-designer.ts\r\n * @module @nice2dev/ui-tools\r\n * @description PRO-13.1 — API Designer\r\n *\r\n * Types for API design tools: OpenAPI, GraphQL, AsyncAPI, Protocol Buffers,\r\n * Thrift, Avro, schema visualization, mock servers, code generation, and more.\r\n */\r\n\r\n// =============================================================================\r\n// Common Types\r\n// =============================================================================\r\n\r\n/** HTTP method type */\r\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'TRACE';\r\n\r\n/** Parameter location */\r\nexport type ParameterLocation = 'path' | 'query' | 'header' | 'cookie' | 'body';\r\n\r\n/** Data format type */\r\nexport type SchemaFormat =\r\n | 'int32'\r\n | 'int64'\r\n | 'float'\r\n | 'double'\r\n | 'byte'\r\n | 'binary'\r\n | 'date'\r\n | 'date-time'\r\n | 'password'\r\n | 'email'\r\n | 'uri'\r\n | 'uuid'\r\n | 'hostname'\r\n | 'ipv4'\r\n | 'ipv6';\r\n\r\n/** Primitive schema type */\r\nexport type SchemaType = 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object' | 'null';\r\n\r\n// =============================================================================\r\n// OpenAPI / Swagger Editor\r\n// =============================================================================\r\n\r\n/** OpenAPI specification document */\r\nexport interface OpenAPISpec {\r\n /** OpenAPI version (3.0.x, 3.1.x) */\r\n openapi: string;\r\n /** API information */\r\n info: OpenAPIInfo;\r\n /** Server URLs */\r\n servers?: OpenAPIServer[];\r\n /** API paths */\r\n paths: Record<string, OpenAPIPathItem>;\r\n /** Reusable components */\r\n components?: OpenAPIComponents;\r\n /** Security requirements */\r\n security?: OpenAPISecurityRequirement[];\r\n /** Tags for grouping */\r\n tags?: OpenAPITag[];\r\n /** External documentation */\r\n externalDocs?: OpenAPIExternalDocs;\r\n}\r\n\r\n/** API info object */\r\nexport interface OpenAPIInfo {\r\n /** API title */\r\n title: string;\r\n /** API version */\r\n version: string;\r\n /** API description */\r\n description?: string;\r\n /** Terms of service URL */\r\n termsOfService?: string;\r\n /** Contact information */\r\n contact?: OpenAPIContact;\r\n /** License information */\r\n license?: OpenAPILicense;\r\n}\r\n\r\n/** Contact information */\r\nexport interface OpenAPIContact {\r\n name?: string;\r\n url?: string;\r\n email?: string;\r\n}\r\n\r\n/** License information */\r\nexport interface OpenAPILicense {\r\n name: string;\r\n url?: string;\r\n identifier?: string; // SPDX identifier (3.1+)\r\n}\r\n\r\n/** Server object */\r\nexport interface OpenAPIServer {\r\n url: string;\r\n description?: string;\r\n variables?: Record<string, OpenAPIServerVariable>;\r\n}\r\n\r\n/** Server variable */\r\nexport interface OpenAPIServerVariable {\r\n default: string;\r\n description?: string;\r\n enum?: string[];\r\n}\r\n\r\n/** Path item object */\r\nexport interface OpenAPIPathItem {\r\n summary?: string;\r\n description?: string;\r\n get?: OpenAPIOperation;\r\n post?: OpenAPIOperation;\r\n put?: OpenAPIOperation;\r\n patch?: OpenAPIOperation;\r\n delete?: OpenAPIOperation;\r\n head?: OpenAPIOperation;\r\n options?: OpenAPIOperation;\r\n trace?: OpenAPIOperation;\r\n parameters?: OpenAPIParameter[];\r\n}\r\n\r\n/** Operation object */\r\nexport interface OpenAPIOperation {\r\n operationId?: string;\r\n summary?: string;\r\n description?: string;\r\n tags?: string[];\r\n parameters?: OpenAPIParameter[];\r\n requestBody?: OpenAPIRequestBody;\r\n responses: Record<string, OpenAPIResponse>;\r\n security?: OpenAPISecurityRequirement[];\r\n deprecated?: boolean;\r\n servers?: OpenAPIServer[];\r\n externalDocs?: OpenAPIExternalDocs;\r\n 'x-codegen-request-body-name'?: string;\r\n callbacks?: Record<string, Record<string, OpenAPIPathItem>>;\r\n}\r\n\r\n/** Parameter object */\r\nexport interface OpenAPIParameter {\r\n name: string;\r\n in: ParameterLocation;\r\n description?: string;\r\n required?: boolean;\r\n deprecated?: boolean;\r\n allowEmptyValue?: boolean;\r\n schema?: OpenAPISchema;\r\n style?: ParameterStyle;\r\n explode?: boolean;\r\n example?: unknown;\r\n examples?: Record<string, OpenAPIExample>;\r\n}\r\n\r\n/** Parameter serialization style */\r\nexport type ParameterStyle =\r\n | 'matrix'\r\n | 'label'\r\n | 'form'\r\n | 'simple'\r\n | 'spaceDelimited'\r\n | 'pipeDelimited'\r\n | 'deepObject';\r\n\r\n/** Request body object */\r\nexport interface OpenAPIRequestBody {\r\n description?: string;\r\n required?: boolean;\r\n content: Record<string, OpenAPIMediaType>;\r\n}\r\n\r\n/** Media type object */\r\nexport interface OpenAPIMediaType {\r\n schema?: OpenAPISchema;\r\n example?: unknown;\r\n examples?: Record<string, OpenAPIExample>;\r\n encoding?: Record<string, OpenAPIEncoding>;\r\n}\r\n\r\n/** Encoding object for multipart */\r\nexport interface OpenAPIEncoding {\r\n contentType?: string;\r\n headers?: Record<string, OpenAPIHeader>;\r\n style?: ParameterStyle;\r\n explode?: boolean;\r\n allowReserved?: boolean;\r\n}\r\n\r\n/** Header object */\r\nexport interface OpenAPIHeader extends Omit<OpenAPIParameter, 'name' | 'in'> {}\r\n\r\n/** Response object */\r\nexport interface OpenAPIResponse {\r\n description: string;\r\n headers?: Record<string, OpenAPIHeader>;\r\n content?: Record<string, OpenAPIMediaType>;\r\n links?: Record<string, OpenAPILink>;\r\n}\r\n\r\n/** Link object */\r\nexport interface OpenAPILink {\r\n operationRef?: string;\r\n operationId?: string;\r\n parameters?: Record<string, unknown>;\r\n requestBody?: unknown;\r\n description?: string;\r\n server?: OpenAPIServer;\r\n}\r\n\r\n/** Schema object */\r\nexport interface OpenAPISchema {\r\n $ref?: string;\r\n type?: SchemaType | SchemaType[];\r\n format?: SchemaFormat | string;\r\n title?: string;\r\n description?: string;\r\n default?: unknown;\r\n example?: unknown;\r\n enum?: unknown[];\r\n const?: unknown;\r\n nullable?: boolean; // 3.0 only, deprecated in 3.1\r\n readOnly?: boolean;\r\n writeOnly?: boolean;\r\n deprecated?: boolean;\r\n\r\n // String validation\r\n minLength?: number;\r\n maxLength?: number;\r\n pattern?: string;\r\n\r\n // Numeric validation\r\n minimum?: number;\r\n maximum?: number;\r\n exclusiveMinimum?: number | boolean;\r\n exclusiveMaximum?: number | boolean;\r\n multipleOf?: number;\r\n\r\n // Array validation\r\n items?: OpenAPISchema;\r\n minItems?: number;\r\n maxItems?: number;\r\n uniqueItems?: boolean;\r\n contains?: OpenAPISchema;\r\n minContains?: number;\r\n maxContains?: number;\r\n\r\n // Object validation\r\n properties?: Record<string, OpenAPISchema>;\r\n additionalProperties?: boolean | OpenAPISchema;\r\n required?: string[];\r\n minProperties?: number;\r\n maxProperties?: number;\r\n patternProperties?: Record<string, OpenAPISchema>;\r\n propertyNames?: OpenAPISchema;\r\n\r\n // Composition\r\n allOf?: OpenAPISchema[];\r\n oneOf?: OpenAPISchema[];\r\n anyOf?: OpenAPISchema[];\r\n not?: OpenAPISchema;\r\n discriminator?: OpenAPIDiscriminator;\r\n\r\n // External\r\n externalDocs?: OpenAPIExternalDocs;\r\n xml?: OpenAPIXml;\r\n}\r\n\r\n/** Discriminator object */\r\nexport interface OpenAPIDiscriminator {\r\n propertyName: string;\r\n mapping?: Record<string, string>;\r\n}\r\n\r\n/** XML object */\r\nexport interface OpenAPIXml {\r\n name?: string;\r\n namespace?: string;\r\n prefix?: string;\r\n attribute?: boolean;\r\n wrapped?: boolean;\r\n}\r\n\r\n/** Example object */\r\nexport interface OpenAPIExample {\r\n summary?: string;\r\n description?: string;\r\n value?: unknown;\r\n externalValue?: string;\r\n}\r\n\r\n/** Security scheme object */\r\nexport interface OpenAPISecurityScheme {\r\n type: 'apiKey' | 'http' | 'oauth2' | 'openIdConnect' | 'mutualTLS';\r\n description?: string;\r\n name?: string; // for apiKey\r\n in?: 'query' | 'header' | 'cookie'; // for apiKey\r\n scheme?: string; // for http\r\n bearerFormat?: string; // for http bearer\r\n flows?: OpenAPIOAuthFlows; // for oauth2\r\n openIdConnectUrl?: string; // for openIdConnect\r\n}\r\n\r\n/** OAuth flows object */\r\nexport interface OpenAPIOAuthFlows {\r\n implicit?: OpenAPIOAuthFlow;\r\n password?: OpenAPIOAuthFlow;\r\n clientCredentials?: OpenAPIOAuthFlow;\r\n authorizationCode?: OpenAPIOAuthFlow;\r\n}\r\n\r\n/** OAuth flow object */\r\nexport interface OpenAPIOAuthFlow {\r\n authorizationUrl?: string;\r\n tokenUrl?: string;\r\n refreshUrl?: string;\r\n scopes: Record<string, string>;\r\n}\r\n\r\n/** Security requirement object */\r\nexport type OpenAPISecurityRequirement = Record<string, string[]>;\r\n\r\n/** Tag object */\r\nexport interface OpenAPITag {\r\n name: string;\r\n description?: string;\r\n externalDocs?: OpenAPIExternalDocs;\r\n}\r\n\r\n/** External documentation object */\r\nexport interface OpenAPIExternalDocs {\r\n url: string;\r\n description?: string;\r\n}\r\n\r\n/** Components object */\r\nexport interface OpenAPIComponents {\r\n schemas?: Record<string, OpenAPISchema>;\r\n responses?: Record<string, OpenAPIResponse>;\r\n parameters?: Record<string, OpenAPIParameter>;\r\n examples?: Record<string, OpenAPIExample>;\r\n requestBodies?: Record<string, OpenAPIRequestBody>;\r\n headers?: Record<string, OpenAPIHeader>;\r\n securitySchemes?: Record<string, OpenAPISecurityScheme>;\r\n links?: Record<string, OpenAPILink>;\r\n callbacks?: Record<string, Record<string, OpenAPIPathItem>>;\r\n pathItems?: Record<string, OpenAPIPathItem>;\r\n}\r\n\r\n/** OpenAPI editor configuration */\r\nexport interface OpenAPIEditorConfig {\r\n /** Spec source (URL, file, or inline)*/\r\n source: OpenAPISource;\r\n /** Editor theme */\r\n theme?: 'light' | 'dark' | 'swagger';\r\n /** Enable spec validation */\r\n validation?: boolean;\r\n /** Validation rules */\r\n validationRules?: OpenAPIValidationConfig;\r\n /** Enable autocomplete */\r\n autocomplete?: boolean;\r\n /** Show preview panel */\r\n showPreview?: boolean;\r\n /** Preview layout */\r\n previewLayout?: 'split' | 'tabs';\r\n /** Enable YAML/JSON toggle */\r\n formatToggle?: boolean;\r\n /** Default format */\r\n defaultFormat?: 'yaml' | 'json';\r\n /** Read-only mode */\r\n readOnly?: boolean;\r\n /** Auto-save interval (ms) */\r\n autoSaveInterval?: number;\r\n /** Version history */\r\n enableHistory?: boolean;\r\n /** Collaboration mode */\r\n collaboration?: CollaborationConfig;\r\n}\r\n\r\n/** OpenAPI source configuration */\r\nexport interface OpenAPISource {\r\n type: 'url' | 'file' | 'inline';\r\n url?: string;\r\n content?: string;\r\n format?: 'yaml' | 'json';\r\n}\r\n\r\n/** Validation configuration */\r\nexport interface OpenAPIValidationConfig {\r\n /** Validate on change */\r\n validateOnChange?: boolean;\r\n /** Validation level */\r\n level?: 'error' | 'warning' | 'info';\r\n /** Rules to enable/disable */\r\n rules?: Record<string, boolean>;\r\n /** Custom validators */\r\n customValidators?: OpenAPIValidator[];\r\n}\r\n\r\n/** Custom validator */\r\nexport interface OpenAPIValidator {\r\n name: string;\r\n description?: string;\r\n validate: (spec: OpenAPISpec) => OpenAPIValidationResult[];\r\n}\r\n\r\n/** Validation result */\r\nexport interface OpenAPIValidationResult {\r\n level: 'error' | 'warning' | 'info';\r\n message: string;\r\n path: string;\r\n line?: number;\r\n column?: number;\r\n rule?: string;\r\n}\r\n\r\n/** Collaboration configuration */\r\nexport interface CollaborationConfig {\r\n enabled: boolean;\r\n provider?: 'yjs' | 'automerge' | 'custom';\r\n serverUrl?: string;\r\n roomId?: string;\r\n userName?: string;\r\n userColor?: string;\r\n}\r\n\r\n// =============================================================================\r\n// GraphQL Editor\r\n// =============================================================================\r\n\r\n/** GraphQL schema document */\r\nexport interface GraphQLSchemaDefinition {\r\n /** Raw SDL */\r\n sdl: string;\r\n /** Parsed types */\r\n types: GraphQLTypeDefinition[];\r\n /** Root query type name */\r\n queryType?: string;\r\n /** Root mutation type name */\r\n mutationType?: string;\r\n /** Root subscription type name */\r\n subscriptionType?: string;\r\n /** Directives */\r\n directives: GraphQLDirectiveDefinition[];\r\n}\r\n\r\n/** GraphQL type definition */\r\nexport interface GraphQLTypeDefinition {\r\n kind: GraphQLTypeKind;\r\n name: string;\r\n description?: string;\r\n fields?: GraphQLFieldDefinition[];\r\n interfaces?: string[];\r\n possibleTypes?: string[]; // for interface/union\r\n enumValues?: GraphQLEnumValue[];\r\n inputFields?: GraphQLInputValue[];\r\n directives?: GraphQLDirectiveUsage[];\r\n}\r\n\r\n/** GraphQL type kind */\r\nexport type GraphQLTypeKind = 'SCALAR' | 'OBJECT' | 'INTERFACE' | 'UNION' | 'ENUM' | 'INPUT_OBJECT';\r\n\r\n/** GraphQL field definition */\r\nexport interface GraphQLFieldDefinition {\r\n name: string;\r\n description?: string;\r\n type: GraphQLTypeRef;\r\n args?: GraphQLInputValue[];\r\n deprecationReason?: string;\r\n directives?: GraphQLDirectiveUsage[];\r\n}\r\n\r\n/** GraphQL type reference */\r\nexport interface GraphQLTypeRef {\r\n kind: 'SCALAR' | 'OBJECT' | 'INTERFACE' | 'UNION' | 'ENUM' | 'INPUT_OBJECT' | 'NON_NULL' | 'LIST';\r\n name?: string;\r\n ofType?: GraphQLTypeRef;\r\n}\r\n\r\n/** GraphQL input value (field arg or input field) */\r\nexport interface GraphQLInputValue {\r\n name: string;\r\n description?: string;\r\n type: GraphQLTypeRef;\r\n defaultValue?: string;\r\n deprecationReason?: string;\r\n directives?: GraphQLDirectiveUsage[];\r\n}\r\n\r\n/** GraphQL enum value */\r\nexport interface GraphQLEnumValue {\r\n name: string;\r\n description?: string;\r\n deprecationReason?: string;\r\n directives?: GraphQLDirectiveUsage[];\r\n}\r\n\r\n/** GraphQL directive definition */\r\nexport interface GraphQLDirectiveDefinition {\r\n name: string;\r\n description?: string;\r\n locations: GraphQLDirectiveLocation[];\r\n args?: GraphQLInputValue[];\r\n isRepeatable?: boolean;\r\n}\r\n\r\n/** GraphQL directive location */\r\nexport type GraphQLDirectiveLocation =\r\n | 'QUERY'\r\n | 'MUTATION'\r\n | 'SUBSCRIPTION'\r\n | 'FIELD'\r\n | 'FRAGMENT_DEFINITION'\r\n | 'FRAGMENT_SPREAD'\r\n | 'INLINE_FRAGMENT'\r\n | 'VARIABLE_DEFINITION'\r\n | 'SCHEMA'\r\n | 'SCALAR'\r\n | 'OBJECT'\r\n | 'FIELD_DEFINITION'\r\n | 'ARGUMENT_DEFINITION'\r\n | 'INTERFACE'\r\n | 'UNION'\r\n | 'ENUM'\r\n | 'ENUM_VALUE'\r\n | 'INPUT_OBJECT'\r\n | 'INPUT_FIELD_DEFINITION';\r\n\r\n/** GraphQL directive usage */\r\nexport interface GraphQLDirectiveUsage {\r\n name: string;\r\n args?: Record<string, unknown>;\r\n}\r\n\r\n/** GraphQL editor configuration */\r\nexport interface GraphQLEditorConfig {\r\n /** Schema source */\r\n source: GraphQLSource;\r\n /** Explorer enabled */\r\n showExplorer?: boolean;\r\n /** Documentation panel */\r\n showDocs?: boolean;\r\n /** Query history */\r\n enableHistory?: boolean;\r\n /** Prettify on save */\r\n prettify?: boolean;\r\n /** Tab size */\r\n tabSize?: number;\r\n /** Use tabs */\r\n useTabs?: boolean;\r\n /** Theme */\r\n theme?: 'light' | 'dark' | 'graphiql';\r\n /** Headers for introspection */\r\n headers?: Record<string, string>;\r\n /** Subscription endpoint */\r\n subscriptionEndpoint?: string;\r\n}\r\n\r\n/** GraphQL source */\r\nexport interface GraphQLSource {\r\n type: 'url' | 'file' | 'inline';\r\n /** Introspection endpoint URL */\r\n url?: string;\r\n /** SDL content */\r\n sdl?: string;\r\n /** File path */\r\n path?: string;\r\n}\r\n\r\n// =============================================================================\r\n// AsyncAPI Editor\r\n// =============================================================================\r\n\r\n/** AsyncAPI specification document */\r\nexport interface AsyncAPISpec {\r\n asyncapi: string;\r\n info: AsyncAPIInfo;\r\n servers?: Record<string, AsyncAPIServer>;\r\n channels: Record<string, AsyncAPIChannel>;\r\n components?: AsyncAPIComponents;\r\n tags?: AsyncAPITag[];\r\n externalDocs?: AsyncAPIExternalDocs;\r\n defaultContentType?: string;\r\n}\r\n\r\n/** AsyncAPI info */\r\nexport interface AsyncAPIInfo {\r\n title: string;\r\n version: string;\r\n description?: string;\r\n termsOfService?: string;\r\n contact?: AsyncAPIContact;\r\n license?: AsyncAPILicense;\r\n}\r\n\r\n/** AsyncAPI contact */\r\nexport interface AsyncAPIContact {\r\n name?: string;\r\n url?: string;\r\n email?: string;\r\n}\r\n\r\n/** AsyncAPI license */\r\nexport interface AsyncAPILicense {\r\n name: string;\r\n url?: string;\r\n}\r\n\r\n/** AsyncAPI server */\r\nexport interface AsyncAPIServer {\r\n url: string;\r\n protocol: AsyncAPIProtocol;\r\n protocolVersion?: string;\r\n description?: string;\r\n variables?: Record<string, AsyncAPIServerVariable>;\r\n security?: Record<string, string[]>[];\r\n bindings?: AsyncAPIServerBindings;\r\n}\r\n\r\n/** AsyncAPI protocol */\r\nexport type AsyncAPIProtocol =\r\n | 'amqp'\r\n | 'amqps'\r\n | 'http'\r\n | 'https'\r\n | 'kafka'\r\n | 'kafka-secure'\r\n | 'mqtt'\r\n | 'mqtts'\r\n | 'ws'\r\n | 'wss'\r\n | 'stomp'\r\n | 'stomps'\r\n | 'jms'\r\n | 'nats'\r\n | 'redis'\r\n | 'sns'\r\n | 'sqs'\r\n | 'pulsar'\r\n | 'solace';\r\n\r\n/** Server variable */\r\nexport interface AsyncAPIServerVariable {\r\n default?: string;\r\n description?: string;\r\n enum?: string[];\r\n examples?: string[];\r\n}\r\n\r\n/** Server bindings */\r\nexport interface AsyncAPIServerBindings {\r\n mqtt?: MqttServerBinding;\r\n kafka?: KafkaServerBinding;\r\n amqp?: AmqpServerBinding;\r\n [key: string]: unknown;\r\n}\r\n\r\n/** MQTT server binding */\r\nexport interface MqttServerBinding {\r\n clientId?: string;\r\n cleanSession?: boolean;\r\n lastWill?: MqttLastWill;\r\n keepAlive?: number;\r\n}\r\n\r\n/** MQTT last will */\r\nexport interface MqttLastWill {\r\n topic: string;\r\n qos?: 0 | 1 | 2;\r\n message?: string;\r\n retain?: boolean;\r\n}\r\n\r\n/** Kafka server binding */\r\nexport interface KafkaServerBinding {\r\n schemaRegistryUrl?: string;\r\n schemaRegistryVendor?: string;\r\n}\r\n\r\n/** AMQP server binding */\r\nexport interface AmqpServerBinding {}\r\n\r\n/** AsyncAPI channel */\r\nexport interface AsyncAPIChannel {\r\n description?: string;\r\n subscribe?: AsyncAPIOperation;\r\n publish?: AsyncAPIOperation;\r\n parameters?: Record<string, AsyncAPIParameter>;\r\n bindings?: AsyncAPIChannelBindings;\r\n}\r\n\r\n/** Channel bindings */\r\nexport interface AsyncAPIChannelBindings {\r\n kafka?: KafkaChannelBinding;\r\n amqp?: AmqpChannelBinding;\r\n [key: string]: unknown;\r\n}\r\n\r\n/** Kafka channel binding */\r\nexport interface KafkaChannelBinding {\r\n topic?: string;\r\n partitions?: number;\r\n replicas?: number;\r\n topicConfiguration?: Record<string, unknown>;\r\n}\r\n\r\n/** AMQP channel binding */\r\nexport interface AmqpChannelBinding {\r\n is?: 'queue' | 'routingKey';\r\n exchange?: AmqpExchange;\r\n queue?: AmqpQueue;\r\n}\r\n\r\n/** AMQP exchange */\r\nexport interface AmqpExchange {\r\n name?: string;\r\n type?: 'topic' | 'direct' | 'fanout' | 'default' | 'headers';\r\n durable?: boolean;\r\n autoDelete?: boolean;\r\n vhost?: string;\r\n}\r\n\r\n/** AMQP queue */\r\nexport interface AmqpQueue {\r\n name?: string;\r\n durable?: boolean;\r\n exclusive?: boolean;\r\n autoDelete?: boolean;\r\n vhost?: string;\r\n}\r\n\r\n/** AsyncAPI operation */\r\nexport interface AsyncAPIOperation {\r\n operationId?: string;\r\n summary?: string;\r\n description?: string;\r\n tags?: AsyncAPITag[];\r\n externalDocs?: AsyncAPIExternalDocs;\r\n bindings?: AsyncAPIOperationBindings;\r\n traits?: AsyncAPIOperationTrait[];\r\n message?: AsyncAPIMessage | AsyncAPIMessageOneOf;\r\n security?: Record<string, string[]>[];\r\n}\r\n\r\n/** Operation bindings */\r\nexport interface AsyncAPIOperationBindings {\r\n kafka?: KafkaOperationBinding;\r\n amqp?: AmqpOperationBinding;\r\n [key: string]: unknown;\r\n}\r\n\r\n/** Kafka operation binding */\r\nexport interface KafkaOperationBinding {\r\n groupId?: AsyncAPISchema;\r\n clientId?: AsyncAPISchema;\r\n}\r\n\r\n/** AMQP operation binding */\r\nexport interface AmqpOperationBinding {\r\n expiration?: number;\r\n userId?: string;\r\n cc?: string[];\r\n priority?: number;\r\n deliveryMode?: 1 | 2;\r\n mandatory?: boolean;\r\n bcc?: string[];\r\n replyTo?: string;\r\n timestamp?: boolean;\r\n ack?: boolean;\r\n}\r\n\r\n/** Operation trait */\r\nexport interface AsyncAPIOperationTrait {\r\n operationId?: string;\r\n summary?: string;\r\n description?: string;\r\n tags?: AsyncAPITag[];\r\n externalDocs?: AsyncAPIExternalDocs;\r\n bindings?: AsyncAPIOperationBindings;\r\n}\r\n\r\n/** AsyncAPI message */\r\nexport interface AsyncAPIMessage {\r\n messageId?: string;\r\n headers?: AsyncAPISchema;\r\n payload?: AsyncAPISchema;\r\n correlationId?: AsyncAPICorrelationId;\r\n schemaFormat?: string;\r\n contentType?: string;\r\n name?: string;\r\n title?: string;\r\n summary?: string;\r\n description?: string;\r\n tags?: AsyncAPITag[];\r\n externalDocs?: AsyncAPIExternalDocs;\r\n bindings?: AsyncAPIMessageBindings;\r\n examples?: AsyncAPIMessageExample[];\r\n traits?: AsyncAPIMessageTrait[];\r\n}\r\n\r\n/** Message oneOf */\r\nexport interface AsyncAPIMessageOneOf {\r\n oneOf: AsyncAPIMessage[];\r\n}\r\n\r\n/** Message bindings */\r\nexport interface AsyncAPIMessageBindings {\r\n kafka?: KafkaMessageBinding;\r\n amqp?: AmqpMessageBinding;\r\n [key: string]: unknown;\r\n}\r\n\r\n/** Kafka message binding */\r\nexport interface KafkaMessageBinding {\r\n key?: AsyncAPISchema;\r\n}\r\n\r\n/** AMQP message binding */\r\nexport interface AmqpMessageBinding {\r\n contentEncoding?: string;\r\n messageType?: string;\r\n}\r\n\r\n/** Message example */\r\nexport interface AsyncAPIMessageExample {\r\n name?: string;\r\n summary?: string;\r\n headers?: Record<string, unknown>;\r\n payload?: unknown;\r\n}\r\n\r\n/** Message trait */\r\nexport interface AsyncAPIMessageTrait {\r\n messageId?: string;\r\n headers?: AsyncAPISchema;\r\n correlationId?: AsyncAPICorrelationId;\r\n schemaFormat?: string;\r\n contentType?: string;\r\n name?: string;\r\n title?: string;\r\n summary?: string;\r\n description?: string;\r\n tags?: AsyncAPITag[];\r\n externalDocs?: AsyncAPIExternalDocs;\r\n bindings?: AsyncAPIMessageBindings;\r\n examples?: AsyncAPIMessageExample[];\r\n}\r\n\r\n/** Correlation ID */\r\nexport interface AsyncAPICorrelationId {\r\n description?: string;\r\n location: string;\r\n}\r\n\r\n/** AsyncAPI parameter */\r\nexport interface AsyncAPIParameter {\r\n description?: string;\r\n schema?: AsyncAPISchema;\r\n location?: string;\r\n}\r\n\r\n/** AsyncAPI schema (JSON Schema) */\r\nexport interface AsyncAPISchema extends OpenAPISchema {\r\n // AsyncAPI uses JSON Schema with some additions\r\n}\r\n\r\n/** AsyncAPI tag */\r\nexport interface AsyncAPITag {\r\n name: string;\r\n description?: string;\r\n externalDocs?: AsyncAPIExternalDocs;\r\n}\r\n\r\n/** AsyncAPI external docs */\r\nexport interface AsyncAPIExternalDocs {\r\n url: string;\r\n description?: string;\r\n}\r\n\r\n/** AsyncAPI components */\r\nexport interface AsyncAPIComponents {\r\n schemas?: Record<string, AsyncAPISchema>;\r\n messages?: Record<string, AsyncAPIMessage>;\r\n securitySchemes?: Record<string, AsyncAPISecurityScheme>;\r\n parameters?: Record<string, AsyncAPIParameter>;\r\n correlationIds?: Record<string, AsyncAPICorrelationId>;\r\n operationTraits?: Record<string, AsyncAPIOperationTrait>;\r\n messageTraits?: Record<string, AsyncAPIMessageTrait>;\r\n serverBindings?: Record<string, AsyncAPIServerBindings>;\r\n channelBindings?: Record<string, AsyncAPIChannelBindings>;\r\n operationBindings?: Record<string, AsyncAPIOperationBindings>;\r\n messageBindings?: Record<string, AsyncAPIMessageBindings>;\r\n}\r\n\r\n/** AsyncAPI security scheme */\r\nexport interface AsyncAPISecurityScheme {\r\n type:\r\n | 'userPassword'\r\n | 'apiKey'\r\n | 'X509'\r\n | 'symmetricEncryption'\r\n | 'asymmetricEncryption'\r\n | 'httpApiKey'\r\n | 'http'\r\n | 'oauth2'\r\n | 'openIdConnect'\r\n | 'plain'\r\n | 'scramSha256'\r\n | 'scramSha512'\r\n | 'gssapi';\r\n description?: string;\r\n name?: string;\r\n in?: 'user' | 'password' | 'query' | 'header' | 'cookie';\r\n scheme?: string;\r\n bearerFormat?: string;\r\n flows?: AsyncAPIOAuthFlows;\r\n openIdConnectUrl?: string;\r\n}\r\n\r\n/** OAuth flows for AsyncAPI */\r\nexport interface AsyncAPIOAuthFlows {\r\n implicit?: AsyncAPIOAuthFlow;\r\n password?: AsyncAPIOAuthFlow;\r\n clientCredentials?: AsyncAPIOAuthFlow;\r\n authorizationCode?: AsyncAPIOAuthFlow;\r\n}\r\n\r\n/** OAuth flow */\r\nexport interface AsyncAPIOAuthFlow {\r\n authorizationUrl?: string;\r\n tokenUrl?: string;\r\n refreshUrl?: string;\r\n scopes: Record<string, string>;\r\n}\r\n\r\n/** AsyncAPI editor configuration */\r\nexport interface AsyncAPIEditorConfig {\r\n source: AsyncAPISource;\r\n validation?: boolean;\r\n theme?: 'light' | 'dark';\r\n showPreview?: boolean;\r\n formatToggle?: boolean;\r\n readOnly?: boolean;\r\n}\r\n\r\n/** AsyncAPI source */\r\nexport interface AsyncAPISource {\r\n type: 'url' | 'file' | 'inline';\r\n url?: string;\r\n content?: string;\r\n format?: 'yaml' | 'json';\r\n}\r\n\r\n// =============================================================================\r\n// Protocol Buffers Editor\r\n// =============================================================================\r\n\r\n/** Protobuf file definition */\r\nexport interface ProtobufDefinition {\r\n syntax: 'proto2' | 'proto3';\r\n package?: string;\r\n imports: ProtobufImport[];\r\n options: ProtobufOption[];\r\n messages: ProtobufMessage[];\r\n enums: ProtobufEnum[];\r\n services: ProtobufService[];\r\n}\r\n\r\n/** Protobuf import */\r\nexport interface ProtobufImport {\r\n path: string;\r\n public?: boolean;\r\n weak?: boolean;\r\n}\r\n\r\n/** Protobuf option */\r\nexport interface ProtobufOption {\r\n name: string;\r\n value: unknown;\r\n}\r\n\r\n/** Protobuf message */\r\nexport interface ProtobufMessage {\r\n name: string;\r\n fields: ProtobufField[];\r\n nestedMessages: ProtobufMessage[];\r\n nestedEnums: ProtobufEnum[];\r\n oneofs: ProtobufOneof[];\r\n options: ProtobufOption[];\r\n reserved: ProtobufReserved[];\r\n extensions: ProtobufExtension[];\r\n comments?: string;\r\n}\r\n\r\n/** Protobuf field */\r\nexport interface ProtobufField {\r\n name: string;\r\n number: number;\r\n type: string;\r\n label?: 'optional' | 'required' | 'repeated';\r\n options?: ProtobufOption[];\r\n map?: ProtobufMapType;\r\n comments?: string;\r\n}\r\n\r\n/** Protobuf map type */\r\nexport interface ProtobufMapType {\r\n keyType: string;\r\n valueType: string;\r\n}\r\n\r\n/** Protobuf oneof */\r\nexport interface ProtobufOneof {\r\n name: string;\r\n fields: ProtobufField[];\r\n options?: ProtobufOption[];\r\n}\r\n\r\n/** Protobuf reserved */\r\nexport interface ProtobufReserved {\r\n ranges?: Array<number | { start: number; end: number }>;\r\n names?: string[];\r\n}\r\n\r\n/** Protobuf extension */\r\nexport interface ProtobufExtension {\r\n extendee: string;\r\n fields: ProtobufField[];\r\n}\r\n\r\n/** Protobuf enum */\r\nexport interface ProtobufEnum {\r\n name: string;\r\n values: ProtobufEnumValue[];\r\n options?: ProtobufOption[];\r\n reserved?: ProtobufReserved[];\r\n comments?: string;\r\n}\r\n\r\n/** Protobuf enum value */\r\nexport interface ProtobufEnumValue {\r\n name: string;\r\n number: number;\r\n options?: ProtobufOption[];\r\n comments?: string;\r\n}\r\n\r\n/** Protobuf service */\r\nexport interface ProtobufService {\r\n name: string;\r\n methods: ProtobufMethod[];\r\n options?: ProtobufOption[];\r\n comments?: string;\r\n}\r\n\r\n/** Protobuf method */\r\nexport interface ProtobufMethod {\r\n name: string;\r\n inputType: string;\r\n outputType: string;\r\n clientStreaming?: boolean;\r\n serverStreaming?: boolean;\r\n options?: ProtobufOption[];\r\n comments?: string;\r\n}\r\n\r\n/** Protobuf editor configuration */\r\nexport interface ProtobufEditorConfig {\r\n source: ProtobufSource;\r\n syntax?: 'proto2' | 'proto3';\r\n validation?: boolean;\r\n theme?: 'light' | 'dark';\r\n showLineNumbers?: boolean;\r\n includePaths?: string[];\r\n}\r\n\r\n/** Protobuf source */\r\nexport interface ProtobufSource {\r\n type: 'file' | 'inline';\r\n path?: string;\r\n content?: string;\r\n}\r\n\r\n// =============================================================================\r\n// Apache Thrift Editor\r\n// =============================================================================\r\n\r\n/** Thrift document */\r\nexport interface ThriftDocument {\r\n headers: ThriftHeader[];\r\n definitions: ThriftDefinition[];\r\n}\r\n\r\n/** Thrift header */\r\nexport interface ThriftHeader {\r\n type: 'include' | 'cppInclude' | 'namespace';\r\n value: string;\r\n scope?: string;\r\n}\r\n\r\n/** Thrift definition */\r\nexport type ThriftDefinition =\r\n | ThriftConst\r\n | ThriftTypedef\r\n | ThriftEnum\r\n | ThriftStruct\r\n | ThriftUnion\r\n | ThriftException\r\n | ThriftService;\r\n\r\n/** Thrift constant */\r\nexport interface ThriftConst {\r\n kind: 'const';\r\n name: string;\r\n type: ThriftType;\r\n value: unknown;\r\n}\r\n\r\n/** Thrift typedef */\r\nexport interface ThriftTypedef {\r\n kind: 'typedef';\r\n name: string;\r\n type: ThriftType;\r\n}\r\n\r\n/** Thrift enum */\r\nexport interface ThriftEnum {\r\n kind: 'enum';\r\n name: string;\r\n members: ThriftEnumMember[];\r\n}\r\n\r\n/** Thrift enum member */\r\nexport interface ThriftEnumMember {\r\n name: string;\r\n value?: number;\r\n}\r\n\r\n/** Thrift struct */\r\nexport interface ThriftStruct {\r\n kind: 'struct';\r\n name: string;\r\n fields: ThriftField[];\r\n annotations?: Record<string, string>;\r\n}\r\n\r\n/** Thrift union */\r\nexport interface ThriftUnion {\r\n kind: 'union';\r\n name: string;\r\n fields: ThriftField[];\r\n}\r\n\r\n/** Thrift exception */\r\nexport interface ThriftException {\r\n kind: 'exception';\r\n name: string;\r\n fields: ThriftField[];\r\n}\r\n\r\n/** Thrift field */\r\nexport interface ThriftField {\r\n id?: number;\r\n name: string;\r\n type: ThriftType;\r\n requiredness?: 'required' | 'optional';\r\n defaultValue?: unknown;\r\n annotations?: Record<string, string>;\r\n}\r\n\r\n/** Thrift type */\r\nexport interface ThriftType {\r\n kind: 'base' | 'identifier' | 'map' | 'set' | 'list';\r\n name?: string; // for base and identifier\r\n keyType?: ThriftType; // for map\r\n valueType?: ThriftType; // for map, set, list\r\n}\r\n\r\n/** Thrift service */\r\nexport interface ThriftService {\r\n kind: 'service';\r\n name: string;\r\n extends?: string;\r\n functions: ThriftFunction[];\r\n annotations?: Record<string, string>;\r\n}\r\n\r\n/** Thrift function */\r\nexport interface ThriftFunction {\r\n name: string;\r\n returnType: ThriftType | 'void';\r\n oneway?: boolean;\r\n parameters: ThriftField[];\r\n throws?: ThriftField[];\r\n annotations?: Record<string, string>;\r\n}\r\n\r\n/** Thrift editor configuration */\r\nexport interface ThriftEditorConfig {\r\n source: ThriftSource;\r\n validation?: boolean;\r\n theme?: 'light' | 'dark';\r\n includePaths?: string[];\r\n}\r\n\r\n/** Thrift source */\r\nexport interface ThriftSource {\r\n type: 'file' | 'inline';\r\n path?: string;\r\n content?: string;\r\n}\r\n\r\n// =============================================================================\r\n// Apache Avro Editor\r\n// =============================================================================\r\n\r\n/** Avro schema */\r\nexport type AvroSchema =\r\n | AvroPrimitive\r\n | AvroRecord\r\n | AvroEnum\r\n | AvroArray\r\n | AvroMap\r\n | AvroUnion\r\n | AvroFixed\r\n | AvroNamedType\r\n | AvroLogicalType;\r\n\r\n/** Avro primitive types */\r\nexport type AvroPrimitive =\r\n | 'null'\r\n | 'boolean'\r\n | 'int'\r\n | 'long'\r\n | 'float'\r\n | 'double'\r\n | 'bytes'\r\n | 'string';\r\n\r\n/** Avro record schema */\r\nexport interface AvroRecord {\r\n type: 'record';\r\n name: string;\r\n namespace?: string;\r\n doc?: string;\r\n aliases?: string[];\r\n fields: AvroField[];\r\n}\r\n\r\n/** Avro field */\r\nexport interface AvroField {\r\n name: string;\r\n type: AvroSchema;\r\n doc?: string;\r\n default?: unknown;\r\n order?: 'ascending' | 'descending' | 'ignore';\r\n aliases?: string[];\r\n}\r\n\r\n/** Avro enum schema */\r\nexport interface AvroEnum {\r\n type: 'enum';\r\n name: string;\r\n namespace?: string;\r\n doc?: string;\r\n aliases?: string[];\r\n symbols: string[];\r\n default?: string;\r\n}\r\n\r\n/** Avro array schema */\r\nexport interface AvroArray {\r\n type: 'array';\r\n items: AvroSchema;\r\n}\r\n\r\n/** Avro map schema */\r\nexport interface AvroMap {\r\n type: 'map';\r\n values: AvroSchema;\r\n}\r\n\r\n/** Avro union (array of types) */\r\nexport type AvroUnion = AvroSchema[];\r\n\r\n/** Avro fixed schema */\r\nexport interface AvroFixed {\r\n type: 'fixed';\r\n name: string;\r\n namespace?: string;\r\n aliases?: string[];\r\n size: number;\r\n}\r\n\r\n/** Named type reference */\r\nexport type AvroNamedType = string;\r\n\r\n/** Avro logical type */\r\nexport interface AvroLogicalType {\r\n type: AvroPrimitive | AvroFixed | 'bytes' | 'string';\r\n logicalType:\r\n | 'decimal'\r\n | 'uuid'\r\n | 'date'\r\n | 'time-millis'\r\n | 'time-micros'\r\n | 'timestamp-millis'\r\n | 'timestamp-micros'\r\n | 'duration'\r\n | 'local-timestamp-millis'\r\n | 'local-timestamp-micros';\r\n precision?: number;\r\n scale?: number;\r\n}\r\n\r\n/** Avro protocol */\r\nexport interface AvroProtocol {\r\n protocol: string;\r\n namespace?: string;\r\n doc?: string;\r\n types?: AvroSchema[];\r\n messages?: Record<string, AvroMessage>;\r\n}\r\n\r\n/** Avro message (RPC) */\r\nexport interface AvroMessage {\r\n doc?: string;\r\n request: AvroField[];\r\n response: AvroSchema;\r\n errors?: AvroSchema[];\r\n one_way?: boolean;\r\n}\r\n\r\n/** Avro editor configuration */\r\nexport interface AvroEditorConfig {\r\n source: AvroSource;\r\n validation?: boolean;\r\n theme?: 'light' | 'dark';\r\n schemaRegistry?: AvroSchemaRegistryConfig;\r\n}\r\n\r\n/** Avro source */\r\nexport interface AvroSource {\r\n type: 'file' | 'inline' | 'registry';\r\n path?: string;\r\n content?: string;\r\n subject?: string;\r\n version?: number | 'latest';\r\n}\r\n\r\n/** Schema registry configuration */\r\nexport interface AvroSchemaRegistryConfig {\r\n url: string;\r\n auth?: {\r\n type: 'basic' | 'bearer';\r\n username?: string;\r\n password?: string;\r\n token?: string;\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// Schema Visualization\r\n// =============================================================================\r\n\r\n/** Schema diagram configuration */\r\nexport interface SchemaDiagramConfig {\r\n /** Schema source */\r\n schema: SchemaSource;\r\n /** Diagram layout */\r\n layout?: DiagramLayout;\r\n /** Show relationships */\r\n showRelationships?: boolean;\r\n /** Show field types */\r\n showTypes?: boolean;\r\n /** Show descriptions */\r\n showDescriptions?: boolean;\r\n /** Collapsible nodes */\r\n collapsible?: boolean;\r\n /** Zoom controls */\r\n zoomControls?: boolean;\r\n /** Pan enabled */\r\n panEnabled?: boolean;\r\n /** Export formats */\r\n exportFormats?: DiagramExportFormat[];\r\n /** Theme */\r\n theme?: 'light' | 'dark';\r\n /** Custom colors */\r\n colors?: DiagramColors;\r\n}\r\n\r\n/** Schema source for visualization */\r\nexport interface SchemaSource {\r\n type: 'openapi' | 'graphql' | 'asyncapi' | 'protobuf' | 'avro' | 'jsonschema';\r\n content: string | object;\r\n format?: 'yaml' | 'json' | 'sdl' | 'proto';\r\n}\r\n\r\n/** Diagram layout options */\r\nexport interface DiagramLayout {\r\n algorithm: 'dagre' | 'elk' | 'force' | 'hierarchy' | 'radial';\r\n direction?: 'TB' | 'BT' | 'LR' | 'RL';\r\n nodeSpacing?: number;\r\n rankSpacing?: number;\r\n grouping?: 'none' | 'namespace' | 'tag';\r\n}\r\n\r\n/** Diagram export format */\r\nexport type DiagramExportFormat = 'png' | 'svg' | 'pdf' | 'json';\r\n\r\n/** Diagram colors */\r\nexport interface DiagramColors {\r\n background?: string;\r\n node?: string;\r\n nodeBorder?: string;\r\n nodeText?: string;\r\n edge?: string;\r\n edgeLabel?: string;\r\n highlight?: string;\r\n}\r\n\r\n/** Diagram node */\r\nexport interface DiagramNode {\r\n id: string;\r\n type: 'type' | 'endpoint' | 'channel' | 'message' | 'service' | 'method';\r\n label: string;\r\n description?: string;\r\n properties?: DiagramNodeProperty[];\r\n group?: string;\r\n x?: number;\r\n y?: number;\r\n collapsed?: boolean;\r\n}\r\n\r\n/** Diagram node property */\r\nexport interface DiagramNodeProperty {\r\n name: string;\r\n type: string;\r\n required?: boolean;\r\n deprecated?: boolean;\r\n description?: string;\r\n}\r\n\r\n/** Diagram edge */\r\nexport interface DiagramEdge {\r\n id: string;\r\n source: string;\r\n target: string;\r\n label?: string;\r\n type: 'reference' | 'inheritance' | 'composition' | 'association' | 'dependency';\r\n cardinality?: string;\r\n}\r\n\r\n// =============================================================================\r\n// Mock Server\r\n// =============================================================================\r\n\r\n/** Mock server configuration */\r\nexport interface MockServerConfig {\r\n /** Schema source */\r\n schema: SchemaSource;\r\n /** Server port */\r\n port?: number;\r\n /** Host */\r\n host?: string;\r\n /** Base path */\r\n basePath?: string;\r\n /** Response delay (ms) */\r\n delay?: number | { min: number; max: number };\r\n /** Mock data configuration */\r\n mockData?: MockDataConfig;\r\n /** CORS configuration */\r\n cors?: MockCorsConfig;\r\n /** Request logging */\r\n logging?: boolean;\r\n /** Record requests */\r\n recording?: boolean;\r\n /** Dynamic mocks */\r\n dynamicMocks?: MockOverride[];\r\n /** Proxy fallback */\r\n proxy?: MockProxyConfig;\r\n}\r\n\r\n/** Mock data configuration */\r\nexport interface MockDataConfig {\r\n /** Use schema examples */\r\n useExamples?: boolean;\r\n /** Generate random data */\r\n generateRandom?: boolean;\r\n /** Faker.js locale */\r\n locale?: string;\r\n /** Custom generators */\r\n generators?: Record<string, MockGenerator>;\r\n /** Field overrides */\r\n fieldOverrides?: Record<string, unknown>;\r\n}\r\n\r\n/** Mock data generator */\r\nexport interface MockGenerator {\r\n type: 'faker' | 'custom' | 'static';\r\n fakerMethod?: string;\r\n customFn?: string;\r\n staticValue?: unknown;\r\n}\r\n\r\n/** Mock CORS config */\r\nexport interface MockCorsConfig {\r\n enabled?: boolean;\r\n origin?: string | string[];\r\n methods?: string[];\r\n headers?: string[];\r\n credentials?: boolean;\r\n}\r\n\r\n/** Mock override */\r\nexport interface MockOverride {\r\n path: string;\r\n method?: HttpMethod;\r\n response?: MockResponse;\r\n condition?: MockCondition;\r\n priority?: number;\r\n}\r\n\r\n/** Mock response */\r\nexport interface MockResponse {\r\n statusCode?: number;\r\n headers?: Record<string, string>;\r\n body?: unknown;\r\n delay?: number;\r\n file?: string;\r\n}\r\n\r\n/** Mock condition */\r\nexport interface MockCondition {\r\n query?: Record<string, string | RegExp>;\r\n headers?: Record<string, string | RegExp>;\r\n body?: Record<string, unknown>;\r\n jsonPath?: string;\r\n jsonPathValue?: unknown;\r\n}\r\n\r\n/** Mock proxy config */\r\nexport interface MockProxyConfig {\r\n target: string;\r\n paths?: string[];\r\n changeOrigin?: boolean;\r\n rewrite?: Record<string, string>;\r\n}\r\n\r\n/** Mock server status */\r\nexport interface MockServerStatus {\r\n running: boolean;\r\n port?: number;\r\n host?: string;\r\n startTime?: Date;\r\n requestCount: number;\r\n endpoints: MockEndpointStatus[];\r\n}\r\n\r\n/** Mock endpoint status */\r\nexport interface MockEndpointStatus {\r\n path: string;\r\n method: HttpMethod;\r\n hitCount: number;\r\n lastRequest?: Date;\r\n averageLatency?: number;\r\n}\r\n\r\n// =============================================================================\r\n// Code Generation\r\n// =============================================================================\r\n\r\n/** Code generation configuration */\r\nexport interface CodeGenConfig {\r\n /** Schema source */\r\n schema: SchemaSource;\r\n /** Output language */\r\n language: CodeGenLanguage;\r\n /** Output type (client/server) */\r\n outputType: 'client' | 'server' | 'both' | 'types';\r\n /** Framework */\r\n framework?: string;\r\n /** Output directory */\r\n outputDir?: string;\r\n /** Package/namespace name */\r\n packageName?: string;\r\n /** Generation options */\r\n options?: CodeGenOptions;\r\n /** Template overrides */\r\n templates?: CodeGenTemplate[];\r\n}\r\n\r\n/** Supported languages / framework targets for code generation */\r\nexport type CodeGenLanguage =\r\n | 'typescript'\r\n | 'javascript'\r\n | 'python'\r\n | 'java'\r\n | 'kotlin'\r\n | 'csharp'\r\n | 'go'\r\n | 'rust'\r\n | 'ruby'\r\n | 'php'\r\n | 'swift'\r\n | 'dart'\r\n // Framework targets (TS/JS based)\r\n | 'nextjs'\r\n | 'nuxt'\r\n | 'sveltekit'\r\n | 'remix'\r\n // Cross-platform / mobile / .NET\r\n | 'react-native'\r\n | 'flutter'\r\n | 'blazor';\r\n\r\n/** Code generation options */\r\nexport interface CodeGenOptions {\r\n /** Include documentation */\r\n includeDocs?: boolean;\r\n /** Include examples */\r\n includeExamples?: boolean;\r\n /** Generate validators */\r\n generateValidators?: boolean;\r\n /** Generate mocks */\r\n generateMocks?: boolean;\r\n /** Enum style */\r\n enumStyle?: 'string' | 'numeric' | 'const';\r\n /** Date/time library */\r\n dateTimeLibrary?: string;\r\n /** HTTP client library */\r\n httpClient?: string;\r\n /** Use optional chaining */\r\n useOptionalChaining?: boolean;\r\n /** Strict null checks */\r\n strictNullChecks?: boolean;\r\n /** Generate index file */\r\n generateIndex?: boolean;\r\n /** File naming convention */\r\n fileNaming?: 'camelCase' | 'PascalCase' | 'snake_case' | 'kebab-case';\r\n}\r\n\r\n/** Custom template */\r\nexport interface CodeGenTemplate {\r\n name: string;\r\n template: string;\r\n outputPath: string;\r\n condition?: string;\r\n}\r\n\r\n/** Code generation result */\r\nexport interface CodeGenResult {\r\n success: boolean;\r\n files: GeneratedFile[];\r\n errors?: CodeGenError[];\r\n warnings?: CodeGenWarning[];\r\n}\r\n\r\n/** Generated file */\r\nexport interface GeneratedFile {\r\n path: string;\r\n content: string;\r\n size: number;\r\n hash?: string;\r\n}\r\n\r\n/** Code generation error */\r\nexport interface CodeGenError {\r\n message: string;\r\n location?: string;\r\n code?: string;\r\n}\r\n\r\n/** Code generation warning */\r\nexport interface CodeGenWarning {\r\n message: string;\r\n location?: string;\r\n code?: string;\r\n}\r\n\r\n// =============================================================================\r\n// API Documentation\r\n// =============================================================================\r\n\r\n/** Documentation configuration */\r\nexport interface APIDocConfig {\r\n /** Schema source */\r\n schema: SchemaSource;\r\n /** Documentation style */\r\n style: 'swagger-ui' | 'redoc' | 'stoplight' | 'slate' | 'custom';\r\n /** Theme */\r\n theme?: DocTheme;\r\n /** Logo */\r\n logo?: DocLogo;\r\n /** Navigation */\r\n navigation?: DocNavigation;\r\n /** Custom sections */\r\n sections?: DocSection[];\r\n /** Code samples */\r\n codeSamples?: DocCodeSampleConfig;\r\n /** Try-it-out */\r\n tryItOut?: boolean;\r\n /** Authentication */\r\n auth?: DocAuthConfig;\r\n /** Output format */\r\n output?: 'html' | 'markdown' | 'pdf';\r\n}\r\n\r\n/** Documentation theme */\r\nexport interface DocTheme {\r\n primaryColor?: string;\r\n accentColor?: string;\r\n textColor?: string;\r\n backgroundColor?: string;\r\n codeBackground?: string;\r\n fontFamily?: string;\r\n codeFontFamily?: string;\r\n}\r\n\r\n/** Documentation logo */\r\nexport interface DocLogo {\r\n url: string;\r\n altText?: string;\r\n link?: string;\r\n height?: number;\r\n}\r\n\r\n/** Documentation navigation */\r\nexport interface DocNavigation {\r\n position?: 'left' | 'right' | 'top';\r\n collapsed?: boolean;\r\n searchEnabled?: boolean;\r\n tagGroups?: DocTagGroup[];\r\n}\r\n\r\n/** Tag group */\r\nexport interface DocTagGroup {\r\n name: string;\r\n tags: string[];\r\n}\r\n\r\n/** Custom documentation section */\r\nexport interface DocSection {\r\n title: string;\r\n content: string;\r\n position?: 'before' | 'after';\r\n target?: string;\r\n}\r\n\r\n/** Code sample configuration */\r\nexport interface DocCodeSampleConfig {\r\n enabled?: boolean;\r\n languages?: DocCodeLanguage[];\r\n defaultLanguage?: string;\r\n}\r\n\r\n/** Code sample language */\r\nexport interface DocCodeLanguage {\r\n name: string;\r\n label: string;\r\n prism?: string;\r\n generator?: 'automatic' | 'manual';\r\n}\r\n\r\n/** Documentation auth config */\r\nexport interface DocAuthConfig {\r\n enabled?: boolean;\r\n persistAuth?: boolean;\r\n defaultScheme?: string;\r\n credentials?: Record<string, string>;\r\n}\r\n\r\n// =============================================================================\r\n// Breaking Change Detection\r\n// =============================================================================\r\n\r\n/** Version diff configuration */\r\nexport interface VersionDiffConfig {\r\n /** Old version */\r\n oldVersion: SchemaVersion;\r\n /** New version */\r\n newVersion: SchemaVersion;\r\n /** Rules */\r\n rules?: BreakingChangeRules;\r\n /** Output format */\r\n outputFormat?: 'json' | 'markdown' | 'html';\r\n}\r\n\r\n/** Schema version */\r\nexport interface SchemaVersion {\r\n source: SchemaSource;\r\n version?: string;\r\n label?: string;\r\n}\r\n\r\n/** Breaking change rules */\r\nexport interface BreakingChangeRules {\r\n /** Treat removals as breaking */\r\n removalsBreaking?: boolean;\r\n /** Treat type changes as breaking */\r\n typeChangesBreaking?: boolean;\r\n /** Treat required changes as breaking */\r\n requiredChangesBreaking?: boolean;\r\n /** Allow deprecation grace period */\r\n deprecationGracePeriod?: boolean;\r\n /** Custom rules */\r\n customRules?: BreakingChangeRule[];\r\n}\r\n\r\n/** Custom breaking change rule */\r\nexport interface BreakingChangeRule {\r\n name: string;\r\n description?: string;\r\n severity: 'error' | 'warning' | 'info';\r\n check: string; // JSONPath or custom expression\r\n}\r\n\r\n/** Version diff result */\r\nexport interface VersionDiffResult {\r\n compatible: boolean;\r\n breakingChanges: SchemaChange[];\r\n nonBreakingChanges: SchemaChange[];\r\n deprecations: SchemaChange[];\r\n additions: SchemaChange[];\r\n summary: DiffSummary;\r\n}\r\n\r\n/** Schema change */\r\nexport interface SchemaChange {\r\n type: 'addition' | 'removal' | 'modification' | 'deprecation';\r\n severity: 'breaking' | 'non-breaking' | 'info';\r\n path: string;\r\n message: string;\r\n oldValue?: unknown;\r\n newValue?: unknown;\r\n rule?: string;\r\n}\r\n\r\n/** Diff summary */\r\nexport interface DiffSummary {\r\n totalChanges: number;\r\n breakingCount: number;\r\n nonBreakingCount: number;\r\n additionCount: number;\r\n removalCount: number;\r\n modificationCount: number;\r\n}\r\n\r\n// =============================================================================\r\n// API Linting\r\n// =============================================================================\r\n\r\n/** Linting configuration */\r\nexport interface APILintConfig {\r\n /** Schema source */\r\n schema: SchemaSource;\r\n /** Ruleset */\r\n ruleset?: 'spectral:oas' | 'spectral:asyncapi' | 'custom';\r\n /** Custom rules path */\r\n customRulesPath?: string;\r\n /** Rule overrides */\r\n rules?: Record<string, APILintRuleSeverity>;\r\n /** Output format */\r\n outputFormat?: 'json' | 'pretty' | 'stylish';\r\n}\r\n\r\n/** Rule severity */\r\nexport type APILintRuleSeverity = 'off' | 'warn' | 'error';\r\n\r\n/** Linting result */\r\nexport interface APILintResult {\r\n valid: boolean;\r\n errors: APILintIssue[];\r\n warnings: APILintIssue[];\r\n info: APILintIssue[];\r\n}\r\n\r\n/** Linting issue */\r\nexport interface APILintIssue {\r\n code: string;\r\n message: string;\r\n severity: 'error' | 'warning' | 'info';\r\n path: string[];\r\n range?: {\r\n start: { line: number; character: number };\r\n end: { line: number; character: number };\r\n };\r\n source?: string;\r\n}\r\n\r\n/** Built-in linting rules */\r\nexport interface APILintRuleDefinition {\r\n name: string;\r\n description: string;\r\n severity: APILintRuleSeverity;\r\n category: 'naming' | 'structure' | 'documentation' | 'security' | 'performance' | 'compatibility';\r\n fixable?: boolean;\r\n}\r\n\r\n/** Common OpenAPI linting rules */\r\nexport const OPENAPI_LINT_RULES: Record<string, APILintRuleDefinition> = {\r\n 'operation-operationId': {\r\n name: 'operation-operationId',\r\n description: 'Operation must have an operationId',\r\n severity: 'error',\r\n category: 'structure',\r\n fixable: false,\r\n },\r\n 'operation-description': {\r\n name: 'operation-description',\r\n description: 'Operation should have a description',\r\n severity: 'warn',\r\n category: 'documentation',\r\n fixable: false,\r\n },\r\n 'info-contact': {\r\n name: 'info-contact',\r\n description: 'Info object should have contact information',\r\n severity: 'warn',\r\n category: 'documentation',\r\n fixable: false,\r\n },\r\n 'no-$ref-siblings': {\r\n name: 'no-$ref-siblings',\r\n description: 'A $ref object must not have sibling properties',\r\n severity: 'error',\r\n category: 'structure',\r\n fixable: false,\r\n },\r\n 'path-params': {\r\n name: 'path-params',\r\n description: 'Path parameters must be defined',\r\n severity: 'error',\r\n category: 'structure',\r\n fixable: false,\r\n },\r\n};\r\n\r\n// =============================================================================\r\n// Editor Events\r\n// =============================================================================\r\n\r\n/** Editor change event */\r\nexport interface APIEditorChangeEvent {\r\n type: 'change' | 'save' | 'validate' | 'format';\r\n content: string;\r\n format: 'yaml' | 'json';\r\n timestamp: Date;\r\n valid?: boolean;\r\n errors?: OpenAPIValidationResult[];\r\n}\r\n\r\n/** Editor selection event */\r\nexport interface APIEditorSelectionEvent {\r\n path: string;\r\n range: {\r\n start: { line: number; column: number };\r\n end: { line: number; column: number };\r\n };\r\n selectedText: string;\r\n}\r\n\r\n/** Editor navigation event */\r\nexport interface APIEditorNavigationEvent {\r\n from: string;\r\n to: string;\r\n type: 'reference' | 'definition' | 'usage';\r\n}\r\n","/**\r\n * @file download-manager.ts\r\n * @module @nice2dev/ui-tools\r\n * @description PRO-31.1 — Core Download Manager Service\r\n *\r\n * Provides download management with multi-protocol support, segmented downloads,\r\n * queue management, bandwidth throttling, and scheduling.\r\n */\r\n\r\nimport type {\r\n DownloadItem,\r\n DownloadStatus,\r\n DownloadPriority,\r\n DownloadManagerConfig,\r\n DownloadQueue,\r\n DownloadCategory,\r\n TransferSpeed,\r\n TransferStats,\r\n BandwidthLimit,\r\n URLParseResult,\r\n DownloadProtocol,\r\n DownloadSchedule,\r\n FileChecksum,\r\n DownloadSource,\r\n MagnetLinkInfo,\r\n} from './download-torrent';\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Utility Functions\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\n/**\r\n * Formats bytes to human-readable string.\r\n */\r\nexport function formatBytes(bytes: number, decimals = 2): string {\r\n if (bytes === 0) {\r\n return '0 B';\r\n }\r\n const k = 1024;\r\n const dm = decimals < 0 ? 0 : decimals;\r\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];\r\n}\r\n\r\n/**\r\n * Formats speed to TransferSpeed object.\r\n */\r\nexport function formatSpeed(bytesPerSecond: number): TransferSpeed {\r\n const k = 1024;\r\n let unit: TransferSpeed['displayUnit'] = 'B/s';\r\n let value = bytesPerSecond;\r\n\r\n if (bytesPerSecond >= k * k * k) {\r\n unit = 'GB/s';\r\n value = bytesPerSecond / (k * k * k);\r\n } else if (bytesPerSecond >= k * k) {\r\n unit = 'MB/s';\r\n value = bytesPerSecond / (k * k);\r\n } else if (bytesPerSecond >= k) {\r\n unit = 'KB/s';\r\n value = bytesPerSecond / k;\r\n }\r\n\r\n return {\r\n bytesPerSecond,\r\n displayValue: value.toFixed(2),\r\n displayUnit: unit,\r\n };\r\n}\r\n\r\n/**\r\n * Formats duration in seconds to human-readable string.\r\n */\r\nexport function formatDuration(seconds: number): string {\r\n if (!isFinite(seconds) || seconds < 0) {\r\n return '∞';\r\n }\r\n\r\n const hours = Math.floor(seconds / 3600);\r\n const minutes = Math.floor((seconds % 3600) / 60);\r\n const secs = Math.floor(seconds % 60);\r\n\r\n if (hours > 0) {\r\n return `${hours}h ${minutes}m`;\r\n } else if (minutes > 0) {\r\n return `${minutes}m ${secs}s`;\r\n }\r\n return `${secs}s`;\r\n}\r\n\r\n/**\r\n * Calculates ETA based on remaining bytes and speed.\r\n */\r\nexport function calculateETA(\r\n remainingBytes: number,\r\n speedBytesPerSecond: number,\r\n): number | undefined {\r\n if (speedBytesPerSecond <= 0) {\r\n return undefined;\r\n }\r\n return Math.ceil(remainingBytes / speedBytesPerSecond);\r\n}\r\n\r\n/**\r\n * Parses a URL to extract download information.\r\n */\r\nexport function parseDownloadUrl(url: string): URLParseResult {\r\n // Handle magnet links\r\n if (url.startsWith('magnet:')) {\r\n return parseMagnetLink(url);\r\n }\r\n\r\n try {\r\n const parsed = new URL(url);\r\n const pathname = decodeURIComponent(parsed.pathname);\r\n const filename = pathname.split('/').pop() || 'download';\r\n const extension = filename.includes('.') ? filename.split('.').pop()?.toLowerCase() : undefined;\r\n\r\n let protocol: DownloadProtocol = 'https';\r\n if (parsed.protocol === 'http:') {\r\n protocol = 'http';\r\n } else if (parsed.protocol === 'ftp:') {\r\n protocol = 'ftp';\r\n } else if (parsed.protocol === 'sftp:') {\r\n protocol = 'sftp';\r\n }\r\n\r\n return {\r\n url,\r\n protocol,\r\n host: parsed.host,\r\n filename,\r\n extension,\r\n fileType: extension ? getFileType(extension) : undefined,\r\n resumable: protocol === 'https' || protocol === 'http', // Likely resumable for HTTP(S)\r\n requiresAuth: !!parsed.username,\r\n isMagnet: false,\r\n isMetalink: false,\r\n };\r\n } catch {\r\n return {\r\n url,\r\n protocol: 'https',\r\n host: 'unknown',\r\n filename: 'download',\r\n resumable: false,\r\n isMagnet: false,\r\n isMetalink: false,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Parses a magnet link.\r\n */\r\nexport function parseMagnetLink(magnetUrl: string): URLParseResult {\r\n const params = new URLSearchParams(magnetUrl.replace('magnet:?', ''));\r\n const xt = params.get('xt') || '';\r\n const infoHash = xt.replace('urn:btih:', '');\r\n const displayName = params.get('dn') || 'Unknown Torrent';\r\n const trackers = params.getAll('tr');\r\n const exactLength = params.get('xl') ? parseInt(params.get('xl')!, 10) : undefined;\r\n const keywords = params.get('kt')?.split('+') || [];\r\n\r\n const magnetInfo: MagnetLinkInfo = {\r\n infoHash,\r\n displayName,\r\n trackers,\r\n exactLength,\r\n keywords,\r\n };\r\n\r\n return {\r\n url: magnetUrl,\r\n protocol: 'bittorrent',\r\n host: 'bittorrent',\r\n filename: displayName,\r\n size: exactLength,\r\n resumable: true,\r\n isMagnet: true,\r\n isMetalink: false,\r\n magnetInfo,\r\n };\r\n}\r\n\r\n/**\r\n * Gets file type category from extension.\r\n */\r\nexport function getFileType(extension: string): string {\r\n const types: Record<string, string[]> = {\r\n video: ['mp4', 'mkv', 'avi', 'mov', 'wmv', 'flv', 'webm', 'm4v', 'mpeg', 'mpg', '3gp'],\r\n audio: ['mp3', 'flac', 'wav', 'aac', 'ogg', 'wma', 'm4a', 'opus', 'aiff'],\r\n image: ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp', 'ico', 'tiff', 'raw'],\r\n document: ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'rtf', 'odt'],\r\n archive: ['zip', 'rar', '7z', 'tar', 'gz', 'bz2', 'xz', 'iso'],\r\n executable: ['exe', 'msi', 'dmg', 'app', 'deb', 'rpm', 'apk'],\r\n code: ['js', 'ts', 'py', 'java', 'cpp', 'c', 'cs', 'go', 'rs', 'rb', 'php'],\r\n };\r\n\r\n for (const [type, extensions] of Object.entries(types)) {\r\n if (extensions.includes(extension.toLowerCase())) {\r\n return type;\r\n }\r\n }\r\n return 'other';\r\n}\r\n\r\n/**\r\n * Generates a unique download ID.\r\n */\r\nexport function generateDownloadId(): string {\r\n return `dl_${Date.now().toString(36)}_${Math.random().toString(36).substring(2, 9)}`;\r\n}\r\n\r\n/**\r\n * Validates a checksum against file data.\r\n */\r\nexport async function validateChecksum(\r\n data: ArrayBuffer,\r\n checksum: FileChecksum,\r\n): Promise<boolean> {\r\n if (typeof crypto === 'undefined' || !crypto.subtle) {\r\n console.warn('Web Crypto API not available for checksum validation');\r\n return true; // Skip validation\r\n }\r\n\r\n const algorithmMap: Record<string, string> = {\r\n sha256: 'SHA-256',\r\n sha512: 'SHA-512',\r\n sha1: 'SHA-1',\r\n };\r\n\r\n const algorithm = algorithmMap[checksum.algorithm];\r\n if (!algorithm) {\r\n console.warn(`Unsupported checksum algorithm: ${checksum.algorithm}`);\r\n return true;\r\n }\r\n\r\n const hashBuffer = await crypto.subtle.digest(algorithm, data);\r\n const hashArray = Array.from(new Uint8Array(hashBuffer));\r\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\r\n\r\n return hashHex.toLowerCase() === checksum.value.toLowerCase();\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Download Segment Manager\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\nexport interface DownloadSegment {\r\n index: number;\r\n start: number;\r\n end: number;\r\n downloaded: number;\r\n status: 'pending' | 'downloading' | 'completed' | 'failed';\r\n retries: number;\r\n}\r\n\r\n/**\r\n * Creates segments for parallel downloading.\r\n */\r\nexport function createDownloadSegments(totalSize: number, segmentCount: number): DownloadSegment[] {\r\n if (totalSize <= 0 || segmentCount <= 0) {\r\n return [];\r\n }\r\n\r\n const segmentSize = Math.ceil(totalSize / segmentCount);\r\n const segments: DownloadSegment[] = [];\r\n\r\n for (let i = 0; i < segmentCount; i++) {\r\n const start = i * segmentSize;\r\n const end = Math.min(start + segmentSize - 1, totalSize - 1);\r\n\r\n segments.push({\r\n index: i,\r\n start,\r\n end,\r\n downloaded: 0,\r\n status: 'pending',\r\n retries: 0,\r\n });\r\n }\r\n\r\n return segments;\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Download Manager Class\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\nexport type DownloadEventType =\r\n | 'added'\r\n | 'started'\r\n | 'progress'\r\n | 'paused'\r\n | 'resumed'\r\n | 'completed'\r\n | 'failed'\r\n | 'cancelled'\r\n | 'queue-changed';\r\n\r\nexport interface DownloadEvent {\r\n type: DownloadEventType;\r\n download?: DownloadItem;\r\n queue?: DownloadQueue;\r\n error?: Error;\r\n}\r\n\r\nexport type DownloadEventCallback = (event: DownloadEvent) => void;\r\n\r\n/**\r\n * Core Download Manager service.\r\n */\r\nexport class DownloadManager {\r\n private config: DownloadManagerConfig;\r\n private downloads: Map<string, DownloadItem> = new Map();\r\n private activeDownloads: Set<string> = new Set();\r\n private abortControllers: Map<string, AbortController> = new Map();\r\n private speedSamples: Map<string, number[]> = new Map();\r\n private eventListeners: Map<DownloadEventType, Set<DownloadEventCallback>> = new Map();\r\n private updateInterval: ReturnType<typeof setInterval> | null = null;\r\n\r\n constructor(config: Partial<DownloadManagerConfig> = {}) {\r\n this.config = {\r\n defaultDownloadPath: config.defaultDownloadPath ?? '/downloads',\r\n maxConcurrentDownloads: config.maxConcurrentDownloads ?? 3,\r\n bandwidthLimit: config.bandwidthLimit,\r\n retryAttempts: config.retryAttempts ?? 3,\r\n retryDelay: config.retryDelay ?? 5000,\r\n autoStart: config.autoStart ?? true,\r\n resumeOnStartup: config.resumeOnStartup ?? true,\r\n categories: config.categories ?? [],\r\n fileTypeFilters: config.fileTypeFilters ?? [],\r\n };\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Event Handling\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Subscribes to download events.\r\n */\r\n on(event: DownloadEventType, callback: DownloadEventCallback): () => void {\r\n if (!this.eventListeners.has(event)) {\r\n this.eventListeners.set(event, new Set());\r\n }\r\n this.eventListeners.get(event)!.add(callback);\r\n return () => this.eventListeners.get(event)?.delete(callback);\r\n }\r\n\r\n /**\r\n * Emits a download event.\r\n */\r\n private emit(event: DownloadEvent): void {\r\n const listeners = this.eventListeners.get(event.type);\r\n if (listeners) {\r\n for (const callback of listeners) {\r\n try {\r\n callback(event);\r\n } catch (error) {\r\n console.error('Download event listener error:', error);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Queue Management\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Adds a download to the queue.\r\n */\r\n addDownload(\r\n url: string,\r\n options: Partial<{\r\n filename: string;\r\n path: string;\r\n priority: DownloadPriority;\r\n category: string;\r\n checksum: FileChecksum;\r\n autoStart: boolean;\r\n headers: Record<string, string>;\r\n }> = {},\r\n ): DownloadItem {\r\n const parsed = parseDownloadUrl(url);\r\n const id = generateDownloadId();\r\n\r\n const download: DownloadItem = {\r\n id,\r\n url,\r\n filename: options.filename ?? parsed.filename,\r\n path: options.path ?? this.config.defaultDownloadPath,\r\n status: 'queued',\r\n priority: options.priority ?? 'normal',\r\n size: parsed.size,\r\n downloadedBytes: 0,\r\n progress: 0,\r\n speed: formatSpeed(0),\r\n addedDate: new Date(),\r\n retryCount: 0,\r\n category: options.category ?? this.detectCategory(parsed.extension),\r\n source: {\r\n type: parsed.isMagnet ? 'magnet' : 'direct',\r\n protocol: parsed.protocol,\r\n host: parsed.host,\r\n },\r\n checksum: options.checksum,\r\n };\r\n\r\n this.downloads.set(id, download);\r\n this.emit({ type: 'added', download });\r\n this.emitQueueChanged();\r\n\r\n // Auto-start if configured and queue has capacity\r\n if (\r\n (options.autoStart ?? this.config.autoStart) &&\r\n this.activeDownloads.size < this.config.maxConcurrentDownloads\r\n ) {\r\n this.startDownload(id);\r\n }\r\n\r\n return download;\r\n }\r\n\r\n /**\r\n * Adds multiple downloads from URLs.\r\n */\r\n addDownloads(\r\n urls: string[],\r\n options: Partial<{\r\n path: string;\r\n priority: DownloadPriority;\r\n category: string;\r\n autoStart: boolean;\r\n }> = {},\r\n ): DownloadItem[] {\r\n return urls.map((url) => this.addDownload(url, options));\r\n }\r\n\r\n /**\r\n * Removes a download from the queue.\r\n */\r\n removeDownload(id: string, deleteFile = false): boolean {\r\n const download = this.downloads.get(id);\r\n if (!download) {\r\n return false;\r\n }\r\n\r\n // Cancel if active\r\n this.cancelDownload(id);\r\n\r\n this.downloads.delete(id);\r\n this.emitQueueChanged();\r\n\r\n // Note: File deletion would require file system access\r\n if (deleteFile) {\r\n console.warn('File deletion not implemented in browser environment');\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Gets a download by ID.\r\n */\r\n getDownload(id: string): DownloadItem | undefined {\r\n return this.downloads.get(id);\r\n }\r\n\r\n /**\r\n * Gets all downloads.\r\n */\r\n getAllDownloads(): DownloadItem[] {\r\n return Array.from(this.downloads.values());\r\n }\r\n\r\n /**\r\n * Gets the download queue summary.\r\n */\r\n getQueue(): DownloadQueue {\r\n const items = this.getAllDownloads();\r\n const totalSize = items.reduce((sum, d) => sum + (d.size ?? 0), 0);\r\n const totalDownloaded = items.reduce((sum, d) => sum + d.downloadedBytes, 0);\r\n\r\n return {\r\n items,\r\n totalSize,\r\n totalProgress: totalSize > 0 ? (totalDownloaded / totalSize) * 100 : 0,\r\n activeDownloads: this.activeDownloads.size,\r\n queuedDownloads: items.filter((d) => d.status === 'queued').length,\r\n completedDownloads: items.filter((d) => d.status === 'completed').length,\r\n };\r\n }\r\n\r\n /**\r\n * Gets downloads by status.\r\n */\r\n getDownloadsByStatus(status: DownloadStatus): DownloadItem[] {\r\n return this.getAllDownloads().filter((d) => d.status === status);\r\n }\r\n\r\n /**\r\n * Gets downloads by category.\r\n */\r\n getDownloadsByCategory(category: string): DownloadItem[] {\r\n return this.getAllDownloads().filter((d) => d.category === category);\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Download Control\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Starts a download.\r\n */\r\n async startDownload(id: string): Promise<void> {\r\n const download = this.downloads.get(id);\r\n if (!download) {\r\n return;\r\n }\r\n\r\n if (download.status === 'downloading') {\r\n return;\r\n }\r\n if (this.activeDownloads.size >= this.config.maxConcurrentDownloads) {\r\n download.status = 'queued';\r\n return;\r\n }\r\n\r\n download.status = 'downloading';\r\n download.startedDate = new Date();\r\n this.activeDownloads.add(id);\r\n\r\n const abortController = new AbortController();\r\n this.abortControllers.set(id, abortController);\r\n this.speedSamples.set(id, []);\r\n\r\n this.emit({ type: 'started', download });\r\n\r\n try {\r\n await this.executeDownload(download, abortController.signal);\r\n\r\n download.status = 'completed';\r\n download.completedDate = new Date();\r\n download.progress = 100;\r\n this.emit({ type: 'completed', download });\r\n } catch (error) {\r\n if (abortController.signal.aborted) {\r\n // Cancelled by user\r\n return;\r\n }\r\n\r\n download.errorMessage = error instanceof Error ? error.message : 'Download failed';\r\n\r\n // Retry logic\r\n if (download.retryCount < this.config.retryAttempts) {\r\n download.retryCount++;\r\n download.status = 'queued';\r\n setTimeout(() => this.startDownload(id), this.config.retryDelay);\r\n } else {\r\n download.status = 'failed';\r\n this.emit({\r\n type: 'failed',\r\n download,\r\n error: error instanceof Error ? error : new Error(String(error)),\r\n });\r\n }\r\n } finally {\r\n this.activeDownloads.delete(id);\r\n this.abortControllers.delete(id);\r\n this.speedSamples.delete(id);\r\n this.emitQueueChanged();\r\n\r\n // Start next in queue\r\n this.processQueue();\r\n }\r\n }\r\n\r\n /**\r\n * Pauses a download.\r\n */\r\n pauseDownload(id: string): void {\r\n const download = this.downloads.get(id);\r\n if (!download || download.status !== 'downloading') {\r\n return;\r\n }\r\n\r\n const controller = this.abortControllers.get(id);\r\n if (controller) {\r\n controller.abort();\r\n }\r\n\r\n download.status = 'paused';\r\n this.activeDownloads.delete(id);\r\n this.emit({ type: 'paused', download });\r\n this.emitQueueChanged();\r\n\r\n // Start next in queue\r\n this.processQueue();\r\n }\r\n\r\n /**\r\n * Resumes a paused download.\r\n */\r\n resumeDownload(id: string): void {\r\n const download = this.downloads.get(id);\r\n if (!download || download.status !== 'paused') {\r\n return;\r\n }\r\n\r\n download.status = 'queued';\r\n this.emit({ type: 'resumed', download });\r\n this.startDownload(id);\r\n }\r\n\r\n /**\r\n * Cancels a download.\r\n */\r\n cancelDownload(id: string): void {\r\n const download = this.downloads.get(id);\r\n if (!download) {\r\n return;\r\n }\r\n\r\n const controller = this.abortControllers.get(id);\r\n if (controller) {\r\n controller.abort();\r\n }\r\n\r\n download.status = 'cancelled';\r\n this.activeDownloads.delete(id);\r\n this.emit({ type: 'cancelled', download });\r\n this.emitQueueChanged();\r\n\r\n this.processQueue();\r\n }\r\n\r\n /**\r\n * Pauses all active downloads.\r\n */\r\n pauseAll(): void {\r\n for (const id of this.activeDownloads) {\r\n this.pauseDownload(id);\r\n }\r\n }\r\n\r\n /**\r\n * Resumes all paused downloads.\r\n */\r\n resumeAll(): void {\r\n for (const download of this.downloads.values()) {\r\n if (download.status === 'paused') {\r\n this.resumeDownload(download.id);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Cancels all downloads.\r\n */\r\n cancelAll(): void {\r\n for (const id of this.downloads.keys()) {\r\n this.cancelDownload(id);\r\n }\r\n }\r\n\r\n /**\r\n * Changes download priority.\r\n */\r\n setPriority(id: string, priority: DownloadPriority): void {\r\n const download = this.downloads.get(id);\r\n if (download) {\r\n download.priority = priority;\r\n this.emitQueueChanged();\r\n }\r\n }\r\n\r\n /**\r\n * Moves a download in the queue.\r\n */\r\n moveInQueue(id: string, direction: 'up' | 'down' | 'top' | 'bottom'): void {\r\n const items = this.getAllDownloads().filter((d) => d.status === 'queued');\r\n const index = items.findIndex((d) => d.id === id);\r\n if (index === -1) {\r\n return;\r\n }\r\n\r\n // Re-prioritize based on direction\r\n switch (direction) {\r\n case 'top':\r\n items[index].priority = 'critical';\r\n break;\r\n case 'up':\r\n if (items[index].priority === 'normal') {\r\n items[index].priority = 'high';\r\n } else if (items[index].priority === 'low') {\r\n items[index].priority = 'normal';\r\n }\r\n break;\r\n case 'down':\r\n if (items[index].priority === 'normal') {\r\n items[index].priority = 'low';\r\n } else if (items[index].priority === 'high') {\r\n items[index].priority = 'normal';\r\n }\r\n break;\r\n case 'bottom':\r\n items[index].priority = 'low';\r\n break;\r\n }\r\n\r\n this.emitQueueChanged();\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Configuration\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Gets the current configuration.\r\n */\r\n getConfig(): DownloadManagerConfig {\r\n return { ...this.config };\r\n }\r\n\r\n /**\r\n * Updates the configuration.\r\n */\r\n updateConfig(updates: Partial<DownloadManagerConfig>): void {\r\n this.config = { ...this.config, ...updates };\r\n }\r\n\r\n /**\r\n * Sets bandwidth limit.\r\n */\r\n setBandwidthLimit(limit: BandwidthLimit | undefined): void {\r\n this.config.bandwidthLimit = limit;\r\n }\r\n\r\n /**\r\n * Sets maximum concurrent downloads.\r\n */\r\n setMaxConcurrentDownloads(max: number): void {\r\n this.config.maxConcurrentDownloads = max;\r\n this.processQueue();\r\n }\r\n\r\n /**\r\n * Adds a download category.\r\n */\r\n addCategory(category: DownloadCategory): void {\r\n this.config.categories = [...(this.config.categories ?? []), category];\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Statistics\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Gets overall transfer statistics.\r\n */\r\n getStats(): TransferStats {\r\n const downloads = this.getAllDownloads();\r\n const downloaded = downloads.reduce((sum, d) => sum + d.downloadedBytes, 0);\r\n const total = downloads.reduce((sum, d) => sum + (d.size ?? 0), 0);\r\n\r\n // Calculate aggregate speed\r\n let totalSpeed = 0;\r\n for (const id of this.activeDownloads) {\r\n const download = this.downloads.get(id);\r\n if (download) {\r\n totalSpeed += download.speed.bytesPerSecond;\r\n }\r\n }\r\n\r\n return {\r\n downloaded,\r\n uploaded: 0,\r\n remaining: total - downloaded,\r\n total,\r\n progress: total > 0 ? (downloaded / total) * 100 : 0,\r\n downloadSpeed: formatSpeed(totalSpeed),\r\n uploadSpeed: formatSpeed(0),\r\n eta: totalSpeed > 0 ? calculateETA(total - downloaded, totalSpeed) : undefined,\r\n };\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Private Methods\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Executes the actual download using Fetch API.\r\n */\r\n private async executeDownload(download: DownloadItem, signal: AbortSignal): Promise<void> {\r\n const response = await fetch(download.url, {\r\n signal,\r\n headers: download.source?.auth ? this.buildAuthHeaders(download.source.auth) : undefined,\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\r\n }\r\n\r\n const contentLength = response.headers.get('content-length');\r\n if (contentLength) {\r\n download.size = parseInt(contentLength, 10);\r\n }\r\n\r\n const reader = response.body?.getReader();\r\n if (!reader) {\r\n throw new Error('Response body is not readable');\r\n }\r\n\r\n const chunks: Uint8Array[] = [];\r\n let lastUpdate = Date.now();\r\n let bytesInInterval = 0;\r\n\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n\r\n if (done) {\r\n break;\r\n }\r\n\r\n chunks.push(value);\r\n download.downloadedBytes += value.length;\r\n bytesInInterval += value.length;\r\n\r\n // Update progress\r\n if (download.size) {\r\n download.progress = (download.downloadedBytes / download.size) * 100;\r\n }\r\n\r\n // Calculate speed every 500ms\r\n const now = Date.now();\r\n const elapsed = now - lastUpdate;\r\n if (elapsed >= 500) {\r\n const speed = (bytesInInterval / elapsed) * 1000;\r\n this.updateSpeed(download.id, speed);\r\n download.speed = formatSpeed(speed);\r\n download.eta = download.size\r\n ? calculateETA(download.size - download.downloadedBytes, speed)\r\n : undefined;\r\n\r\n this.emit({ type: 'progress', download });\r\n\r\n lastUpdate = now;\r\n bytesInInterval = 0;\r\n }\r\n }\r\n\r\n // Combine chunks and validate checksum if provided\r\n const data = new Uint8Array(download.downloadedBytes);\r\n let offset = 0;\r\n for (const chunk of chunks) {\r\n data.set(chunk, offset);\r\n offset += chunk.length;\r\n }\r\n\r\n if (download.checksum) {\r\n const valid = await validateChecksum(data.buffer, download.checksum);\r\n if (!valid) {\r\n throw new Error('Checksum validation failed');\r\n }\r\n download.checksum.verified = true;\r\n }\r\n\r\n // In a browser environment, we'd typically create a blob and trigger download\r\n // For Node.js/Electron, we'd write to the file system\r\n this.handleDownloadComplete(download, data);\r\n }\r\n\r\n /**\r\n * Handles completed download data.\r\n */\r\n private handleDownloadComplete(download: DownloadItem, data: Uint8Array): void {\r\n // Create blob and download link for browser\r\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\r\n const blob = new Blob([new Uint8Array(data)]);\r\n const url = URL.createObjectURL(blob);\r\n const a = document.createElement('a');\r\n a.href = url;\r\n a.download = download.filename;\r\n document.body.appendChild(a);\r\n a.click();\r\n document.body.removeChild(a);\r\n URL.revokeObjectURL(url);\r\n }\r\n }\r\n\r\n /**\r\n * Builds authentication headers.\r\n */\r\n private buildAuthHeaders(auth: DownloadSource['auth']): Record<string, string> {\r\n if (!auth) {\r\n return {};\r\n }\r\n\r\n switch (auth.type) {\r\n case 'basic':\r\n const credentials = btoa(`${auth.username}:${auth.password}`);\r\n return { Authorization: `Basic ${credentials}` };\r\n case 'bearer':\r\n return { Authorization: `Bearer ${auth.token}` };\r\n case 'api_key':\r\n return { 'X-API-Key': auth.apiKey ?? '' };\r\n default:\r\n return {};\r\n }\r\n }\r\n\r\n /**\r\n * Updates speed tracking for a download.\r\n */\r\n private updateSpeed(id: string, speed: number): void {\r\n const samples = this.speedSamples.get(id) || [];\r\n samples.push(speed);\r\n\r\n // Keep last 10 samples for smoothing\r\n if (samples.length > 10) {\r\n samples.shift();\r\n }\r\n\r\n this.speedSamples.set(id, samples);\r\n }\r\n\r\n /**\r\n * Processes the download queue.\r\n */\r\n private processQueue(): void {\r\n if (this.activeDownloads.size >= this.config.maxConcurrentDownloads) {\r\n return;\r\n }\r\n\r\n // Get queued downloads sorted by priority\r\n const queued = this.getDownloadsByStatus('queued').sort((a, b) => {\r\n const priorityOrder = { critical: 0, high: 1, normal: 2, low: 3 };\r\n return priorityOrder[a.priority] - priorityOrder[b.priority];\r\n });\r\n\r\n for (const download of queued) {\r\n if (this.activeDownloads.size >= this.config.maxConcurrentDownloads) {\r\n break;\r\n }\r\n this.startDownload(download.id);\r\n }\r\n }\r\n\r\n /**\r\n * Detects category from file extension.\r\n */\r\n private detectCategory(extension?: string): string | undefined {\r\n if (!extension || !this.config.categories) {\r\n return undefined;\r\n }\r\n\r\n for (const category of this.config.categories) {\r\n if (category.fileTypes?.includes(extension.toLowerCase())) {\r\n return category.id;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Emits a queue changed event.\r\n */\r\n private emitQueueChanged(): void {\r\n this.emit({ type: 'queue-changed', queue: this.getQueue() });\r\n }\r\n\r\n /**\r\n * Disposes the download manager.\r\n */\r\n dispose(): void {\r\n this.cancelAll();\r\n if (this.updateInterval) {\r\n clearInterval(this.updateInterval);\r\n }\r\n this.eventListeners.clear();\r\n this.downloads.clear();\r\n }\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Singleton Instance\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\nlet downloadManagerInstance: DownloadManager | null = null;\r\n\r\n/**\r\n * Gets or creates the download manager singleton.\r\n */\r\nexport function getDownloadManager(config?: Partial<DownloadManagerConfig>): DownloadManager {\r\n if (!downloadManagerInstance) {\r\n downloadManagerInstance = new DownloadManager(config);\r\n }\r\n return downloadManagerInstance;\r\n}\r\n\r\n/**\r\n * Disposes the download manager singleton.\r\n */\r\nexport function disposeDownloadManager(): void {\r\n downloadManagerInstance?.dispose();\r\n downloadManagerInstance = null;\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n React Hook\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\nimport { useState, useEffect, useCallback, useMemo } from 'react';\r\n\r\nexport interface UseDownloadManagerOptions {\r\n config?: Partial<DownloadManagerConfig>;\r\n autoRefresh?: boolean;\r\n refreshInterval?: number;\r\n}\r\n\r\nexport interface UseDownloadManagerReturn {\r\n /** Queue state */\r\n queue: DownloadQueue;\r\n /** Transfer stats */\r\n stats: TransferStats;\r\n /** Active downloads */\r\n activeDownloads: DownloadItem[];\r\n /** Add a download */\r\n addDownload: (\r\n url: string,\r\n options?: Parameters<DownloadManager['addDownload']>[1],\r\n ) => DownloadItem;\r\n /** Add multiple downloads */\r\n addDownloads: (\r\n urls: string[],\r\n options?: Parameters<DownloadManager['addDownloads']>[1],\r\n ) => DownloadItem[];\r\n /** Start a download */\r\n startDownload: (id: string) => void;\r\n /** Pause a download */\r\n pauseDownload: (id: string) => void;\r\n /** Resume a download */\r\n resumeDownload: (id: string) => void;\r\n /** Cancel a download */\r\n cancelDownload: (id: string) => void;\r\n /** Remove a download */\r\n removeDownload: (id: string, deleteFile?: boolean) => void;\r\n /** Pause all downloads */\r\n pauseAll: () => void;\r\n /** Resume all downloads */\r\n resumeAll: () => void;\r\n /** Set bandwidth limit */\r\n setBandwidthLimit: (limit: BandwidthLimit | undefined) => void;\r\n /** Set priority */\r\n setPriority: (id: string, priority: DownloadPriority) => void;\r\n}\r\n\r\n/**\r\n * React hook for download manager.\r\n */\r\nexport function useDownloadManager(\r\n options: UseDownloadManagerOptions = {},\r\n): UseDownloadManagerReturn {\r\n const { config, autoRefresh = true, refreshInterval = 1000 } = options;\r\n\r\n const manager = useMemo(() => getDownloadManager(config), [config]);\r\n\r\n const [queue, setQueue] = useState<DownloadQueue>(manager.getQueue());\r\n const [stats, setStats] = useState<TransferStats>(manager.getStats());\r\n\r\n useEffect(() => {\r\n const handleQueueChange = () => {\r\n setQueue(manager.getQueue());\r\n setStats(manager.getStats());\r\n };\r\n\r\n const unsubscribers = [\r\n manager.on('added', handleQueueChange),\r\n manager.on('started', handleQueueChange),\r\n manager.on('progress', handleQueueChange),\r\n manager.on('paused', handleQueueChange),\r\n manager.on('resumed', handleQueueChange),\r\n manager.on('completed', handleQueueChange),\r\n manager.on('failed', handleQueueChange),\r\n manager.on('cancelled', handleQueueChange),\r\n manager.on('queue-changed', handleQueueChange),\r\n ];\r\n\r\n // Auto-refresh for active downloads\r\n let interval: ReturnType<typeof setInterval> | undefined;\r\n if (autoRefresh) {\r\n interval = setInterval(() => {\r\n if (manager.getQueue().activeDownloads > 0) {\r\n handleQueueChange();\r\n }\r\n }, refreshInterval);\r\n }\r\n\r\n return () => {\r\n unsubscribers.forEach((unsub) => unsub());\r\n if (interval) {\r\n clearInterval(interval);\r\n }\r\n };\r\n }, [manager, autoRefresh, refreshInterval]);\r\n\r\n const activeDownloads = useMemo(\r\n () => queue.items.filter((d) => d.status === 'downloading'),\r\n [queue],\r\n );\r\n\r\n const addDownload = useCallback(\r\n (url: string, opts?: Parameters<DownloadManager['addDownload']>[1]) =>\r\n manager.addDownload(url, opts),\r\n [manager],\r\n );\r\n\r\n const addDownloads = useCallback(\r\n (urls: string[], opts?: Parameters<DownloadManager['addDownloads']>[1]) =>\r\n manager.addDownloads(urls, opts),\r\n [manager],\r\n );\r\n\r\n return {\r\n queue,\r\n stats,\r\n activeDownloads,\r\n addDownload,\r\n addDownloads,\r\n startDownload: useCallback((id) => manager.startDownload(id), [manager]),\r\n pauseDownload: useCallback((id) => manager.pauseDownload(id), [manager]),\r\n resumeDownload: useCallback((id) => manager.resumeDownload(id), [manager]),\r\n cancelDownload: useCallback((id) => manager.cancelDownload(id), [manager]),\r\n removeDownload: useCallback(\r\n (id, deleteFile) => manager.removeDownload(id, deleteFile),\r\n [manager],\r\n ),\r\n pauseAll: useCallback(() => manager.pauseAll(), [manager]),\r\n resumeAll: useCallback(() => manager.resumeAll(), [manager]),\r\n setBandwidthLimit: useCallback((limit) => manager.setBandwidthLimit(limit), [manager]),\r\n setPriority: useCallback((id, priority) => manager.setPriority(id, priority), [manager]),\r\n };\r\n}\r\n","/**\r\n * @file torrent-client.ts\r\n * @module @nice2dev/ui-tools\r\n * @description PRO-31.2 — BitTorrent Client Service\r\n *\r\n * Provides BitTorrent functionality including magnet handling, DHT, PEX,\r\n * selective file download, sequential downloading, and torrent creation.\r\n */\r\n\r\nimport { formatSpeed, calculateETA } from './download-manager';\r\nimport type {\r\n Torrent,\r\n TorrentFile,\r\n TorrentClientConfig,\r\n TorrentTracker,\r\n Peer,\r\n TorrentStatus,\r\n DownloadPriority,\r\n TorrentDashboardStats,\r\n TransferSpeed,\r\n MagnetLinkInfo,\r\n PieceStatus,\r\n TorrentCreationOptions,\r\n CreatedTorrent,\r\n BandwidthLimit,\r\n} from './download-torrent';\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Torrent Utilities\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\n/**\r\n * Generates an info hash from torrent metadata.\r\n */\r\nexport function generateInfoHash(): string {\r\n const chars = '0123456789abcdef';\r\n let hash = '';\r\n for (let i = 0; i < 40; i++) {\r\n hash += chars[Math.floor(Math.random() * chars.length)];\r\n }\r\n return hash;\r\n}\r\n\r\n/**\r\n * Generates a peer ID.\r\n */\r\nexport function generatePeerId(): string {\r\n const clientId = '-NI0100-'; // NI = Nice2Dev, version 01.00\r\n const randomPart = Array.from({ length: 12 }, () =>\r\n Math.floor(Math.random() * 256)\r\n .toString(16)\r\n .padStart(2, '0'),\r\n ).join('');\r\n return clientId + randomPart;\r\n}\r\n\r\n/**\r\n * Parses a magnet link.\r\n */\r\nexport function parseMagnetUri(magnetUri: string): MagnetLinkInfo | null {\r\n if (!magnetUri.startsWith('magnet:?')) {\r\n return null;\r\n }\r\n\r\n const params = new URLSearchParams(magnetUri.replace('magnet:?', ''));\r\n\r\n const xt = params.get('xt');\r\n if (!xt) {\r\n return null;\r\n }\r\n\r\n const infoHash = xt.replace('urn:btih:', '');\r\n const displayName = params.get('dn') || undefined;\r\n const trackers = params.getAll('tr');\r\n const exactLength = params.get('xl') ? parseInt(params.get('xl')!, 10) : undefined;\r\n const keywords = params.get('kt')?.split('+') || undefined;\r\n\r\n return {\r\n infoHash,\r\n displayName,\r\n trackers: trackers.length > 0 ? trackers : undefined,\r\n exactLength,\r\n keywords,\r\n };\r\n}\r\n\r\n/**\r\n * Creates a magnet URI from torrent info.\r\n */\r\nexport function createMagnetUri(torrent: {\r\n infoHash: string;\r\n name: string;\r\n trackers?: string[];\r\n size?: number;\r\n}): string {\r\n const params = new URLSearchParams();\r\n params.set('xt', `urn:btih:${torrent.infoHash}`);\r\n params.set('dn', torrent.name);\r\n\r\n if (torrent.size) {\r\n params.set('xl', torrent.size.toString());\r\n }\r\n\r\n if (torrent.trackers) {\r\n for (const tracker of torrent.trackers) {\r\n params.append('tr', tracker);\r\n }\r\n }\r\n\r\n return `magnet:?${params.toString()}`;\r\n}\r\n\r\n/**\r\n * Calculates pieces for a file.\r\n */\r\nexport function calculatePieces(totalSize: number, pieceSize: number = 262144): number {\r\n return Math.ceil(totalSize / pieceSize);\r\n}\r\n\r\n/**\r\n * Creates piece array for a torrent.\r\n */\r\nexport function createPieceStatus(pieceCount: number): PieceStatus[] {\r\n return Array.from({ length: pieceCount }, () => 'missing' as PieceStatus);\r\n}\r\n\r\n/**\r\n * Formats peer count display.\r\n */\r\nexport function formatPeerCount(connected: number, total: number): string {\r\n return `${connected}/${total}`;\r\n}\r\n\r\n/**\r\n * Calculates torrent health based on seeders and leechers.\r\n */\r\nexport function calculateTorrentHealth(\r\n seeders: number,\r\n leechers: number,\r\n): 'excellent' | 'good' | 'fair' | 'poor' | 'dead' {\r\n if (seeders === 0) {\r\n return 'dead';\r\n }\r\n const ratio = seeders / (leechers + 1);\r\n if (ratio >= 2 && seeders >= 10) {\r\n return 'excellent';\r\n }\r\n if (ratio >= 1 && seeders >= 5) {\r\n return 'good';\r\n }\r\n if (seeders >= 1) {\r\n return 'fair';\r\n }\r\n return 'poor';\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Torrent File Selection\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\n/**\r\n * Creates a file selection map from torrent files.\r\n */\r\nexport function createFileSelection(files: TorrentFile[]): Map<number, boolean> {\r\n return new Map(files.map((f) => [f.index, f.wanted]));\r\n}\r\n\r\n/**\r\n * Filters files by extension.\r\n */\r\nexport function filterFilesByExtension(files: TorrentFile[], extensions: string[]): TorrentFile[] {\r\n return files.filter((f) => {\r\n const ext = f.name.split('.').pop()?.toLowerCase();\r\n return ext && extensions.includes(ext);\r\n });\r\n}\r\n\r\n/**\r\n * Gets video files from torrent.\r\n */\r\nexport function getVideoFiles(files: TorrentFile[]): TorrentFile[] {\r\n const videoExtensions = ['mp4', 'mkv', 'avi', 'mov', 'wmv', 'flv', 'webm', 'm4v', 'mpeg', 'mpg'];\r\n return filterFilesByExtension(files, videoExtensions);\r\n}\r\n\r\n/**\r\n * Gets audio files from torrent.\r\n */\r\nexport function getAudioFiles(files: TorrentFile[]): TorrentFile[] {\r\n const audioExtensions = ['mp3', 'flac', 'wav', 'aac', 'ogg', 'wma', 'm4a', 'opus'];\r\n return filterFilesByExtension(files, audioExtensions);\r\n}\r\n\r\n/**\r\n * Gets largest file in torrent.\r\n */\r\nexport function getLargestFile(files: TorrentFile[]): TorrentFile | undefined {\r\n return files.reduce(\r\n (largest, file) => (file.size > (largest?.size ?? 0) ? file : largest),\r\n undefined as TorrentFile | undefined,\r\n );\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Torrent Event System\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\nexport type TorrentEventType =\r\n | 'added'\r\n | 'metadata'\r\n | 'started'\r\n | 'progress'\r\n | 'piece'\r\n | 'paused'\r\n | 'resumed'\r\n | 'completed'\r\n | 'seeding'\r\n | 'failed'\r\n | 'removed'\r\n | 'peer-connect'\r\n | 'peer-disconnect'\r\n | 'tracker-update';\r\n\r\nexport interface TorrentEvent {\r\n type: TorrentEventType;\r\n torrent?: Torrent;\r\n peer?: Peer;\r\n tracker?: TorrentTracker;\r\n pieceIndex?: number;\r\n error?: Error;\r\n}\r\n\r\nexport type TorrentEventCallback = (event: TorrentEvent) => void;\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Internal Torrent State (extends Torrent with additional runtime state)\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\ninterface InternalTorrentState extends Torrent {\r\n magnetUri?: string;\r\n startedDate?: Date;\r\n sequentialDownload?: boolean;\r\n selectedFiles?: number[];\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Torrent Client Class\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\n/**\r\n * BitTorrent Client service.\r\n */\r\nexport class TorrentClient {\r\n private config: TorrentClientConfig;\r\n private torrents: Map<string, InternalTorrentState> = new Map();\r\n private eventListeners: Map<TorrentEventType, Set<TorrentEventCallback>> = new Map();\r\n private peerId: string;\r\n private updateIntervals: Map<string, ReturnType<typeof setInterval>> = new Map();\r\n\r\n constructor(config: Partial<TorrentClientConfig> = {}) {\r\n this.peerId = generatePeerId();\r\n this.config = {\r\n downloadPath: config.downloadPath ?? '/downloads/torrents',\r\n tempPath: config.tempPath,\r\n maxActiveTorrents: config.maxActiveTorrents ?? 5,\r\n maxActiveSeedsperTorrent: config.maxActiveSeedsperTorrent ?? 50,\r\n maxConnectionsPerTorrent: config.maxConnectionsPerTorrent ?? 50,\r\n maxGlobalConnections: config.maxGlobalConnections ?? 200,\r\n bandwidthLimit: config.bandwidthLimit ?? { enabled: false, unit: 'MB/s' },\r\n dhtEnabled: config.dhtEnabled ?? true,\r\n pexEnabled: config.pexEnabled ?? true,\r\n lpdEnabled: config.lpdEnabled ?? true,\r\n upnpEnabled: config.upnpEnabled ?? true,\r\n natPmpEnabled: config.natPmpEnabled ?? true,\r\n encryptionMode: config.encryptionMode ?? 'enabled',\r\n ipv6Enabled: config.ipv6Enabled ?? true,\r\n listeningPort: config.listeningPort ?? 6881,\r\n proxySettings: config.proxySettings,\r\n };\r\n\r\n if (this.config.dhtEnabled) {\r\n this.initDHT();\r\n }\r\n if (this.config.pexEnabled) {\r\n this.initPEX();\r\n }\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Event Handling\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Subscribes to torrent events.\r\n */\r\n on(event: TorrentEventType, callback: TorrentEventCallback): () => void {\r\n if (!this.eventListeners.has(event)) {\r\n this.eventListeners.set(event, new Set());\r\n }\r\n this.eventListeners.get(event)!.add(callback);\r\n return () => this.eventListeners.get(event)?.delete(callback);\r\n }\r\n\r\n /**\r\n * Emits a torrent event.\r\n */\r\n private emit(event: TorrentEvent): void {\r\n const listeners = this.eventListeners.get(event.type);\r\n if (listeners) {\r\n for (const callback of listeners) {\r\n try {\r\n callback(event);\r\n } catch (error) {\r\n console.error('Torrent event listener error:', error);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Torrent Management\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Adds a torrent from magnet URI.\r\n */\r\n addMagnet(\r\n magnetUri: string,\r\n options: Partial<{\r\n path: string;\r\n priority: DownloadPriority;\r\n autoStart: boolean;\r\n sequentialDownload: boolean;\r\n selectedFiles: number[];\r\n }> = {},\r\n ): Torrent | null {\r\n const magnetInfo = parseMagnetUri(magnetUri);\r\n if (!magnetInfo) {\r\n console.error('Invalid magnet URI');\r\n return null;\r\n }\r\n\r\n // Check if already added\r\n if (this.torrents.has(magnetInfo.infoHash)) {\r\n return this.torrents.get(magnetInfo.infoHash)!;\r\n }\r\n\r\n const torrent = this.createTorrent({\r\n infoHash: magnetInfo.infoHash,\r\n name: magnetInfo.displayName ?? 'Unknown Torrent',\r\n size: magnetInfo.exactLength,\r\n trackers: magnetInfo.trackers,\r\n magnetUri,\r\n ...options,\r\n });\r\n\r\n this.torrents.set(torrent.infoHash, torrent);\r\n this.emit({ type: 'added', torrent });\r\n\r\n if (options.autoStart !== false) {\r\n this.startTorrent(torrent.infoHash);\r\n }\r\n\r\n return torrent;\r\n }\r\n\r\n /**\r\n * Adds a torrent from .torrent file data.\r\n */\r\n addTorrentFile(\r\n data: ArrayBuffer,\r\n options: Partial<{\r\n path: string;\r\n priority: DownloadPriority;\r\n autoStart: boolean;\r\n sequentialDownload: boolean;\r\n selectedFiles: number[];\r\n }> = {},\r\n ): Torrent | null {\r\n // In a real implementation, this would parse the bencode data\r\n // For now, we create a mock torrent\r\n const infoHash = generateInfoHash();\r\n\r\n const torrent = this.createTorrent({\r\n infoHash,\r\n name: 'Torrent from file',\r\n ...options,\r\n });\r\n\r\n this.torrents.set(torrent.infoHash, torrent);\r\n this.emit({ type: 'added', torrent });\r\n\r\n if (options.autoStart !== false) {\r\n this.startTorrent(torrent.infoHash);\r\n }\r\n\r\n return torrent;\r\n }\r\n\r\n /**\r\n * Creates a new torrent structure.\r\n */\r\n private createTorrent(params: {\r\n infoHash: string;\r\n name: string;\r\n size?: number;\r\n trackers?: string[];\r\n magnetUri?: string;\r\n path?: string;\r\n priority?: DownloadPriority;\r\n sequentialDownload?: boolean;\r\n selectedFiles?: number[];\r\n }): InternalTorrentState {\r\n const pieceCount = params.size ? calculatePieces(params.size) : 0;\r\n\r\n const trackers: TorrentTracker[] = (params.trackers || this.getDefaultTrackers())\r\n .filter((v, i, a) => a.indexOf(v) === i) // Deduplicate\r\n .map((url, index) => ({\r\n url,\r\n tier: Math.floor(index / 3),\r\n status: 'not_contacted' as const,\r\n seeds: undefined,\r\n leechers: undefined,\r\n }));\r\n\r\n return {\r\n id: `torrent_${Date.now().toString(36)}_${Math.random().toString(36).substring(2, 9)}`,\r\n infoHash: params.infoHash,\r\n name: params.name,\r\n status: 'queued',\r\n priority: params.priority ?? 'normal',\r\n\r\n // Size info\r\n size: params.size ?? 0,\r\n downloadedBytes: 0,\r\n uploadedBytes: 0,\r\n progress: 0,\r\n ratio: 0,\r\n\r\n // Speed\r\n downloadSpeed: formatSpeed(0),\r\n uploadSpeed: formatSpeed(0),\r\n\r\n // Peers\r\n seeds: 0,\r\n peers: 0,\r\n\r\n // Trackers\r\n trackers,\r\n\r\n // Files\r\n files: [],\r\n pieces: createPieceStatus(pieceCount),\r\n\r\n // Configuration\r\n savePath: params.path ?? this.config.downloadPath,\r\n isPrivate: false,\r\n\r\n // Metadata\r\n magnetUri: params.magnetUri,\r\n addedDate: new Date(),\r\n sequentialDownload: params.sequentialDownload ?? false,\r\n selectedFiles: params.selectedFiles ?? [],\r\n };\r\n }\r\n\r\n /**\r\n * Removes a torrent.\r\n */\r\n removeTorrent(infoHash: string, deleteData = false): boolean {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return false;\r\n }\r\n\r\n this.stopTorrent(infoHash);\r\n this.torrents.delete(infoHash);\r\n\r\n this.emit({ type: 'removed', torrent });\r\n\r\n if (deleteData) {\r\n console.warn('Data deletion not implemented in browser environment');\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Gets a torrent by info hash.\r\n */\r\n getTorrent(infoHash: string): Torrent | undefined {\r\n return this.torrents.get(infoHash);\r\n }\r\n\r\n /**\r\n * Gets all torrents.\r\n */\r\n getAllTorrents(): Torrent[] {\r\n return Array.from(this.torrents.values());\r\n }\r\n\r\n /**\r\n * Gets torrents by status.\r\n */\r\n getTorrentsByStatus(status: TorrentStatus): Torrent[] {\r\n return this.getAllTorrents().filter((t) => t.status === status);\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Torrent Control\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Starts a torrent.\r\n */\r\n startTorrent(infoHash: string): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n if (torrent.status === 'downloading' || torrent.status === 'seeding') {\r\n return;\r\n }\r\n\r\n // If no files yet (magnet), try to fetch metadata\r\n if (torrent.files.length === 0 && torrent.magnetUri) {\r\n torrent.status = 'checking'; // Use 'checking' for metadata fetch\r\n this.fetchMetadata(torrent);\r\n } else {\r\n torrent.status = 'downloading';\r\n torrent.startedDate = new Date();\r\n }\r\n\r\n this.emit({ type: 'started', torrent });\r\n this.simulateTorrentProgress(infoHash);\r\n }\r\n\r\n /**\r\n * Pauses a torrent.\r\n */\r\n pauseTorrent(infoHash: string): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n const interval = this.updateIntervals.get(infoHash);\r\n if (interval) {\r\n clearInterval(interval);\r\n this.updateIntervals.delete(infoHash);\r\n }\r\n\r\n torrent.status = 'paused';\r\n torrent.downloadSpeed = formatSpeed(0);\r\n torrent.uploadSpeed = formatSpeed(0);\r\n\r\n this.emit({ type: 'paused', torrent });\r\n }\r\n\r\n /**\r\n * Resumes a torrent.\r\n */\r\n resumeTorrent(infoHash: string): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent || torrent.status !== 'paused') {\r\n return;\r\n }\r\n\r\n torrent.status = torrent.progress >= 100 ? 'seeding' : 'downloading';\r\n this.emit({ type: 'resumed', torrent });\r\n this.simulateTorrentProgress(infoHash);\r\n }\r\n\r\n /**\r\n * Stops a torrent.\r\n */\r\n stopTorrent(infoHash: string): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n const interval = this.updateIntervals.get(infoHash);\r\n if (interval) {\r\n clearInterval(interval);\r\n this.updateIntervals.delete(infoHash);\r\n }\r\n\r\n torrent.status = 'stopped';\r\n torrent.downloadSpeed = formatSpeed(0);\r\n torrent.uploadSpeed = formatSpeed(0);\r\n }\r\n\r\n /**\r\n * Forces recheck of torrent.\r\n */\r\n recheckTorrent(infoHash: string): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n torrent.status = 'checking';\r\n // Simulate recheck\r\n setTimeout(() => {\r\n if (torrent.status === 'checking') {\r\n torrent.status = torrent.progress >= 100 ? 'seeding' : 'queued';\r\n }\r\n }, 2000);\r\n }\r\n\r\n /**\r\n * Force announces to trackers.\r\n */\r\n announceToTrackers(infoHash: string): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n for (const tracker of torrent.trackers) {\r\n tracker.status = 'updating';\r\n // Simulate tracker update\r\n setTimeout(\r\n () => {\r\n tracker.status = 'working';\r\n tracker.lastAnnounce = new Date();\r\n tracker.seeds = Math.floor(Math.random() * 100);\r\n tracker.leechers = Math.floor(Math.random() * 50);\r\n this.emit({ type: 'tracker-update', torrent, tracker });\r\n },\r\n 1000 + Math.random() * 2000,\r\n );\r\n }\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n File Selection\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Sets file priority/selection.\r\n */\r\n setFileSelection(infoHash: string, fileIndex: number, wanted: boolean): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n const file = torrent.files.find((f) => f.index === fileIndex);\r\n if (file) {\r\n file.wanted = wanted;\r\n file.priority = wanted ? 'normal' : 'skip';\r\n\r\n if (torrent.selectedFiles) {\r\n if (wanted && !torrent.selectedFiles.includes(fileIndex)) {\r\n torrent.selectedFiles.push(fileIndex);\r\n } else if (!wanted) {\r\n torrent.selectedFiles = torrent.selectedFiles.filter((i: number) => i !== fileIndex);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Sets priority for a file.\r\n */\r\n setFilePriority(\r\n infoHash: string,\r\n fileIndex: number,\r\n priority: 'skip' | 'low' | 'normal' | 'high',\r\n ): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n const file = torrent.files.find((f) => f.index === fileIndex);\r\n if (file) {\r\n file.priority = priority;\r\n file.wanted = priority !== 'skip';\r\n }\r\n }\r\n\r\n /**\r\n * Selects all files.\r\n */\r\n selectAllFiles(infoHash: string): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n for (const file of torrent.files) {\r\n file.wanted = true;\r\n file.priority = 'normal';\r\n }\r\n if (torrent.selectedFiles !== undefined) {\r\n torrent.selectedFiles = torrent.files.map((f) => f.index);\r\n }\r\n }\r\n\r\n /**\r\n * Deselects all files.\r\n */\r\n deselectAllFiles(infoHash: string): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n for (const file of torrent.files) {\r\n file.wanted = false;\r\n file.priority = 'skip';\r\n }\r\n if (torrent.selectedFiles !== undefined) {\r\n torrent.selectedFiles = [];\r\n }\r\n }\r\n\r\n /**\r\n * Sets sequential download mode.\r\n */\r\n setSequentialDownload(infoHash: string, enabled: boolean): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (torrent) {\r\n torrent.sequentialDownload = enabled;\r\n }\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Configuration\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Gets client configuration.\r\n */\r\n getConfig(): TorrentClientConfig {\r\n return { ...this.config };\r\n }\r\n\r\n /**\r\n * Updates client configuration.\r\n */\r\n updateConfig(updates: Partial<TorrentClientConfig>): void {\r\n this.config = { ...this.config, ...updates };\r\n }\r\n\r\n /**\r\n * Sets download speed limit.\r\n */\r\n setDownloadLimit(bytesPerSecond: number | undefined): void {\r\n if (bytesPerSecond !== undefined) {\r\n this.config.bandwidthLimit = {\r\n ...this.config.bandwidthLimit,\r\n download: bytesPerSecond,\r\n enabled: true,\r\n };\r\n } else {\r\n this.config.bandwidthLimit = {\r\n ...this.config.bandwidthLimit,\r\n download: undefined,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Sets upload speed limit.\r\n */\r\n setUploadLimit(bytesPerSecond: number | undefined): void {\r\n if (bytesPerSecond !== undefined) {\r\n this.config.bandwidthLimit = {\r\n ...this.config.bandwidthLimit,\r\n upload: bytesPerSecond,\r\n enabled: true,\r\n };\r\n } else {\r\n this.config.bandwidthLimit = {\r\n ...this.config.bandwidthLimit,\r\n upload: undefined,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Enables or disables DHT.\r\n */\r\n setDHTEnabled(enabled: boolean): void {\r\n this.config.dhtEnabled = enabled;\r\n if (enabled) {\r\n this.initDHT();\r\n }\r\n }\r\n\r\n /**\r\n * Enables or disables PEX.\r\n */\r\n setPEXEnabled(enabled: boolean): void {\r\n this.config.pexEnabled = enabled;\r\n if (enabled) {\r\n this.initPEX();\r\n }\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Statistics\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Gets overall client statistics.\r\n */\r\n getStatistics(): TorrentDashboardStats {\r\n const torrents = this.getAllTorrents();\r\n\r\n let totalDownload = 0;\r\n let totalUpload = 0;\r\n let downloadSpeedSum = 0;\r\n let uploadSpeedSum = 0;\r\n let totalPeers = 0;\r\n\r\n for (const t of torrents) {\r\n totalDownload += t.downloadedBytes;\r\n totalUpload += t.uploadedBytes;\r\n downloadSpeedSum += t.downloadSpeed.bytesPerSecond;\r\n uploadSpeedSum += t.uploadSpeed.bytesPerSecond;\r\n totalPeers += t.peers;\r\n }\r\n\r\n return {\r\n activeSeeders: torrents.filter((t) => t.status === 'seeding').length,\r\n activeDownloads: torrents.filter((t) => t.status === 'downloading').length,\r\n totalDownloaded: totalDownload,\r\n totalUploaded: totalUpload,\r\n downloadSpeed: formatSpeed(downloadSpeedSum),\r\n uploadSpeed: formatSpeed(uploadSpeedSum),\r\n globalRatio: totalDownload > 0 ? totalUpload / totalDownload : 0,\r\n dhtNodes: this.config.dhtEnabled ? Math.floor(Math.random() * 500 + 100) : 0,\r\n totalPeers,\r\n sessionDuration: 0, // Would track actual session time\r\n };\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Private Methods\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Gets default trackers.\r\n */\r\n private getDefaultTrackers(): string[] {\r\n return [\r\n 'udp://tracker.opentrackr.org:1337/announce',\r\n 'udp://tracker.openbittorrent.com:6969/announce',\r\n 'udp://open.stealth.si:80/announce',\r\n 'udp://tracker.torrent.eu.org:451/announce',\r\n ];\r\n }\r\n\r\n /**\r\n * Initializes DHT.\r\n */\r\n private initDHT(): void {\r\n console.log('DHT initialized');\r\n }\r\n\r\n /**\r\n * Initializes PEX.\r\n */\r\n private initPEX(): void {\r\n console.log('PEX initialized');\r\n }\r\n\r\n /**\r\n * Fetches torrent metadata from magnet.\r\n */\r\n private fetchMetadata(torrent: InternalTorrentState): void {\r\n // Simulate metadata fetch\r\n setTimeout(\r\n () => {\r\n if (torrent.status !== 'checking') {\r\n return;\r\n }\r\n\r\n // Create mock files\r\n torrent.files = [\r\n {\r\n index: 0,\r\n name: `${torrent.name}.mkv`,\r\n path: `${torrent.name}/${torrent.name}.mkv`,\r\n size: Math.floor(Math.random() * 2000000000) + 500000000, // 500MB - 2.5GB\r\n progress: 0,\r\n downloaded: 0,\r\n priority: 'normal',\r\n wanted: true,\r\n },\r\n {\r\n index: 1,\r\n name: 'sample.mp4',\r\n path: `${torrent.name}/sample.mp4`,\r\n size: Math.floor(Math.random() * 50000000) + 10000000, // 10-60MB\r\n progress: 0,\r\n downloaded: 0,\r\n priority: 'normal',\r\n wanted: true,\r\n },\r\n {\r\n index: 2,\r\n name: 'readme.txt',\r\n path: `${torrent.name}/readme.txt`,\r\n size: 1024,\r\n progress: 0,\r\n downloaded: 0,\r\n priority: 'low',\r\n wanted: true,\r\n },\r\n ];\r\n\r\n torrent.size = torrent.files.reduce((sum, f) => sum + f.size, 0);\r\n torrent.selectedFiles = torrent.files.map((f) => f.index);\r\n torrent.pieces = createPieceStatus(calculatePieces(torrent.size));\r\n torrent.status = 'downloading';\r\n\r\n this.emit({ type: 'metadata', torrent });\r\n this.emit({ type: 'started', torrent });\r\n },\r\n 2000 + Math.random() * 3000,\r\n );\r\n }\r\n\r\n /**\r\n * Simulates torrent progress for demo purposes.\r\n */\r\n private simulateTorrentProgress(infoHash: string): void {\r\n if (this.updateIntervals.has(infoHash)) {\r\n clearInterval(this.updateIntervals.get(infoHash)!);\r\n }\r\n\r\n const interval = setInterval(() => {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n clearInterval(interval);\r\n return;\r\n }\r\n\r\n if (torrent.status !== 'downloading' && torrent.status !== 'seeding') {\r\n return;\r\n }\r\n\r\n // Simulate download progress\r\n if (torrent.status === 'downloading' && torrent.size > 0) {\r\n const baseSpeed = 1000000 + Math.random() * 5000000; // 1-6 MB/s\r\n const downloadSpeed = this.config.bandwidthLimit.download\r\n ? Math.min(baseSpeed, this.config.bandwidthLimit.download)\r\n : baseSpeed;\r\n\r\n const increment = downloadSpeed * (1 + Math.random() * 0.5);\r\n torrent.downloadedBytes = Math.min(torrent.downloadedBytes + increment, torrent.size);\r\n torrent.progress = (torrent.downloadedBytes / torrent.size) * 100;\r\n torrent.downloadSpeed = formatSpeed(downloadSpeed);\r\n torrent.uploadSpeed = formatSpeed(downloadSpeed * 0.1 * Math.random());\r\n\r\n // Update file progress\r\n for (const file of torrent.files) {\r\n if (file.wanted) {\r\n file.downloaded = Math.min(\r\n file.downloaded + increment * (file.size / torrent.size),\r\n file.size,\r\n );\r\n file.progress = (file.downloaded / file.size) * 100;\r\n }\r\n }\r\n\r\n // Simulate peers\r\n torrent.peers = Math.floor(Math.random() * 30) + 5;\r\n torrent.seeds = Math.floor(torrent.peers * 0.6);\r\n\r\n // Calculate ETA\r\n torrent.eta = calculateETA(torrent.size - torrent.downloadedBytes, downloadSpeed);\r\n\r\n this.emit({ type: 'progress', torrent });\r\n\r\n // Check if complete\r\n if (torrent.progress >= 100) {\r\n torrent.status = 'seeding';\r\n torrent.completedDate = new Date();\r\n torrent.progress = 100;\r\n torrent.downloadedBytes = torrent.size;\r\n this.emit({ type: 'completed', torrent });\r\n this.emit({ type: 'seeding', torrent });\r\n }\r\n }\r\n\r\n // Simulate seeding\r\n if (torrent.status === 'seeding') {\r\n const uploadSpeed = 500000 + Math.random() * 2000000; // 0.5-2.5 MB/s\r\n torrent.uploadedBytes += uploadSpeed;\r\n torrent.uploadSpeed = formatSpeed(uploadSpeed);\r\n torrent.downloadSpeed = formatSpeed(0);\r\n torrent.ratio = torrent.size > 0 ? torrent.uploadedBytes / torrent.size : 0;\r\n\r\n torrent.peers = Math.floor(Math.random() * 10) + 1;\r\n torrent.seeds = 0;\r\n }\r\n }, 1000);\r\n\r\n this.updateIntervals.set(infoHash, interval);\r\n }\r\n\r\n /**\r\n * Disposes the client.\r\n */\r\n dispose(): void {\r\n for (const interval of this.updateIntervals.values()) {\r\n clearInterval(interval);\r\n }\r\n this.updateIntervals.clear();\r\n this.torrents.clear();\r\n this.eventListeners.clear();\r\n }\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Torrent Creator\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\nexport interface CreateTorrentOptions {\r\n name: string;\r\n files: File[];\r\n trackers?: string[];\r\n comment?: string;\r\n isPrivate?: boolean;\r\n pieceSize?: number;\r\n webSeeds?: string[];\r\n source?: string;\r\n}\r\n\r\n/**\r\n * Creates a .torrent file (bencode output).\r\n *\r\n * Note: This is a simplified implementation. A full implementation would\r\n * use the bencode library and calculate proper piece hashes.\r\n */\r\nexport async function createTorrent(options: CreateTorrentOptions): Promise<CreatedTorrent> {\r\n const {\r\n name,\r\n files,\r\n trackers = [],\r\n comment,\r\n isPrivate = false,\r\n pieceSize = 262144,\r\n webSeeds = [],\r\n } = options;\r\n\r\n // Calculate total size\r\n const totalSize = files.reduce((sum, f) => sum + f.size, 0);\r\n\r\n // Generate mock info hash\r\n const infoHash = generateInfoHash();\r\n const pieceCount = calculatePieces(totalSize, pieceSize);\r\n\r\n // Create magnet URI\r\n const magnetLink = createMagnetUri({ infoHash, name, trackers, size: totalSize });\r\n\r\n // In a real implementation, we would bencode the torrent dict\r\n // For now, return a placeholder Uint8Array\r\n const encoder = new TextEncoder();\r\n const torrentFile = encoder.encode(\r\n JSON.stringify({\r\n announce: trackers[0] || '',\r\n info: {\r\n name,\r\n 'piece length': pieceSize,\r\n length: totalSize,\r\n private: isPrivate ? 1 : 0,\r\n },\r\n comment,\r\n 'url-list': webSeeds,\r\n }),\r\n );\r\n\r\n return {\r\n infoHash,\r\n magnetLink,\r\n torrentFile,\r\n size: totalSize,\r\n pieceCount,\r\n pieceSize,\r\n };\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Singleton Instance\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\nlet torrentClientInstance: TorrentClient | null = null;\r\n\r\n/**\r\n * Gets or creates the torrent client singleton.\r\n */\r\nexport function getTorrentClient(config?: Partial<TorrentClientConfig>): TorrentClient {\r\n if (!torrentClientInstance) {\r\n torrentClientInstance = new TorrentClient(config);\r\n }\r\n return torrentClientInstance;\r\n}\r\n\r\n/**\r\n * Disposes the torrent client singleton.\r\n */\r\nexport function disposeTorrentClient(): void {\r\n torrentClientInstance?.dispose();\r\n torrentClientInstance = null;\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n React Hook\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\nimport { useState, useEffect, useCallback, useMemo } from 'react';\r\n\r\nexport interface UseTorrentClientOptions {\r\n config?: Partial<TorrentClientConfig>;\r\n autoRefresh?: boolean;\r\n refreshInterval?: number;\r\n}\r\n\r\nexport interface UseTorrentClientReturn {\r\n /** All torrents */\r\n torrents: Torrent[];\r\n /** Client statistics */\r\n statistics: TorrentDashboardStats;\r\n /** Active torrents */\r\n activeTorrents: Torrent[];\r\n /** Add magnet */\r\n addMagnet: (uri: string, options?: Parameters<TorrentClient['addMagnet']>[1]) => Torrent | null;\r\n /** Add torrent file */\r\n addTorrentFile: (\r\n data: ArrayBuffer,\r\n options?: Parameters<TorrentClient['addTorrentFile']>[1],\r\n ) => Torrent | null;\r\n /** Remove torrent */\r\n removeTorrent: (infoHash: string, deleteData?: boolean) => void;\r\n /** Start torrent */\r\n startTorrent: (infoHash: string) => void;\r\n /** Pause torrent */\r\n pauseTorrent: (infoHash: string) => void;\r\n /** Resume torrent */\r\n resumeTorrent: (infoHash: string) => void;\r\n /** Stop torrent */\r\n stopTorrent: (infoHash: string) => void;\r\n /** Set file selection */\r\n setFileSelection: (infoHash: string, fileIndex: number, wanted: boolean) => void;\r\n /** Set sequential download */\r\n setSequentialDownload: (infoHash: string, enabled: boolean) => void;\r\n /** Set download limit */\r\n setDownloadLimit: (bytesPerSecond: number | undefined) => void;\r\n /** Set upload limit */\r\n setUploadLimit: (bytesPerSecond: number | undefined) => void;\r\n /** Create torrent */\r\n createTorrent: typeof createTorrent;\r\n}\r\n\r\n/**\r\n * React hook for torrent client.\r\n */\r\nexport function useTorrentClient(options: UseTorrentClientOptions = {}): UseTorrentClientReturn {\r\n const { config, autoRefresh = true, refreshInterval = 1000 } = options;\r\n\r\n const client = useMemo(() => getTorrentClient(config), [config]);\r\n\r\n const [torrents, setTorrents] = useState<Torrent[]>(client.getAllTorrents());\r\n const [statistics, setStatistics] = useState<TorrentDashboardStats>(client.getStatistics());\r\n\r\n useEffect(() => {\r\n const handleUpdate = () => {\r\n setTorrents([...client.getAllTorrents()]);\r\n setStatistics(client.getStatistics());\r\n };\r\n\r\n const unsubscribers = [\r\n client.on('added', handleUpdate),\r\n client.on('metadata', handleUpdate),\r\n client.on('started', handleUpdate),\r\n client.on('progress', handleUpdate),\r\n client.on('paused', handleUpdate),\r\n client.on('resumed', handleUpdate),\r\n client.on('completed', handleUpdate),\r\n client.on('seeding', handleUpdate),\r\n client.on('failed', handleUpdate),\r\n client.on('removed', handleUpdate),\r\n ];\r\n\r\n // Auto-refresh\r\n let interval: ReturnType<typeof setInterval> | undefined;\r\n if (autoRefresh) {\r\n interval = setInterval(() => {\r\n if (\r\n client.getStatistics().activeDownloads > 0 ||\r\n client.getStatistics().activeSeeders > 0\r\n ) {\r\n handleUpdate();\r\n }\r\n }, refreshInterval);\r\n }\r\n\r\n return () => {\r\n unsubscribers.forEach((unsub) => unsub());\r\n if (interval) {\r\n clearInterval(interval);\r\n }\r\n };\r\n }, [client, autoRefresh, refreshInterval]);\r\n\r\n const activeTorrents = useMemo(\r\n () => torrents.filter((t) => t.status === 'downloading' || t.status === 'seeding'),\r\n [torrents],\r\n );\r\n\r\n return {\r\n torrents,\r\n statistics,\r\n activeTorrents,\r\n addMagnet: useCallback((uri, opts) => client.addMagnet(uri, opts), [client]),\r\n addTorrentFile: useCallback((data, opts) => client.addTorrentFile(data, opts), [client]),\r\n removeTorrent: useCallback((hash, del) => client.removeTorrent(hash, del), [client]),\r\n startTorrent: useCallback((hash) => client.startTorrent(hash), [client]),\r\n pauseTorrent: useCallback((hash) => client.pauseTorrent(hash), [client]),\r\n resumeTorrent: useCallback((hash) => client.resumeTorrent(hash), [client]),\r\n stopTorrent: useCallback((hash) => client.stopTorrent(hash), [client]),\r\n setFileSelection: useCallback(\r\n (hash, idx, w) => client.setFileSelection(hash, idx, w),\r\n [client],\r\n ),\r\n setSequentialDownload: useCallback(\r\n (hash, en) => client.setSequentialDownload(hash, en),\r\n [client],\r\n ),\r\n setDownloadLimit: useCallback((lim) => client.setDownloadLimit(lim), [client]),\r\n setUploadLimit: useCallback((lim) => client.setUploadLimit(lim), [client]),\r\n createTorrent,\r\n };\r\n}\r\n","/**\r\n * @fileoverview SEC-008: Traceless™ — Zero-Trace Privacy Architecture\r\n *\r\n * \"Your ERP. Zero traces. No cookie banners. Ever.\"\r\n *\r\n * This module provides TypeScript types and interfaces for the Traceless™\r\n * privacy architecture - a flagship feature that allows enterprise applications\r\n * to operate with zero client-side storage when required.\r\n *\r\n * @module @nice2dev/ui-tools/traceless\r\n */\r\n\r\n// =============================================================================\r\n// PRIVACY MODES\r\n// =============================================================================\r\n\r\n/**\r\n * Privacy mode levels from most restrictive to least restrictive.\r\n *\r\n * - `traceless`: Zero client-side storage. In-memory only. Full privacy.\r\n * - `ephemeral`: sessionStorage only. Cleared on tab close.\r\n * - `private`: sessionStorage + 1 httpOnly auth cookie.\r\n * - `balanced`: sessionStorage + localStorage. No cookies.\r\n * - `full`: All storage types including cookies. Requires consent banner.\r\n * - `custom`: Manually configured storage permissions.\r\n */\r\nexport type TracelessMode = 'traceless' | 'ephemeral' | 'private' | 'balanced' | 'full' | 'custom';\r\n\r\n/**\r\n * Storage capability flags for granular control.\r\n */\r\nexport interface StorageCapabilities {\r\n /** Whether cookies are allowed */\r\n cookiesAllowed: boolean;\r\n /** Whether localStorage is allowed */\r\n localStorageAllowed: boolean;\r\n /** Whether sessionStorage is allowed */\r\n sessionStorageAllowed: boolean;\r\n /** Whether IndexedDB is allowed */\r\n indexedDBAllowed?: boolean;\r\n /** Whether Web SQL is allowed (deprecated but still used) */\r\n webSQLAllowed?: boolean;\r\n /** Whether Service Workers can cache data */\r\n serviceWorkerCacheAllowed?: boolean;\r\n}\r\n\r\n/**\r\n * Main Traceless Policy interface - injected per-request.\r\n */\r\nexport interface ITracelessPolicy extends StorageCapabilities {\r\n /** Effective mode after resolution */\r\n effectiveMode: TracelessMode;\r\n /** Whether consent banner is required */\r\n consentRequired: boolean;\r\n /** Whether any form of persistence is allowed */\r\n canPersist: boolean;\r\n /** Source of the policy (instance, tenant, group, user) */\r\n policySource: PolicySource;\r\n /** Timestamp when policy was resolved */\r\n resolvedAt: string;\r\n /** Cache TTL in seconds */\r\n cacheTTL?: number;\r\n}\r\n\r\n/**\r\n * Source of the privacy policy in the hierarchy.\r\n */\r\nexport type PolicySource = 'instance' | 'tenant' | 'group' | 'user' | 'module' | 'computed';\r\n\r\n// =============================================================================\r\n// POLICY HIERARCHY\r\n// =============================================================================\r\n\r\n/**\r\n * Instance-level ceiling - the maximum permissions any tenant can have.\r\n */\r\nexport interface InstanceStorageCeiling {\r\n /** Maximum cookies permission for the instance */\r\n maxCookies: boolean;\r\n /** Maximum localStorage permission for the instance */\r\n maxLocalStorage: boolean;\r\n /** Maximum sessionStorage permission for the instance */\r\n maxSessionStorage: boolean;\r\n /** Maximum IndexedDB permission */\r\n maxIndexedDB?: boolean;\r\n /** Description of why ceiling is set this way */\r\n reason?: string;\r\n /** Who set this ceiling */\r\n configuredBy?: string;\r\n /** When ceiling was last modified */\r\n lastModified?: string;\r\n}\r\n\r\n/**\r\n * Tenant-level policy configuration.\r\n */\r\nexport interface TenantStoragePolicy {\r\n /** Tenant identifier */\r\n tenantId: string;\r\n /** Tenant's chosen privacy mode (must be <= instance ceiling) */\r\n mode: TracelessMode;\r\n /** Override for cookies (cannot exceed instance ceiling) */\r\n cookiesAllowed?: boolean;\r\n /** Override for localStorage (cannot exceed instance ceiling) */\r\n localStorageAllowed?: boolean;\r\n /** Override for sessionStorage (cannot exceed instance ceiling) */\r\n sessionStorageAllowed?: boolean;\r\n /** Default mode for new users */\r\n defaultUserMode?: TracelessMode;\r\n /** Whether users can adjust their privacy level */\r\n userAdjustmentAllowed: boolean;\r\n /** Minimum mode users must have (cannot go more permissive) */\r\n minimumUserMode?: TracelessMode;\r\n}\r\n\r\n/**\r\n * User group policy configuration.\r\n */\r\nexport interface GroupStoragePolicy {\r\n /** Group identifier */\r\n groupId: string;\r\n /** Group name for display */\r\n groupName: string;\r\n /** Privacy mode for this group */\r\n mode: TracelessMode;\r\n /** Custom storage capabilities for the group */\r\n capabilities?: Partial<StorageCapabilities>;\r\n /** Whether users in this group can adjust their level */\r\n userAdjustmentAllowed: boolean;\r\n /** Priority when user belongs to multiple groups */\r\n priority: number;\r\n}\r\n\r\n/**\r\n * User-level privacy preferences (self-lockdown).\r\n */\r\nexport interface UserPrivacyPreferences {\r\n /** User identifier */\r\n userId: string;\r\n /** User's chosen mode (can only be more restrictive than group) */\r\n mode: TracelessMode;\r\n /** Custom restrictions */\r\n restrictions?: Partial<StorageCapabilities>;\r\n /** When user last modified their preferences */\r\n lastModified: string;\r\n /** Device-specific overrides */\r\n deviceOverrides?: Record<string, TracelessMode>;\r\n}\r\n\r\n/**\r\n * Module minimum storage requirements.\r\n */\r\nexport interface ModuleStorageRequirement {\r\n /** Module identifier */\r\n moduleId: string;\r\n /** Module name */\r\n moduleName: string;\r\n /** Minimum storage needed for basic functionality */\r\n minStorageRequirement: Partial<StorageCapabilities>;\r\n /** Features that degrade gracefully without storage */\r\n degradableFeatures: DegradableFeature[];\r\n /** Features that are completely disabled without storage */\r\n disabledFeatures: string[];\r\n /** Warning message when storage is insufficient */\r\n insufficientStorageWarning?: string;\r\n}\r\n\r\n/**\r\n * A feature that can work with reduced functionality.\r\n */\r\nexport interface DegradableFeature {\r\n /** Feature identifier */\r\n featureId: string;\r\n /** Feature name */\r\n name: string;\r\n /** Description of full functionality */\r\n fullDescription: string;\r\n /** Description of degraded functionality */\r\n degradedDescription: string;\r\n /** What storage is needed for full functionality */\r\n requiredStorage: Partial<StorageCapabilities>;\r\n /** Impact level when degraded */\r\n degradedImpact: 'minor' | 'moderate' | 'significant';\r\n}\r\n\r\n// =============================================================================\r\n// POLICY RESOLUTION\r\n// =============================================================================\r\n\r\n/**\r\n * Policy resolution request.\r\n */\r\nexport interface PolicyResolutionRequest {\r\n /** Tenant context */\r\n tenantId?: string;\r\n /** User context */\r\n userId?: string;\r\n /** Device identifier for device-specific policies */\r\n deviceId?: string;\r\n /** Module requesting the policy */\r\n moduleId?: string;\r\n /** Whether to include detailed resolution trace */\r\n includeTrace?: boolean;\r\n}\r\n\r\n/**\r\n * Policy resolution response with computed policy.\r\n */\r\nexport interface PolicyResolutionResponse {\r\n /** The computed effective policy */\r\n policy: ITracelessPolicy;\r\n /** Resolution trace showing how policy was computed */\r\n trace?: PolicyResolutionTrace;\r\n /** Warnings about capability limitations */\r\n warnings?: PolicyWarning[];\r\n /** Cache key for this resolution */\r\n cacheKey?: string;\r\n}\r\n\r\n/**\r\n * Trace of how policy was resolved through the hierarchy.\r\n */\r\nexport interface PolicyResolutionTrace {\r\n /** Instance ceiling that was applied */\r\n instanceCeiling: InstanceStorageCeiling;\r\n /** Tenant policy that was applied */\r\n tenantPolicy?: TenantStoragePolicy;\r\n /** Group policies that were considered (in priority order) */\r\n groupPolicies?: GroupStoragePolicy[];\r\n /** User preferences that were applied */\r\n userPreferences?: UserPrivacyPreferences;\r\n /** Module requirements that were checked */\r\n moduleRequirements?: ModuleStorageRequirement[];\r\n /** Final computed result */\r\n computedResult: ITracelessPolicy;\r\n /** Resolution timestamp */\r\n resolvedAt: string;\r\n}\r\n\r\n/**\r\n * Warning about policy limitations.\r\n */\r\nexport interface PolicyWarning {\r\n /** Warning code */\r\n code: string;\r\n /** Warning message */\r\n message: string;\r\n /** Severity of the warning */\r\n severity: 'info' | 'warning' | 'error';\r\n /** Affected module or feature */\r\n affectedModule?: string;\r\n /** Suggestion for resolution */\r\n suggestion?: string;\r\n}\r\n\r\n// =============================================================================\r\n// STORAGE ADAPTER\r\n// =============================================================================\r\n\r\n/**\r\n * Storage backend types.\r\n */\r\nexport type StorageBackend = 'memory' | 'sessionStorage' | 'localStorage' | 'indexedDB' | 'cookie';\r\n\r\n/**\r\n * Unified Storage Adapter interface for all platforms.\r\n */\r\nexport interface IStorageAdapter {\r\n /** Get a value by key */\r\n get<T = unknown>(key: string): T | null;\r\n /** Get a value asynchronously (for IndexedDB) */\r\n getAsync<T = unknown>(key: string): Promise<T | null>;\r\n /** Set a value */\r\n set<T = unknown>(key: string, value: T): void;\r\n /** Set a value asynchronously */\r\n setAsync<T = unknown>(key: string, value: T): Promise<void>;\r\n /** Remove a value */\r\n remove(key: string): void;\r\n /** Remove a value asynchronously */\r\n removeAsync(key: string): Promise<void>;\r\n /** Clear all values (within namespace) */\r\n clear(): void;\r\n /** Clear all values asynchronously */\r\n clearAsync(): Promise<void>;\r\n /** Check if a key exists */\r\n has(key: string): boolean;\r\n /** Get all keys (within namespace) */\r\n keys(): string[];\r\n /** Get the current storage backend being used */\r\n getCurrentBackend(): StorageBackend;\r\n /** Check if storage is available */\r\n isAvailable(): boolean;\r\n}\r\n\r\n/**\r\n * Storage adapter configuration.\r\n */\r\nexport interface StorageAdapterConfig {\r\n /** Namespace prefix for all keys */\r\n namespace: string;\r\n /** Policy to respect */\r\n policy: ITracelessPolicy;\r\n /** Preferred backend (will fallback if not available) */\r\n preferredBackend?: StorageBackend;\r\n /** Whether to encrypt values */\r\n encrypt?: boolean;\r\n /** Encryption key (required if encrypt is true) */\r\n encryptionKey?: string;\r\n /** Default TTL for values in seconds */\r\n defaultTTL?: number;\r\n /** Event handlers */\r\n onStorageUnavailable?: (requestedBackend: StorageBackend) => void;\r\n onValueExpired?: (key: string) => void;\r\n onPolicyViolation?: (operation: string, requestedBackend: StorageBackend) => void;\r\n}\r\n\r\n/**\r\n * Storage item with metadata.\r\n */\r\nexport interface StorageItem<T = unknown> {\r\n /** The stored value */\r\n value: T;\r\n /** When the item was created */\r\n createdAt: string;\r\n /** When the item was last accessed */\r\n lastAccessedAt?: string;\r\n /** When the item expires (if applicable) */\r\n expiresAt?: string;\r\n /** Which backend is storing this item */\r\n backend: StorageBackend;\r\n /** Whether the item is encrypted */\r\n encrypted: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// REACT INTEGRATION\r\n// =============================================================================\r\n\r\n/**\r\n * React hook return type for useTracelessPolicy.\r\n */\r\nexport interface UseTracelessPolicyResult extends ITracelessPolicy {\r\n /** Whether policy is still loading */\r\n isLoading: boolean;\r\n /** Error if policy couldn't be loaded */\r\n error: Error | null;\r\n /** Refresh the policy */\r\n refresh: () => Promise<void>;\r\n /** Check if a specific operation is allowed */\r\n isAllowed: (operation: StorageOperation) => boolean;\r\n}\r\n\r\n/**\r\n * Storage operations that can be checked.\r\n */\r\nexport type StorageOperation =\r\n | 'setCookie'\r\n | 'readCookie'\r\n | 'setLocalStorage'\r\n | 'readLocalStorage'\r\n | 'setSessionStorage'\r\n | 'readSessionStorage'\r\n | 'useIndexedDB'\r\n | 'useServiceWorker';\r\n\r\n/**\r\n * Props for traceless-aware components.\r\n */\r\nexport interface TracelessAwareProps {\r\n /** Whether this component can use cookies */\r\n cookies?: boolean;\r\n /** Whether this component can use localStorage */\r\n localStorage?: boolean;\r\n /** Storage mode override */\r\n storageMode?: 'traceless' | 'ephemeral' | 'persistent' | 'auto';\r\n}\r\n\r\n/**\r\n * Context value for TracelessProvider.\r\n */\r\nexport interface TracelessContextValue {\r\n /** Current policy */\r\n policy: ITracelessPolicy;\r\n /** Storage adapter instance */\r\n storageAdapter: IStorageAdapter;\r\n /** Update user preferences */\r\n updatePreferences: (prefs: Partial<UserPrivacyPreferences>) => Promise<void>;\r\n /** Check if mode change is allowed */\r\n canChangeTo: (mode: TracelessMode) => boolean;\r\n}\r\n\r\n// =============================================================================\r\n// FLUTTER INTEGRATION\r\n// =============================================================================\r\n\r\n/**\r\n * Flutter storage adapter configuration.\r\n */\r\nexport interface FlutterStorageAdapterConfig {\r\n /** Namespace for SharedPreferences keys */\r\n namespace: string;\r\n /** Policy to respect */\r\n policy: ITracelessPolicy;\r\n /** Use flutter_secure_storage for sensitive data */\r\n useSecureStorage: boolean;\r\n /** Use Hive for complex data structures */\r\n useHive: boolean;\r\n /** Hive box name */\r\n hiveBoxName?: string;\r\n}\r\n\r\n// =============================================================================\r\n// COMPONENT-SPECIFIC STORAGE\r\n// =============================================================================\r\n\r\n/**\r\n * Storage scope for different component types.\r\n */\r\nexport interface ComponentStorageScope {\r\n /** Component type identifier */\r\n componentType: string;\r\n /** What data this component wants to store */\r\n dataCategories: ComponentDataCategory[];\r\n /** Required storage for basic functionality */\r\n requiredStorage: Partial<StorageCapabilities>;\r\n /** Behavior when storage is restricted */\r\n restrictedBehavior: RestrictedBehavior;\r\n}\r\n\r\n/**\r\n * Categories of data components might store.\r\n */\r\nexport type ComponentDataCategory =\r\n | 'layout' // Column widths, panel sizes\r\n | 'filters' // Filter states, search terms\r\n | 'sorting' // Sort column and direction\r\n | 'selection' // Selected items\r\n | 'view' // Current view mode\r\n | 'draft' // Unsaved content\r\n | 'preferences' // User preferences\r\n | 'history' // Action history\r\n | 'cache' // Performance cache\r\n | 'session' // Session state\r\n | 'auth'; // Authentication data\r\n\r\n/**\r\n * How component behaves when storage is restricted.\r\n */\r\nexport interface RestrictedBehavior {\r\n /** Behavior in traceless mode */\r\n traceless: GracefulDegradation;\r\n /** Behavior in ephemeral mode */\r\n ephemeral: GracefulDegradation;\r\n /** Behavior in private mode */\r\n private: GracefulDegradation;\r\n}\r\n\r\n/**\r\n * Graceful degradation configuration.\r\n */\r\nexport interface GracefulDegradation {\r\n /** What features work */\r\n availableFeatures: string[];\r\n /** What features are disabled */\r\n disabledFeatures: string[];\r\n /** Warning message to show user */\r\n userWarning?: string;\r\n /** Default values to use */\r\n defaults: Record<string, unknown>;\r\n}\r\n\r\n// =============================================================================\r\n// SPECIFIC COMPONENT CONFIGS\r\n// =============================================================================\r\n\r\n/**\r\n * NiceDataGrid storage config.\r\n */\r\nexport interface DataGridStorageConfig extends TracelessAwareProps {\r\n /** What to store */\r\n persist?: {\r\n columnOrder?: boolean;\r\n columnWidths?: boolean;\r\n sortState?: boolean;\r\n filterState?: boolean;\r\n pageSize?: boolean;\r\n hiddenColumns?: boolean;\r\n };\r\n /** Storage key for this grid instance */\r\n storageKey?: string;\r\n}\r\n\r\n/**\r\n * NiceKanban storage config.\r\n */\r\nexport interface KanbanStorageConfig extends TracelessAwareProps {\r\n /** What to store */\r\n persist?: {\r\n collapsedColumns?: boolean;\r\n swimlaneState?: boolean;\r\n filterState?: boolean;\r\n scrollPosition?: boolean;\r\n };\r\n /** Storage key for this board instance */\r\n storageKey?: string;\r\n}\r\n\r\n/**\r\n * NiceRichTextEditor storage config.\r\n */\r\nexport interface RichTextEditorStorageConfig extends TracelessAwareProps {\r\n /** Auto-save draft configuration */\r\n autosave?: {\r\n enabled: boolean;\r\n intervalMs: number;\r\n maxDrafts: number;\r\n };\r\n /** Storage key for drafts */\r\n draftKey?: string;\r\n /** Warning when draft might be lost */\r\n showDraftLossWarning?: boolean;\r\n}\r\n\r\n/**\r\n * NiceCalendar storage config.\r\n */\r\nexport interface CalendarStorageConfig extends TracelessAwareProps {\r\n /** What to store */\r\n persist?: {\r\n viewMode?: boolean;\r\n selectedDate?: boolean;\r\n timezone?: boolean;\r\n hiddenCalendars?: boolean;\r\n };\r\n /** Fall back to these defaults when no storage */\r\n defaults?: {\r\n viewMode?: 'day' | 'week' | 'month' | 'year';\r\n showWeekends?: boolean;\r\n };\r\n}\r\n\r\n/**\r\n * NiceLoginForm storage config.\r\n */\r\nexport interface LoginFormStorageConfig extends TracelessAwareProps {\r\n /** Whether \"Remember me\" option is shown */\r\n showRememberMe?: boolean;\r\n /** Whether to remember username */\r\n rememberUsername?: boolean;\r\n /** Cookie expiration for \"Remember me\" in days */\r\n rememberMeDays?: number;\r\n}\r\n\r\n// =============================================================================\r\n// CONSENT MANAGEMENT\r\n// =============================================================================\r\n\r\n/**\r\n * Consent state for cookie/storage usage.\r\n */\r\nexport interface ConsentState {\r\n /** Whether any consent has been given */\r\n hasConsent: boolean;\r\n /** Consent version (for managing consent changes) */\r\n consentVersion: string;\r\n /** When consent was last updated */\r\n consentUpdatedAt: string;\r\n /** Granular consent choices */\r\n choices: ConsentChoices;\r\n}\r\n\r\n/**\r\n * Granular consent choices.\r\n */\r\nexport interface ConsentChoices {\r\n /** Strictly necessary (cannot be disabled) */\r\n necessary: true;\r\n /** Functional cookies */\r\n functional?: boolean;\r\n /** Analytics cookies */\r\n analytics?: boolean;\r\n /** Marketing/targeting cookies */\r\n marketing?: boolean;\r\n /** Third-party cookies */\r\n thirdParty?: boolean;\r\n /** Custom consent categories */\r\n custom?: Record<string, boolean>;\r\n}\r\n\r\n/**\r\n * Consent panel configuration.\r\n */\r\nexport interface ConsentPanelConfig {\r\n /** Privacy mode determines if panel is shown */\r\n policyMode: TracelessMode;\r\n /** Available consent categories */\r\n categories: ConsentCategory[];\r\n /** Privacy policy URL */\r\n privacyPolicyUrl?: string;\r\n /** Cookie policy URL */\r\n cookiePolicyUrl?: string;\r\n /** Position of the banner */\r\n position?: 'top' | 'bottom' | 'center';\r\n /** Theme */\r\n theme?: 'light' | 'dark' | 'auto';\r\n /** Text customization */\r\n text?: ConsentPanelText;\r\n}\r\n\r\n/**\r\n * Consent category definition.\r\n */\r\nexport interface ConsentCategory {\r\n /** Category identifier */\r\n id: string;\r\n /** Display name */\r\n name: string;\r\n /** Description */\r\n description: string;\r\n /** Whether category is required */\r\n required: boolean;\r\n /** Default state if not required */\r\n defaultEnabled?: boolean;\r\n /** Cookies/storage used by this category */\r\n items?: ConsentItem[];\r\n}\r\n\r\n/**\r\n * Individual consent item (cookie or storage key).\r\n */\r\nexport interface ConsentItem {\r\n /** Item name */\r\n name: string;\r\n /** Provider/domain */\r\n provider: string;\r\n /** Purpose */\r\n purpose: string;\r\n /** Expiry */\r\n expiry?: string;\r\n /** Type */\r\n type: 'cookie' | 'localStorage' | 'sessionStorage' | 'indexedDB';\r\n}\r\n\r\n/**\r\n * Text customization for consent panel.\r\n */\r\nexport interface ConsentPanelText {\r\n /** Banner title */\r\n title?: string;\r\n /** Banner description */\r\n description?: string;\r\n /** Accept all button */\r\n acceptAll?: string;\r\n /** Reject all button */\r\n rejectAll?: string;\r\n /** Customize button */\r\n customize?: string;\r\n /** Save preferences button */\r\n savePreferences?: string;\r\n}\r\n\r\n// =============================================================================\r\n// AUDIT & COMPLIANCE\r\n// =============================================================================\r\n\r\n/**\r\n * Privacy policy change audit entry.\r\n */\r\nexport interface PolicyAuditEntry {\r\n /** Entry ID */\r\n id: string;\r\n /** Timestamp */\r\n timestamp: string;\r\n /** Who made the change */\r\n changedBy: string;\r\n /** What changed */\r\n changeType: PolicyChangeType;\r\n /** Previous mode */\r\n previousMode?: TracelessMode;\r\n /** New mode */\r\n newMode?: TracelessMode;\r\n /** Previous capabilities */\r\n previousCapabilities?: Partial<StorageCapabilities>;\r\n /** New capabilities */\r\n newCapabilities?: Partial<StorageCapabilities>;\r\n /** Reason for change */\r\n reason?: string;\r\n /** IP address */\r\n ipAddress?: string;\r\n /** User agent */\r\n userAgent?: string;\r\n /** Additional metadata */\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Types of policy changes.\r\n */\r\nexport type PolicyChangeType =\r\n | 'mode_change'\r\n | 'capability_change'\r\n | 'user_lockdown'\r\n | 'admin_override'\r\n | 'tenant_policy_update'\r\n | 'instance_ceiling_update'\r\n | 'group_policy_update';\r\n\r\n/**\r\n * Compliance report for Traceless mode.\r\n */\r\nexport interface TracelessComplianceReport {\r\n /** Report ID */\r\n reportId: string;\r\n /** Generated timestamp */\r\n generatedAt: string;\r\n /** Instance identifier */\r\n instanceId: string;\r\n /** Tenant identifier */\r\n tenantId?: string;\r\n /** Current mode */\r\n mode: TracelessMode;\r\n /** Storage capabilities summary */\r\n storageCapabilities: StorageCapabilities;\r\n /** Cookie count (should be 0 in traceless) */\r\n cookieCount: number;\r\n /** localStorage keys count */\r\n localStorageKeys: number;\r\n /** sessionStorage keys count */\r\n sessionStorageKeys: number;\r\n /** Whether consent banner is required */\r\n consentBannerRequired: boolean;\r\n /** Compliance statements */\r\n complianceStatements: ComplianceStatement[];\r\n /** Legal disclaimer */\r\n legalDisclaimer: string;\r\n}\r\n\r\n/**\r\n * Compliance statement for regulations.\r\n */\r\nexport interface ComplianceStatement {\r\n /** Regulation name */\r\n regulation: string;\r\n /** Relevant article/section */\r\n article?: string;\r\n /** Compliance status */\r\n status: 'compliant' | 'exempt' | 'requires_review';\r\n /** Explanation */\r\n explanation: string;\r\n}\r\n\r\n// =============================================================================\r\n// PRIVACY API ENDPOINTS\r\n// =============================================================================\r\n\r\n/**\r\n * Privacy API endpoint definitions.\r\n */\r\nexport interface PrivacyAPI {\r\n /** Get effective policy */\r\n getPolicy: () => Promise<ITracelessPolicy>;\r\n /** Update user preferences */\r\n updatePolicy: (prefs: Partial<UserPrivacyPreferences>) => Promise<ITracelessPolicy>;\r\n /** Get capabilities for current mode */\r\n getCapabilities: () => Promise<StorageCapabilities>;\r\n /** Get audit log */\r\n getAuditLog: (params: AuditLogParams) => Promise<PolicyAuditEntry[]>;\r\n /** Generate compliance report */\r\n generateComplianceReport: () => Promise<TracelessComplianceReport>;\r\n}\r\n\r\n/**\r\n * Audit log query parameters.\r\n */\r\nexport interface AuditLogParams {\r\n /** Start date */\r\n from?: string;\r\n /** End date */\r\n to?: string;\r\n /** Filter by user */\r\n userId?: string;\r\n /** Filter by change type */\r\n changeType?: PolicyChangeType;\r\n /** Page number */\r\n page?: number;\r\n /** Page size */\r\n pageSize?: number;\r\n}\r\n\r\n// =============================================================================\r\n// TESTING & SCANNING\r\n// =============================================================================\r\n\r\n/**\r\n * Storage scanner configuration for CI/CD.\r\n */\r\nexport interface StorageScannerConfig {\r\n /** Base URL to scan */\r\n baseUrl: string;\r\n /** Pages to visit */\r\n pages: string[];\r\n /** Expected mode */\r\n expectedMode: TracelessMode;\r\n /** Whether to fail on any cookie */\r\n failOnCookie: boolean;\r\n /** Whether to fail on any localStorage */\r\n failOnLocalStorage: boolean;\r\n /** Whether to fail on any sessionStorage */\r\n failOnSessionStorage: boolean;\r\n /** Timeout per page in ms */\r\n pageTimeout: number;\r\n /** Output format */\r\n outputFormat: 'json' | 'junit' | 'console';\r\n}\r\n\r\n/**\r\n * Storage scan result.\r\n */\r\nexport interface StorageScanResult {\r\n /** Scan timestamp */\r\n timestamp: string;\r\n /** Base URL scanned */\r\n baseUrl: string;\r\n /** Pages scanned */\r\n pagesScanned: number;\r\n /** Overall pass/fail */\r\n passed: boolean;\r\n /** Violations found */\r\n violations: StorageViolation[];\r\n /** Summary statistics */\r\n summary: StorageScanSummary;\r\n}\r\n\r\n/**\r\n * A storage violation found during scan.\r\n */\r\nexport interface StorageViolation {\r\n /** Page URL where violation occurred */\r\n pageUrl: string;\r\n /** Type of violation */\r\n type: 'cookie' | 'localStorage' | 'sessionStorage' | 'indexedDB';\r\n /** Key name */\r\n key: string;\r\n /** Value (may be truncated) */\r\n value?: string;\r\n /** Likely source/framework */\r\n suspectedSource?: string;\r\n /** Severity */\r\n severity: 'critical' | 'high' | 'medium' | 'low';\r\n}\r\n\r\n/**\r\n * Scan summary statistics.\r\n */\r\nexport interface StorageScanSummary {\r\n /** Total cookies found */\r\n totalCookies: number;\r\n /** Total localStorage keys */\r\n totalLocalStorageKeys: number;\r\n /** Total sessionStorage keys */\r\n totalSessionStorageKeys: number;\r\n /** Total IndexedDB databases */\r\n totalIndexedDBDatabases: number;\r\n /** Total violations */\r\n totalViolations: number;\r\n /** Violations by severity */\r\n violationsBySeverity: Record<string, number>;\r\n}\r\n\r\n// =============================================================================\r\n// EXPORT HELPERS\r\n// =============================================================================\r\n\r\n/**\r\n * Default traceless policy - maximum privacy.\r\n */\r\nexport const DEFAULT_TRACELESS_POLICY: ITracelessPolicy = {\r\n cookiesAllowed: false,\r\n localStorageAllowed: false,\r\n sessionStorageAllowed: false,\r\n indexedDBAllowed: false,\r\n webSQLAllowed: false,\r\n serviceWorkerCacheAllowed: false,\r\n effectiveMode: 'traceless',\r\n consentRequired: false,\r\n canPersist: false,\r\n policySource: 'instance',\r\n resolvedAt: new Date().toISOString(),\r\n};\r\n\r\n/**\r\n * Default full policy - all storage allowed.\r\n */\r\nexport const DEFAULT_FULL_POLICY: ITracelessPolicy = {\r\n cookiesAllowed: true,\r\n localStorageAllowed: true,\r\n sessionStorageAllowed: true,\r\n indexedDBAllowed: true,\r\n webSQLAllowed: true,\r\n serviceWorkerCacheAllowed: true,\r\n effectiveMode: 'full',\r\n consentRequired: true,\r\n canPersist: true,\r\n policySource: 'instance',\r\n resolvedAt: new Date().toISOString(),\r\n};\r\n\r\n/**\r\n * Mode to capabilities mapping.\r\n */\r\nexport const MODE_CAPABILITIES: Record<TracelessMode, StorageCapabilities> = {\r\n traceless: {\r\n cookiesAllowed: false,\r\n localStorageAllowed: false,\r\n sessionStorageAllowed: false,\r\n indexedDBAllowed: false,\r\n webSQLAllowed: false,\r\n serviceWorkerCacheAllowed: false,\r\n },\r\n ephemeral: {\r\n cookiesAllowed: false,\r\n localStorageAllowed: false,\r\n sessionStorageAllowed: true,\r\n indexedDBAllowed: false,\r\n webSQLAllowed: false,\r\n serviceWorkerCacheAllowed: false,\r\n },\r\n private: {\r\n cookiesAllowed: false, // except httpOnly auth\r\n localStorageAllowed: false,\r\n sessionStorageAllowed: true,\r\n indexedDBAllowed: false,\r\n webSQLAllowed: false,\r\n serviceWorkerCacheAllowed: false,\r\n },\r\n balanced: {\r\n cookiesAllowed: false,\r\n localStorageAllowed: true,\r\n sessionStorageAllowed: true,\r\n indexedDBAllowed: true,\r\n webSQLAllowed: false,\r\n serviceWorkerCacheAllowed: true,\r\n },\r\n full: {\r\n cookiesAllowed: true,\r\n localStorageAllowed: true,\r\n sessionStorageAllowed: true,\r\n indexedDBAllowed: true,\r\n webSQLAllowed: true,\r\n serviceWorkerCacheAllowed: true,\r\n },\r\n custom: {\r\n cookiesAllowed: false,\r\n localStorageAllowed: false,\r\n sessionStorageAllowed: false,\r\n indexedDBAllowed: false,\r\n webSQLAllowed: false,\r\n serviceWorkerCacheAllowed: false,\r\n },\r\n};\r\n","/**\r\n * @fileoverview PRO-23: Accessibility & Internationalization Types\r\n *\r\n * This module provides TypeScript types and interfaces for building\r\n * fully accessible and internationalized applications following\r\n * WCAG 2.1 AA guidelines and supporting 50+ languages.\r\n *\r\n * @module @nice2dev/ui-tools/accessibility-i18n\r\n */\r\n\r\n// =============================================================================\r\n// ACCESSIBILITY (A11Y) TYPES\r\n// =============================================================================\r\n\r\n/**\r\n * WCAG compliance levels.\r\n */\r\nexport type WCAGLevel = 'A' | 'AA' | 'AAA';\r\n\r\n/**\r\n * WCAG version.\r\n */\r\nexport type WCAGVersion = '2.0' | '2.1' | '2.2';\r\n\r\n/**\r\n * Accessibility configuration for an application.\r\n */\r\nexport interface AccessibilityConfig {\r\n /** Target WCAG level */\r\n targetLevel: WCAGLevel;\r\n /** WCAG version to follow */\r\n wcagVersion: WCAGVersion;\r\n /** Enable screen reader optimizations */\r\n screenReaderOptimizations: boolean;\r\n /** Enable full keyboard navigation */\r\n keyboardNavigation: boolean;\r\n /** Enforce minimum color contrast */\r\n enforceColorContrast: boolean;\r\n /** Minimum contrast ratio (4.5:1 for AA) */\r\n minContrastRatio: number;\r\n /** Respect prefers-reduced-motion */\r\n respectReducedMotion: boolean;\r\n /** Enable focus visible indicators */\r\n focusVisible: boolean;\r\n /** Enable high contrast mode support */\r\n highContrastSupport: boolean;\r\n /** Enable forced colors support */\r\n forcedColorsSupport: boolean;\r\n /** Run automated accessibility tests */\r\n automatedTesting: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// ARIA TYPES\r\n// =============================================================================\r\n\r\n/**\r\n * ARIA roles for semantic meaning.\r\n */\r\nexport type AriaRole =\r\n // Landmark roles\r\n | 'banner'\r\n | 'complementary'\r\n | 'contentinfo'\r\n | 'form'\r\n | 'main'\r\n | 'navigation'\r\n | 'region'\r\n | 'search'\r\n // Widget roles\r\n | 'button'\r\n | 'checkbox'\r\n | 'dialog'\r\n | 'gridcell'\r\n | 'link'\r\n | 'log'\r\n | 'marquee'\r\n | 'menuitem'\r\n | 'menuitemcheckbox'\r\n | 'menuitemradio'\r\n | 'option'\r\n | 'progressbar'\r\n | 'radio'\r\n | 'scrollbar'\r\n | 'searchbox'\r\n | 'slider'\r\n | 'spinbutton'\r\n | 'status'\r\n | 'switch'\r\n | 'tab'\r\n | 'tabpanel'\r\n | 'textbox'\r\n | 'timer'\r\n | 'tooltip'\r\n | 'treeitem'\r\n // Document structure roles\r\n | 'article'\r\n | 'cell'\r\n | 'columnheader'\r\n | 'definition'\r\n | 'directory'\r\n | 'document'\r\n | 'figure'\r\n | 'group'\r\n | 'heading'\r\n | 'img'\r\n | 'list'\r\n | 'listitem'\r\n | 'math'\r\n | 'none'\r\n | 'note'\r\n | 'presentation'\r\n | 'row'\r\n | 'rowgroup'\r\n | 'rowheader'\r\n | 'separator'\r\n | 'table'\r\n | 'term'\r\n | 'toolbar'\r\n // Live region roles\r\n | 'alert'\r\n | 'alertdialog'\r\n | 'application'\r\n | 'grid'\r\n | 'listbox'\r\n | 'menu'\r\n | 'menubar'\r\n | 'radiogroup'\r\n | 'tablist'\r\n | 'tree'\r\n | 'treegrid';\r\n\r\n/**\r\n * ARIA live region politeness.\r\n */\r\nexport type AriaLive = 'off' | 'polite' | 'assertive';\r\n\r\n/**\r\n * ARIA pressed state for toggle buttons.\r\n */\r\nexport type AriaPressed = boolean | 'mixed';\r\n\r\n/**\r\n * ARIA expanded state for collapsible elements.\r\n */\r\nexport type AriaExpanded = boolean;\r\n\r\n/**\r\n * ARIA selected state.\r\n */\r\nexport type AriaSelected = boolean;\r\n\r\n/**\r\n * ARIA checked state.\r\n */\r\nexport type AriaChecked = boolean | 'mixed';\r\n\r\n/**\r\n * ARIA label configuration.\r\n */\r\nexport interface AriaLabelConfig {\r\n /** The accessible label */\r\n label?: string;\r\n /** ID of element that labels this */\r\n labelledBy?: string;\r\n /** ID of element that describes this */\r\n describedBy?: string;\r\n /** ID of error message element */\r\n errorMessage?: string;\r\n /** Additional details for screen readers */\r\n details?: string;\r\n}\r\n\r\n/**\r\n * ARIA relationship configuration.\r\n */\r\nexport interface AriaRelationships {\r\n /** ID of controlled element */\r\n controls?: string;\r\n /** IDs of owned elements */\r\n owns?: string;\r\n /** ID of active descendant */\r\n activeDescendant?: string;\r\n /** IDs of related flow elements */\r\n flowTo?: string;\r\n /** ID of help element */\r\n help?: string;\r\n}\r\n\r\n/**\r\n * ARIA state configuration.\r\n */\r\nexport interface AriaState {\r\n /** Whether element is expanded */\r\n expanded?: AriaExpanded;\r\n /** Whether element is selected */\r\n selected?: AriaSelected;\r\n /** Whether element is pressed */\r\n pressed?: AriaPressed;\r\n /** Whether element is checked */\r\n checked?: AriaChecked;\r\n /** Whether element is disabled */\r\n disabled?: boolean;\r\n /** Whether element is hidden */\r\n hidden?: boolean;\r\n /** Whether element is invalid */\r\n invalid?: boolean | 'grammar' | 'spelling';\r\n /** Whether element is required */\r\n required?: boolean;\r\n /** Whether element is read-only */\r\n readOnly?: boolean;\r\n /** Whether element is busy */\r\n busy?: boolean;\r\n /** Current value for range widgets */\r\n valuenow?: number;\r\n /** Minimum value for range widgets */\r\n valuemin?: number;\r\n /** Maximum value for range widgets */\r\n valuemax?: number;\r\n /** Text alternative for current value */\r\n valuetext?: string;\r\n /** Current item position */\r\n posinset?: number;\r\n /** Total items in set */\r\n setsize?: number;\r\n /** Level in hierarchy */\r\n level?: number;\r\n /** Sort direction */\r\n sort?: 'ascending' | 'descending' | 'none' | 'other';\r\n /** Autocomplete behavior */\r\n autocomplete?: 'none' | 'inline' | 'list' | 'both';\r\n /** Multiselectable */\r\n multiselectable?: boolean;\r\n /** Orientation */\r\n orientation?: 'horizontal' | 'vertical';\r\n}\r\n\r\n/**\r\n * Complete accessible element configuration.\r\n */\r\nexport interface AccessibleElementConfig extends AriaLabelConfig, AriaRelationships, AriaState {\r\n /** Element role */\r\n role?: AriaRole;\r\n /** Live region configuration */\r\n live?: AriaLive;\r\n /** Atomic updates for live regions */\r\n atomic?: boolean;\r\n /** Relevant changes for live regions */\r\n relevant?: 'additions' | 'removals' | 'text' | 'all';\r\n /** Tab index for keyboard navigation */\r\n tabIndex?: number;\r\n}\r\n\r\n// =============================================================================\r\n// KEYBOARD NAVIGATION\r\n// =============================================================================\r\n\r\n/**\r\n * Keyboard shortcut definition.\r\n */\r\nexport interface KeyboardShortcut {\r\n /** Shortcut identifier */\r\n id: string;\r\n /** Key combination (e.g., \"Ctrl+S\", \"Alt+Shift+P\") */\r\n keys: string;\r\n /** Description of what the shortcut does */\r\n description: string;\r\n /** Action category */\r\n category?: string;\r\n /** Whether shortcut is global */\r\n global?: boolean;\r\n /** Whether shortcut can be customized */\r\n customizable?: boolean;\r\n /** Alternative key combination */\r\n alternative?: string;\r\n /** Platform-specific overrides */\r\n platformOverrides?: Record<string, string>;\r\n}\r\n\r\n/**\r\n * Keyboard navigation configuration.\r\n */\r\nexport interface KeyboardNavigationConfig {\r\n /** Enable arrow key navigation */\r\n arrowNavigation: boolean;\r\n /** Enable tab navigation */\r\n tabNavigation: boolean;\r\n /** Enable home/end navigation */\r\n homeEndNavigation: boolean;\r\n /** Enable page up/down navigation */\r\n pageNavigation: boolean;\r\n /** Enable type-ahead search */\r\n typeAhead: boolean;\r\n /** Type-ahead timeout in ms */\r\n typeAheadTimeout?: number;\r\n /** Wrap around at boundaries */\r\n wrapNavigation: boolean;\r\n /** Custom shortcuts */\r\n shortcuts: KeyboardShortcut[];\r\n}\r\n\r\n/**\r\n * Focus trap configuration.\r\n */\r\nexport interface FocusTrapConfig {\r\n /** Enable focus trap */\r\n enabled: boolean;\r\n /** Allow escape key to exit */\r\n allowEscape: boolean;\r\n /** Return focus to trigger on close */\r\n returnFocus: boolean;\r\n /** Initial focus target selector */\r\n initialFocus?: string;\r\n /** Final focus target selector */\r\n finalFocus?: string;\r\n /** Selectors for focusable elements */\r\n focusableSelectors?: string[];\r\n}\r\n\r\n/**\r\n * Focus management utilities.\r\n */\r\nexport interface FocusManagement {\r\n /** Currently focused element ID */\r\n currentFocus?: string;\r\n /** Focus history stack */\r\n focusHistory: string[];\r\n /** Maximum history length */\r\n maxHistoryLength: number;\r\n /** Focus trap configuration */\r\n trap?: FocusTrapConfig;\r\n}\r\n\r\n// =============================================================================\r\n// COLOR & CONTRAST\r\n// =============================================================================\r\n\r\n/**\r\n * Color contrast requirements.\r\n */\r\nexport interface ColorContrastRequirements {\r\n /** Minimum contrast for normal text */\r\n normalText: number;\r\n /** Minimum contrast for large text (14pt bold or 18pt) */\r\n largeText: number;\r\n /** Minimum contrast for UI components */\r\n uiComponents: number;\r\n /** Minimum contrast for graphical objects */\r\n graphicalObjects: number;\r\n /** Minimum contrast for focus indicators */\r\n focusIndicators: number;\r\n}\r\n\r\n/**\r\n * WCAG 2.1 AA contrast requirements.\r\n */\r\nexport const WCAG_AA_CONTRAST: ColorContrastRequirements = {\r\n normalText: 4.5,\r\n largeText: 3,\r\n uiComponents: 3,\r\n graphicalObjects: 3,\r\n focusIndicators: 3,\r\n};\r\n\r\n/**\r\n * WCAG 2.1 AAA contrast requirements.\r\n */\r\nexport const WCAG_AAA_CONTRAST: ColorContrastRequirements = {\r\n normalText: 7,\r\n largeText: 4.5,\r\n uiComponents: 3,\r\n graphicalObjects: 3,\r\n focusIndicators: 4.5,\r\n};\r\n\r\n/**\r\n * Color contrast check result.\r\n */\r\nexport interface ContrastCheckResult {\r\n /** Foreground color */\r\n foreground: string;\r\n /** Background color */\r\n background: string;\r\n /** Calculated contrast ratio */\r\n ratio: number;\r\n /** Passes AA for normal text */\r\n passesAANormal: boolean;\r\n /** Passes AA for large text */\r\n passesAALarge: boolean;\r\n /** Passes AAA for normal text */\r\n passesAAANormal: boolean;\r\n /** Passes AAA for large text */\r\n passesAAALarge: boolean;\r\n /** Suggested alternatives if failing */\r\n suggestions?: ColorSuggestion[];\r\n}\r\n\r\n/**\r\n * Color suggestion for improving contrast.\r\n */\r\nexport interface ColorSuggestion {\r\n /** Suggested color */\r\n color: string;\r\n /** Resulting contrast ratio */\r\n resultingRatio: number;\r\n /** Whether it passes target level */\r\n passesTarget: boolean;\r\n /** How different from original (0-1) */\r\n colorDifference: number;\r\n}\r\n\r\n/**\r\n * High contrast mode configuration.\r\n */\r\nexport interface HighContrastConfig {\r\n /** Detect high contrast mode automatically */\r\n autoDetect: boolean;\r\n /** Custom high contrast theme */\r\n customTheme?: HighContrastTheme;\r\n /** Respect Windows high contrast mode */\r\n respectWindowsHC: boolean;\r\n /** Enable forced-colors support */\r\n forcedColors: boolean;\r\n}\r\n\r\n/**\r\n * High contrast theme colors.\r\n */\r\nexport interface HighContrastTheme {\r\n /** Background color */\r\n background: string;\r\n /** Foreground/text color */\r\n foreground: string;\r\n /** Link color */\r\n link: string;\r\n /** Visited link color */\r\n linkVisited: string;\r\n /** Button background */\r\n buttonBackground: string;\r\n /** Button text */\r\n buttonText: string;\r\n /** Disabled text */\r\n disabledText: string;\r\n /** Highlight background */\r\n highlight: string;\r\n /** Highlight text */\r\n highlightText: string;\r\n}\r\n\r\n// =============================================================================\r\n// MOTION & ANIMATION\r\n// =============================================================================\r\n\r\n/**\r\n * Reduced motion configuration.\r\n */\r\nexport interface ReducedMotionConfig {\r\n /** Detect prefers-reduced-motion automatically */\r\n autoDetect: boolean;\r\n /** Force reduced motion regardless of system setting */\r\n forceReduced: boolean;\r\n /** Alternative for essential animations */\r\n essentialAnimationFallback: 'none' | 'fade' | 'instant';\r\n /** Maximum animation duration when reduced (ms) */\r\n maxDuration: number;\r\n}\r\n\r\n/**\r\n * Animation accessibility settings.\r\n */\r\nexport interface AnimationAccessibility {\r\n /** Whether animations are enabled */\r\n enabled: boolean;\r\n /** Maximum animation duration (ms) */\r\n maxDuration: number;\r\n /** Disable parallax effects */\r\n disableParallax: boolean;\r\n /** Disable auto-playing videos */\r\n disableAutoplayVideo: boolean;\r\n /** Disable auto-playing audio */\r\n disableAutoplayAudio: boolean;\r\n /** Pause animations on focus loss */\r\n pauseOnFocusLoss: boolean;\r\n /** Provide animation controls */\r\n showAnimationControls: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// SCREEN READER SUPPORT\r\n// =============================================================================\r\n\r\n/**\r\n * Screen reader announcement configuration.\r\n */\r\nexport interface ScreenReaderAnnouncement {\r\n /** Message to announce */\r\n message: string;\r\n /** Politeness level */\r\n politeness: AriaLive;\r\n /** Whether to clear previous announcements */\r\n clearQueue?: boolean;\r\n /** Delay before announcement (ms) */\r\n delay?: number;\r\n}\r\n\r\n/**\r\n * Live region configuration.\r\n */\r\nexport interface LiveRegionConfig {\r\n /** Region ID */\r\n id: string;\r\n /** Politeness level */\r\n politeness: AriaLive;\r\n /** Whether updates are atomic */\r\n atomic: boolean;\r\n /** What changes are relevant */\r\n relevant: 'additions' | 'removals' | 'text' | 'all';\r\n /** Role (status, log, alert, etc.) */\r\n role?: 'status' | 'log' | 'alert' | 'progressbar' | 'marquee' | 'timer';\r\n}\r\n\r\n/**\r\n * Screen reader hints configuration.\r\n */\r\nexport interface ScreenReaderHints {\r\n /** Enable form field hints */\r\n formHints: boolean;\r\n /** Enable navigation hints */\r\n navigationHints: boolean;\r\n /** Enable state change announcements */\r\n stateChangeAnnouncements: boolean;\r\n /** Enable error announcements */\r\n errorAnnouncements: boolean;\r\n /** Enable loading announcements */\r\n loadingAnnouncements: boolean;\r\n /** Announce page titles */\r\n announcePageTitles: boolean;\r\n /** Announce focus changes */\r\n announceFocusChanges: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// FORM ACCESSIBILITY\r\n// =============================================================================\r\n\r\n/**\r\n * Accessible form field configuration.\r\n */\r\nexport interface AccessibleFormField {\r\n /** Field ID */\r\n id: string;\r\n /** Field name */\r\n name: string;\r\n /** Label text */\r\n label: string;\r\n /** Label position */\r\n labelPosition: 'before' | 'after' | 'floating';\r\n /** Whether label is visible */\r\n labelVisible: boolean;\r\n /** Help text */\r\n helpText?: string;\r\n /** Error message */\r\n errorMessage?: string;\r\n /** Whether field is required */\r\n required: boolean;\r\n /** Auto-complete attribute */\r\n autocomplete?: string;\r\n /** Input mode */\r\n inputMode?: 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';\r\n /** Pattern validation */\r\n pattern?: string;\r\n /** Pattern description for screen readers */\r\n patternDescription?: string;\r\n}\r\n\r\n/**\r\n * Form error handling configuration.\r\n */\r\nexport interface FormErrorHandling {\r\n /** Show inline errors */\r\n inlineErrors: boolean;\r\n /** Show error summary */\r\n errorSummary: boolean;\r\n /** Error summary position */\r\n summaryPosition: 'top' | 'bottom';\r\n /** Focus first error on submit */\r\n focusFirstError: boolean;\r\n /** Announce errors to screen readers */\r\n announceErrors: boolean;\r\n /** Error announcement politeness */\r\n errorPoliteness: AriaLive;\r\n /** Real-time validation */\r\n realtimeValidation: boolean;\r\n /** Validation delay (ms) */\r\n validationDelay?: number;\r\n}\r\n\r\n// =============================================================================\r\n// SKIP LINKS & LANDMARKS\r\n// =============================================================================\r\n\r\n/**\r\n * Skip link configuration.\r\n */\r\nexport interface SkipLink {\r\n /** Link text */\r\n text: string;\r\n /** Target element ID */\r\n target: string;\r\n /** Whether link is visible on focus */\r\n visibleOnFocus: boolean;\r\n}\r\n\r\n/**\r\n * Page landmarks configuration.\r\n */\r\nexport interface LandmarksConfig {\r\n /** Main content landmark ID */\r\n main?: string;\r\n /** Navigation landmark ID */\r\n navigation?: string;\r\n /** Search landmark ID */\r\n search?: string;\r\n /** Banner landmark ID */\r\n banner?: string;\r\n /** Footer landmark ID */\r\n contentinfo?: string;\r\n /** Complementary/aside landmark IDs */\r\n complementary?: string[];\r\n /** Custom regions */\r\n regions?: { id: string; label: string }[];\r\n}\r\n\r\n// =============================================================================\r\n// ACCESSIBILITY TESTING\r\n// =============================================================================\r\n\r\n/**\r\n * Accessibility test result.\r\n */\r\nexport interface AccessibilityTestResult {\r\n /** Test passed */\r\n passed: boolean;\r\n /** Number of violations */\r\n violationCount: number;\r\n /** Violations found */\r\n violations: AccessibilityViolation[];\r\n /** Passes (optional, for reporting) */\r\n passes?: AccessibilityPass[];\r\n /** Incomplete checks (need manual review) */\r\n incomplete?: AccessibilityIncomplete[];\r\n /** Test timestamp */\r\n timestamp: string;\r\n /** Page/component tested */\r\n target: string;\r\n}\r\n\r\n/**\r\n * Accessibility violation.\r\n */\r\nexport interface AccessibilityViolation {\r\n /** Rule ID */\r\n ruleId: string;\r\n /** Violation description */\r\n description: string;\r\n /** Impact severity */\r\n impact: 'minor' | 'moderate' | 'serious' | 'critical';\r\n /** WCAG criteria violated */\r\n wcagCriteria: string[];\r\n /** Help URL */\r\n helpUrl: string;\r\n /** Affected elements */\r\n nodes: AccessibilityNode[];\r\n /** How to fix */\r\n fix: string;\r\n}\r\n\r\n/**\r\n * Accessibility pass (rule that passed).\r\n */\r\nexport interface AccessibilityPass {\r\n /** Rule ID */\r\n ruleId: string;\r\n /** Rule description */\r\n description: string;\r\n /** Elements that passed */\r\n nodes: AccessibilityNode[];\r\n}\r\n\r\n/**\r\n * Incomplete accessibility check.\r\n */\r\nexport interface AccessibilityIncomplete {\r\n /** Rule ID */\r\n ruleId: string;\r\n /** What needs manual review */\r\n description: string;\r\n /** Elements to review */\r\n nodes: AccessibilityNode[];\r\n}\r\n\r\n/**\r\n * Affected DOM node.\r\n */\r\nexport interface AccessibilityNode {\r\n /** Element selector */\r\n selector: string;\r\n /** Element HTML */\r\n html: string;\r\n /** Failure summary */\r\n failureSummary?: string;\r\n}\r\n\r\n// =============================================================================\r\n// INTERNATIONALIZATION (I18N) TYPES\r\n// =============================================================================\r\n\r\n/**\r\n * Locale identifier (BCP 47).\r\n */\r\nexport type LocaleCode = string; // e.g., 'en', 'en-US', 'pl-PL', 'ar-SA'\r\n\r\n/**\r\n * Text direction.\r\n */\r\nexport type TextDirection = 'ltr' | 'rtl' | 'auto';\r\n\r\n/**\r\n * I18n configuration.\r\n */\r\nexport interface I18nConfig {\r\n /** Default locale */\r\n defaultLocale: LocaleCode;\r\n /** Supported locales */\r\n supportedLocales: LocaleCode[];\r\n /** Fallback locale */\r\n fallbackLocale: LocaleCode;\r\n /** Enable RTL support */\r\n rtlSupport: boolean;\r\n /** RTL locales */\r\n rtlLocales: LocaleCode[];\r\n /** Load locale on demand */\r\n lazyLoading: boolean;\r\n /** Translation file format */\r\n format: 'json' | 'yaml' | 'po' | 'xliff';\r\n /** Missing translation handling */\r\n missingTranslation: 'warn' | 'error' | 'fallback' | 'key';\r\n /** Enable pluralization */\r\n pluralization: boolean;\r\n /** Enable gender agreement */\r\n genderAgreement: boolean;\r\n /** Date/time format configuration */\r\n dateTimeFormats: Record<LocaleCode, DateTimeFormats>;\r\n /** Number format configuration */\r\n numberFormats: Record<LocaleCode, NumberFormats>;\r\n}\r\n\r\n// =============================================================================\r\n// DATE/TIME FORMATTING\r\n// =============================================================================\r\n\r\n/**\r\n * Date/time format presets.\r\n */\r\nexport interface DateTimeFormats {\r\n /** Short date format */\r\n short: Intl.DateTimeFormatOptions;\r\n /** Medium date format */\r\n medium: Intl.DateTimeFormatOptions;\r\n /** Long date format */\r\n long: Intl.DateTimeFormatOptions;\r\n /** Full date format */\r\n full: Intl.DateTimeFormatOptions;\r\n /** Time only format */\r\n time: Intl.DateTimeFormatOptions;\r\n /** DateTime format */\r\n datetime: Intl.DateTimeFormatOptions;\r\n /** Relative time format */\r\n relative: Intl.RelativeTimeFormatOptions;\r\n}\r\n\r\n/**\r\n * Date formatting configuration.\r\n */\r\nexport interface DateFormatConfig {\r\n /** Locale for formatting */\r\n locale: LocaleCode;\r\n /** Calendar system */\r\n calendar: CalendarSystem;\r\n /** Timezone */\r\n timezone: string;\r\n /** Hour cycle (12 or 24) */\r\n hourCycle: 'h11' | 'h12' | 'h23' | 'h24';\r\n /** Week starts on */\r\n weekStartsOn: 0 | 1 | 2 | 3 | 4 | 5 | 6;\r\n}\r\n\r\n/**\r\n * Supported calendar systems.\r\n */\r\nexport type CalendarSystem =\r\n | 'gregory' // Gregorian (default)\r\n | 'buddhist' // Buddhist\r\n | 'chinese' // Chinese\r\n | 'coptic' // Coptic\r\n | 'ethiopic' // Ethiopian\r\n | 'hebrew' // Hebrew\r\n | 'indian' // Indian National\r\n | 'islamic' // Islamic (Hijri)\r\n | 'islamic-civil' // Islamic civil\r\n | 'islamic-rgsa' // Islamic (Saudi Arabia)\r\n | 'islamic-tbla' // Islamic (tabular)\r\n | 'islamic-umalqura' // Islamic (Umm al-Qura)\r\n | 'japanese' // Japanese\r\n | 'persian' // Persian (Jalali)\r\n | 'roc'; // Republic of China\r\n\r\n/**\r\n * Relative time formatting result.\r\n */\r\nexport interface RelativeTimeResult {\r\n /** Formatted string */\r\n formatted: string;\r\n /** Unit used */\r\n unit: Intl.RelativeTimeFormatUnit;\r\n /** Numeric value */\r\n value: number;\r\n /** Whether time is in past */\r\n isPast: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// NUMBER FORMATTING\r\n// =============================================================================\r\n\r\n/**\r\n * Number format presets.\r\n */\r\nexport interface NumberFormats {\r\n /** Decimal format */\r\n decimal: Intl.NumberFormatOptions;\r\n /** Currency format */\r\n currency: CurrencyFormatOptions;\r\n /** Percent format */\r\n percent: Intl.NumberFormatOptions;\r\n /** Compact format (1K, 1M) */\r\n compact: Intl.NumberFormatOptions;\r\n /** Scientific format */\r\n scientific: Intl.NumberFormatOptions;\r\n /** Unit format */\r\n unit: UnitFormatOptions;\r\n}\r\n\r\n/**\r\n * Currency format options.\r\n */\r\nexport interface CurrencyFormatOptions extends Intl.NumberFormatOptions {\r\n /** Currency code (ISO 4217) */\r\n currency: string;\r\n /** Currency display style */\r\n currencyDisplay?: 'symbol' | 'narrowSymbol' | 'code' | 'name';\r\n /** Accounting format for negative values */\r\n currencySign?: 'standard' | 'accounting';\r\n}\r\n\r\n/**\r\n * Unit format options.\r\n */\r\nexport interface UnitFormatOptions extends Intl.NumberFormatOptions {\r\n /** Unit to display */\r\n unit: string;\r\n /** Unit display style */\r\n unitDisplay?: 'short' | 'narrow' | 'long';\r\n}\r\n\r\n/**\r\n * Common currency codes.\r\n */\r\nexport type CurrencyCode =\r\n | 'USD'\r\n | 'EUR'\r\n | 'GBP'\r\n | 'JPY'\r\n | 'CNY'\r\n | 'CHF'\r\n | 'CAD'\r\n | 'AUD'\r\n | 'NZD'\r\n | 'SEK'\r\n | 'NOK'\r\n | 'DKK'\r\n | 'PLN'\r\n | 'CZK'\r\n | 'HUF'\r\n | 'RON'\r\n | 'BGN'\r\n | 'HRK'\r\n | 'RUB'\r\n | 'UAH'\r\n | 'TRY'\r\n | 'BRL'\r\n | 'MXN'\r\n | 'ARS'\r\n | 'INR'\r\n | 'KRW'\r\n | 'SGD'\r\n | 'HKD'\r\n | 'TWD'\r\n | 'THB'\r\n | 'MYR'\r\n | 'IDR'\r\n | 'PHP'\r\n | 'VND'\r\n | 'ZAR'\r\n | 'EGP'\r\n | 'SAR'\r\n | 'AED'\r\n | 'ILS'\r\n | 'NGN'\r\n | string; // Allow other codes\r\n\r\n// =============================================================================\r\n// PLURALIZATION\r\n// =============================================================================\r\n\r\n/**\r\n * Plural categories (CLDR).\r\n */\r\nexport type PluralCategory = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other';\r\n\r\n/**\r\n * Plural rule function type.\r\n */\r\nexport type PluralRuleFunction = (n: number, ord?: boolean) => PluralCategory;\r\n\r\n/**\r\n * Plural rules configuration.\r\n */\r\nexport interface PluralRules {\r\n /** Locale */\r\n locale: LocaleCode;\r\n /** Cardinal plural rules */\r\n cardinal: PluralRuleFunction;\r\n /** Ordinal plural rules */\r\n ordinal: PluralRuleFunction;\r\n /** Plural categories used by this locale */\r\n categories: PluralCategory[];\r\n /** Ordinal categories used by this locale */\r\n ordinalCategories: PluralCategory[];\r\n}\r\n\r\n/**\r\n * Pluralized message.\r\n */\r\nexport interface PluralMessage {\r\n /** Message for zero */\r\n zero?: string;\r\n /** Message for one */\r\n one?: string;\r\n /** Message for two (Arabic, Hebrew) */\r\n two?: string;\r\n /** Message for few (Slavic languages) */\r\n few?: string;\r\n /** Message for many (Slavic languages) */\r\n many?: string;\r\n /** Message for other (required) */\r\n other: string;\r\n}\r\n\r\n// =============================================================================\r\n// GENDER AGREEMENT\r\n// =============================================================================\r\n\r\n/**\r\n * Grammatical gender.\r\n */\r\nexport type GrammaticalGender =\r\n | 'masculine'\r\n | 'feminine'\r\n | 'neuter'\r\n | 'common'\r\n | 'animate'\r\n | 'inanimate';\r\n\r\n/**\r\n * Gender-aware message.\r\n */\r\nexport interface GenderedMessage {\r\n /** Message for masculine */\r\n masculine?: string;\r\n /** Message for feminine */\r\n feminine?: string;\r\n /** Message for neuter */\r\n neuter?: string;\r\n /** Message for unknown/common gender */\r\n other: string;\r\n}\r\n\r\n/**\r\n * Combined plural and gender message.\r\n */\r\nexport interface PluralGenderedMessage {\r\n /** Messages by gender, then by plural */\r\n [gender: string]: PluralMessage;\r\n}\r\n\r\n// =============================================================================\r\n// TRANSLATION MANAGEMENT\r\n// =============================================================================\r\n\r\n/**\r\n * Translation entry.\r\n */\r\nexport interface TranslationEntry {\r\n /** Translation key */\r\n key: string;\r\n /** Source text */\r\n source: string;\r\n /** Translated text */\r\n translation: string;\r\n /** Context for translators */\r\n context?: string;\r\n /** Translator notes */\r\n notes?: string;\r\n /** Whether entry is reviewed */\r\n reviewed: boolean;\r\n /** Last modified timestamp */\r\n lastModified: string;\r\n /** Last modified by */\r\n modifiedBy?: string;\r\n /** Plural forms */\r\n plurals?: PluralMessage;\r\n /** Gender forms */\r\n genders?: GenderedMessage;\r\n}\r\n\r\n/**\r\n * Translation namespace/file.\r\n */\r\nexport interface TranslationNamespace {\r\n /** Namespace name */\r\n name: string;\r\n /** Locale code */\r\n locale: LocaleCode;\r\n /** Translations in this namespace */\r\n translations: Record<string, TranslationEntry | string | PluralMessage>;\r\n /** Namespace version */\r\n version: string;\r\n /** Last updated */\r\n lastUpdated: string;\r\n}\r\n\r\n/**\r\n * Translation Management System (TMS) integration.\r\n */\r\nexport interface TMSIntegration {\r\n /** TMS provider */\r\n provider: 'crowdin' | 'lokalise' | 'phrase' | 'transifex' | 'weblate' | 'custom';\r\n /** API endpoint */\r\n apiEndpoint?: string;\r\n /** API key (should be from env) */\r\n apiKey?: string;\r\n /** Project ID */\r\n projectId: string;\r\n /** Sync direction */\r\n syncDirection: 'push' | 'pull' | 'both';\r\n /** Auto-sync on build */\r\n autoSync: boolean;\r\n}\r\n\r\n/**\r\n * Translation memory entry.\r\n */\r\nexport interface TranslationMemoryEntry {\r\n /** Source text */\r\n source: string;\r\n /** Source locale */\r\n sourceLocale: LocaleCode;\r\n /** Target text */\r\n target: string;\r\n /** Target locale */\r\n targetLocale: LocaleCode;\r\n /** Similarity score (0-100) */\r\n similarity: number;\r\n /** Context */\r\n context?: string;\r\n /** Usage count */\r\n usageCount: number;\r\n}\r\n\r\n// =============================================================================\r\n// RTL SUPPORT\r\n// =============================================================================\r\n\r\n/**\r\n * RTL layout configuration.\r\n */\r\nexport interface RTLConfig {\r\n /** Current direction */\r\n direction: TextDirection;\r\n /** Flip icons in RTL */\r\n flipIcons: boolean;\r\n /** Icons to exclude from flipping */\r\n excludeIcons: string[];\r\n /** Flip animations */\r\n flipAnimations: boolean;\r\n /** Use logical properties (start/end vs left/right) */\r\n useLogicalProperties: boolean;\r\n /** Mirror entire layout */\r\n mirrorLayout: boolean;\r\n}\r\n\r\n/**\r\n * Bidirectional text handling.\r\n */\r\nexport interface BidiConfig {\r\n /** Enable bidirectional text support */\r\n enabled: boolean;\r\n /** Default text direction */\r\n defaultDirection: TextDirection;\r\n /** Isolate mixed direction text */\r\n isolateMixed: boolean;\r\n /** Override algorithm for specific elements */\r\n overrides?: Record<string, TextDirection>;\r\n}\r\n\r\n// =============================================================================\r\n// TIMEZONE HANDLING\r\n// =============================================================================\r\n\r\n/**\r\n * Timezone configuration.\r\n */\r\nexport interface TimezoneConfig {\r\n /** User's timezone */\r\n userTimezone: string;\r\n /** Server/default timezone */\r\n serverTimezone: string;\r\n /** Display format */\r\n displayFormat: 'local' | 'utc' | 'both';\r\n /** Auto-detect timezone */\r\n autoDetect: boolean;\r\n /** Show timezone abbreviation */\r\n showAbbreviation: boolean;\r\n}\r\n\r\n/**\r\n * Timezone info.\r\n */\r\nexport interface TimezoneInfo {\r\n /** IANA timezone ID */\r\n id: string;\r\n /** Display name */\r\n displayName: string;\r\n /** UTC offset in minutes */\r\n offsetMinutes: number;\r\n /** UTC offset string (e.g., \"+02:00\") */\r\n offsetString: string;\r\n /** Abbreviation (e.g., \"CET\", \"EST\") */\r\n abbreviation: string;\r\n /** Whether DST is currently active */\r\n isDST: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// PSEUDO-LOCALIZATION\r\n// =============================================================================\r\n\r\n/**\r\n * Pseudo-localization configuration for testing.\r\n */\r\nexport interface PseudoLocalizationConfig {\r\n /** Enable pseudo-localization */\r\n enabled: boolean;\r\n /** Pseudo-locale code */\r\n pseudoLocale: string;\r\n /** Expansion factor (1.3 = 30% longer) */\r\n expansionFactor: number;\r\n /** Use accented characters */\r\n accented: boolean;\r\n /** Add brackets around strings */\r\n brackets: boolean;\r\n /** Bracket style */\r\n bracketStyle: '[{text}]' | '「{text}」' | '《{text}》';\r\n /** Simulate RTL */\r\n simulateRtl: boolean;\r\n /** Exclamation marks at start */\r\n exclamation: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// LOCALE DETECTION\r\n// =============================================================================\r\n\r\n/**\r\n * Locale detection configuration.\r\n */\r\nexport interface LocaleDetectionConfig {\r\n /** Detection order */\r\n order: LocaleDetectionSource[];\r\n /** Default if detection fails */\r\n fallback: LocaleCode;\r\n /** Cache detected locale */\r\n cache: boolean;\r\n /** Cache key (localStorage/cookie) */\r\n cacheKey: string;\r\n /** Accept partial matches (e.g., 'en' for 'en-US') */\r\n partialMatch: boolean;\r\n}\r\n\r\n/**\r\n * Sources for locale detection.\r\n */\r\nexport type LocaleDetectionSource =\r\n | 'querystring' // URL parameter (?lang=en)\r\n | 'cookie' // Cookie value\r\n | 'localStorage' // localStorage value\r\n | 'sessionStorage' // sessionStorage value\r\n | 'navigator' // navigator.language\r\n | 'header' // Accept-Language header\r\n | 'path' // URL path (/en/page)\r\n | 'subdomain' // Subdomain (en.example.com)\r\n | 'custom'; // Custom detection function\r\n\r\n// =============================================================================\r\n// REACT INTEGRATION\r\n// =============================================================================\r\n\r\n/**\r\n * useTranslation hook options.\r\n */\r\nexport interface UseTranslationOptions {\r\n /** Namespace to use */\r\n namespace?: string | string[];\r\n /** Key prefix */\r\n keyPrefix?: string;\r\n /** Fallback namespace */\r\n fallbackNS?: string;\r\n /** Use suspense for loading */\r\n useSuspense?: boolean;\r\n}\r\n\r\n/**\r\n * useTranslation hook return type.\r\n */\r\nexport interface UseTranslationResult {\r\n /** Translation function */\r\n t: TranslationFunction;\r\n /** Current locale */\r\n locale: LocaleCode;\r\n /** Available locales */\r\n locales: LocaleCode[];\r\n /** Change locale */\r\n changeLocale: (locale: LocaleCode) => Promise<void>;\r\n /** Whether translations are loading */\r\n isLoading: boolean;\r\n /** Current direction */\r\n dir: TextDirection;\r\n}\r\n\r\n/**\r\n * Translation function type.\r\n */\r\nexport type TranslationFunction = {\r\n /** Simple translation */\r\n (key: string): string;\r\n /** Translation with interpolation */\r\n (key: string, values: Record<string, unknown>): string;\r\n /** Translation with count for pluralization */\r\n (key: string, options: { count: number; [key: string]: unknown }): string;\r\n /** Translation with context */\r\n (key: string, options: { context: string; [key: string]: unknown }): string;\r\n};\r\n\r\n/**\r\n * I18n provider props.\r\n */\r\nexport interface I18nProviderProps {\r\n /** I18n configuration */\r\n config: I18nConfig;\r\n /** Initial locale */\r\n initialLocale?: LocaleCode;\r\n /** Children */\r\n children: React.ReactNode;\r\n /** On locale change callback */\r\n onLocaleChange?: (locale: LocaleCode) => void;\r\n}\r\n\r\n// =============================================================================\r\n// COMBINED ACCESSIBILITY & I18N\r\n// =============================================================================\r\n\r\n/**\r\n * Full accessibility and i18n configuration.\r\n */\r\nexport interface A11yI18nConfig {\r\n /** Accessibility configuration */\r\n accessibility: AccessibilityConfig;\r\n /** I18n configuration */\r\n i18n: I18nConfig;\r\n /** Screen reader adjustments per locale */\r\n localeScreenReaderAdjustments?: Record<LocaleCode, ScreenReaderHints>;\r\n /** Locale-specific keyboard shortcuts */\r\n localeKeyboardShortcuts?: Record<LocaleCode, KeyboardShortcut[]>;\r\n}\r\n\r\n/**\r\n * Default accessibility configuration.\r\n */\r\nexport const DEFAULT_ACCESSIBILITY_CONFIG: AccessibilityConfig = {\r\n targetLevel: 'AA',\r\n wcagVersion: '2.1',\r\n screenReaderOptimizations: true,\r\n keyboardNavigation: true,\r\n enforceColorContrast: true,\r\n minContrastRatio: 4.5,\r\n respectReducedMotion: true,\r\n focusVisible: true,\r\n highContrastSupport: true,\r\n forcedColorsSupport: true,\r\n automatedTesting: true,\r\n};\r\n\r\n/**\r\n * Common supported locales.\r\n */\r\nexport const COMMON_LOCALES: LocaleCode[] = [\r\n 'en',\r\n 'en-US',\r\n 'en-GB',\r\n 'es',\r\n 'es-ES',\r\n 'es-MX',\r\n 'fr',\r\n 'fr-FR',\r\n 'fr-CA',\r\n 'de',\r\n 'de-DE',\r\n 'it',\r\n 'it-IT',\r\n 'pt',\r\n 'pt-BR',\r\n 'pt-PT',\r\n 'ru',\r\n 'ru-RU',\r\n 'zh',\r\n 'zh-CN',\r\n 'zh-TW',\r\n 'ja',\r\n 'ja-JP',\r\n 'ko',\r\n 'ko-KR',\r\n 'ar',\r\n 'ar-SA',\r\n 'he',\r\n 'he-IL',\r\n 'hi',\r\n 'hi-IN',\r\n 'pl',\r\n 'pl-PL',\r\n 'nl',\r\n 'nl-NL',\r\n 'tr',\r\n 'tr-TR',\r\n 'sv',\r\n 'sv-SE',\r\n 'da',\r\n 'da-DK',\r\n 'no',\r\n 'nb-NO',\r\n 'fi',\r\n 'fi-FI',\r\n 'cs',\r\n 'cs-CZ',\r\n 'sk',\r\n 'sk-SK',\r\n 'hu',\r\n 'hu-HU',\r\n 'ro',\r\n 'ro-RO',\r\n 'bg',\r\n 'bg-BG',\r\n 'uk',\r\n 'uk-UA',\r\n 'el',\r\n 'el-GR',\r\n 'th',\r\n 'th-TH',\r\n 'vi',\r\n 'vi-VN',\r\n 'id',\r\n 'id-ID',\r\n 'ms',\r\n 'ms-MY',\r\n];\r\n\r\n/**\r\n * RTL locales.\r\n */\r\nexport const RTL_LOCALES: LocaleCode[] = [\r\n 'ar',\r\n 'ar-SA',\r\n 'ar-AE',\r\n 'ar-EG',\r\n 'ar-MA',\r\n 'he',\r\n 'he-IL',\r\n 'fa',\r\n 'fa-IR',\r\n 'ur',\r\n 'ur-PK',\r\n 'ps', // Pashto\r\n 'sd', // Sindhi\r\n 'yi', // Yiddish\r\n];\r\n","/**\r\n * @fileoverview PRO-28: Icons Professional Suite Types\r\n *\r\n * This module provides TypeScript types and interfaces for the comprehensive\r\n * icon system including icon management, searching, editing, and cross-framework\r\n * support.\r\n *\r\n * @module @nice2dev/ui-tools/icon-tools\r\n */\r\n\r\n// =============================================================================\r\n// CORE ICON TYPES\r\n// =============================================================================\r\n\r\n/**\r\n * Icon style variants.\r\n */\r\nexport type IconStyle =\r\n | 'solid' // Filled icons\r\n | 'outline' // Line/stroke icons\r\n | 'duotone' // Two-color icons\r\n | 'light' // Light stroke weight\r\n | 'thin' // Thinnest stroke weight\r\n | 'bold' // Bold stroke weight\r\n | 'filled' // Alias for solid\r\n | 'regular' // Default weight\r\n | 'brand'; // Brand/logo icons\r\n\r\n/**\r\n * Icon size presets.\r\n */\r\nexport type IconSize =\r\n | 'xs' // 12px\r\n | 'sm' // 16px\r\n | 'md' // 24px\r\n | 'lg' // 32px\r\n | 'xl' // 48px\r\n | '2xl' // 64px\r\n | '3xl' // 96px\r\n | '4xl'; // 128px\r\n\r\n/**\r\n * Icon size in pixels.\r\n */\r\nexport type IconSizePixels =\r\n | 12\r\n | 14\r\n | 16\r\n | 18\r\n | 20\r\n | 24\r\n | 28\r\n | 32\r\n | 36\r\n | 40\r\n | 48\r\n | 56\r\n | 64\r\n | 72\r\n | 96\r\n | 128\r\n | 192\r\n | 256\r\n | 512;\r\n\r\n/**\r\n * Icon category for organization.\r\n */\r\nexport type IconCategory =\r\n | 'action' // Action icons (edit, delete, save)\r\n | 'alert' // Alert/notification icons\r\n | 'av' // Audio/video controls\r\n | 'communication' // Email, chat, phone\r\n | 'content' // Content management\r\n | 'device' // Device/hardware\r\n | 'editor' // Text editor\r\n | 'file' // File types\r\n | 'hardware' // Hardware devices\r\n | 'image' // Image manipulation\r\n | 'maps' // Maps and navigation\r\n | 'navigation' // UI navigation\r\n | 'notification' // Notifications\r\n | 'places' // Places and buildings\r\n | 'social' // Social platforms\r\n | 'toggle' // Toggle controls\r\n | 'brand' // Brand logos\r\n | 'custom'; // Custom/user-defined\r\n\r\n/**\r\n * Domain-specific icon categories.\r\n */\r\nexport type DomainCategory =\r\n | 'business' // Business operations\r\n | 'finance' // Financial\r\n | 'healthcare' // Medical/health\r\n | 'education' // Educational\r\n | 'manufacturing' // Industrial\r\n | 'retail' // Retail/commerce\r\n | 'technology' // Tech/IT\r\n | 'gaming' // Game-related\r\n | 'science' // Scientific\r\n | 'life-management' // Personal life\r\n | 'creative' // Creative/design\r\n | 'legal' // Legal/compliance\r\n | 'hr' // Human resources\r\n | 'logistics'; // Supply chain\r\n\r\n/**\r\n * Use case for icon selection.\r\n */\r\nexport type IconUseCase =\r\n | 'toolbar' // Toolbar button\r\n | 'menu' // Menu item\r\n | 'button' // Action button\r\n | 'status' // Status indicator\r\n | 'cursor' // Mouse cursor\r\n | 'notification' // Notification badge\r\n | 'tab' // Tab icon\r\n | 'avatar' // Avatar/profile\r\n | 'decoration' // Decorative only\r\n | 'illustration' // Illustrative\r\n | 'logo' // Brand logo\r\n | 'favicon'; // Website favicon\r\n\r\n// =============================================================================\r\n// ICON METADATA\r\n// =============================================================================\r\n\r\n/**\r\n * Basic icon definition.\r\n */\r\nexport interface IconDefinition {\r\n /** Unique icon ID */\r\n id: string;\r\n /** Icon name (kebab-case) */\r\n name: string;\r\n /** Display name */\r\n displayName: string;\r\n /** SVG path data */\r\n path: string;\r\n /** Alternative paths for composite icons */\r\n paths?: string[];\r\n /** Viewbox dimensions */\r\n viewBox: string;\r\n /** Default fill rule */\r\n fillRule?: 'nonzero' | 'evenodd';\r\n /** Default stroke properties */\r\n stroke?: IconStrokeConfig;\r\n /** Icon style */\r\n style: IconStyle;\r\n /** Available sizes */\r\n sizes?: IconSizePixels[];\r\n}\r\n\r\n/**\r\n * Stroke configuration for outline icons.\r\n */\r\nexport interface IconStrokeConfig {\r\n /** Stroke width */\r\n width: number;\r\n /** Stroke line cap */\r\n lineCap: 'butt' | 'round' | 'square';\r\n /** Stroke line join */\r\n lineJoin: 'miter' | 'round' | 'bevel';\r\n /** Miter limit */\r\n miterLimit?: number;\r\n}\r\n\r\n/**\r\n * Extended icon metadata for search and organization.\r\n */\r\nexport interface IconMetadata extends IconDefinition {\r\n /** Primary category */\r\n category: IconCategory;\r\n /** Secondary categories */\r\n secondaryCategories?: IconCategory[];\r\n /** Domain tags */\r\n domains: DomainCategory[];\r\n /** Use case tags */\r\n useCases: IconUseCase[];\r\n /** Style compatibility */\r\n availableStyles: IconStyle[];\r\n /** Recommended sizes */\r\n recommendedSizes: IconSizePixels[];\r\n /** Related icon IDs */\r\n relatedIcons: string[];\r\n /** Alternative names/aliases */\r\n aliases: string[];\r\n /** Localized names */\r\n localizedNames: Record<string, string>;\r\n /** Keywords for search */\r\n keywords: string[];\r\n /** Description */\r\n description?: string;\r\n /** Version added */\r\n versionAdded: string;\r\n /** Whether icon is deprecated */\r\n deprecated?: boolean;\r\n /** Replacement icon if deprecated */\r\n replacement?: string;\r\n /** License information */\r\n license?: string;\r\n /** Author/source */\r\n author?: string;\r\n /** Unicode codepoint (if in icon font) */\r\n unicode?: string;\r\n}\r\n\r\n/**\r\n * Icon usage statistics.\r\n */\r\nexport interface IconUsageStats {\r\n /** Icon ID */\r\n iconId: string;\r\n /** Total usage count */\r\n totalUsage: number;\r\n /** Usage by project */\r\n byProject: Record<string, number>;\r\n /** Usage by component type */\r\n byComponentType: Record<string, number>;\r\n /** First used date */\r\n firstUsed: string;\r\n /** Last used date */\r\n lastUsed: string;\r\n /** Usage trend */\r\n trend: 'increasing' | 'stable' | 'decreasing';\r\n}\r\n\r\n// =============================================================================\r\n// ICON COLLECTIONS\r\n// =============================================================================\r\n\r\n/**\r\n * Icon set/collection definition.\r\n */\r\nexport interface IconSet {\r\n /** Set identifier */\r\n id: string;\r\n /** Set name */\r\n name: string;\r\n /** Set description */\r\n description: string;\r\n /** Set version */\r\n version: string;\r\n /** Total icon count */\r\n iconCount: number;\r\n /** Available styles in this set */\r\n styles: IconStyle[];\r\n /** License */\r\n license: IconLicense;\r\n /** Author/organization */\r\n author: string;\r\n /** Website URL */\r\n website?: string;\r\n /** Documentation URL */\r\n docsUrl?: string;\r\n /** Icon prefix */\r\n prefix: string;\r\n /** Default style */\r\n defaultStyle: IconStyle;\r\n /** Categories available */\r\n categories: IconCategory[];\r\n /** Icons in this set */\r\n icons: Record<string, IconDefinition>;\r\n}\r\n\r\n/**\r\n * Icon license information.\r\n */\r\nexport interface IconLicense {\r\n /** License name */\r\n name: string;\r\n /** SPDX identifier */\r\n spdx?: string;\r\n /** License URL */\r\n url?: string;\r\n /** Whether attribution is required */\r\n attributionRequired: boolean;\r\n /** Attribution text if required */\r\n attributionText?: string;\r\n /** Commercial use allowed */\r\n commercialUse: boolean;\r\n /** Modification allowed */\r\n modification: boolean;\r\n}\r\n\r\n/**\r\n * User-created icon collection.\r\n */\r\nexport interface UserIconCollection {\r\n /** Collection ID */\r\n id: string;\r\n /** Collection name */\r\n name: string;\r\n /** Description */\r\n description?: string;\r\n /** Owner user ID */\r\n ownerId: string;\r\n /** Icon IDs in collection */\r\n iconIds: string[];\r\n /** Custom icon data (user-created icons) */\r\n customIcons?: IconDefinition[];\r\n /** Created date */\r\n createdAt: string;\r\n /** Last modified date */\r\n modifiedAt: string;\r\n /** Whether collection is public */\r\n isPublic: boolean;\r\n /** Tags for organization */\r\n tags: string[];\r\n /** Cover icon ID */\r\n coverIconId?: string;\r\n}\r\n\r\n// =============================================================================\r\n// ICON SEARCH\r\n// =============================================================================\r\n\r\n/**\r\n * Icon search query.\r\n */\r\nexport interface IconSearchQuery {\r\n /** Search text */\r\n query: string;\r\n /** Filter by category */\r\n categories?: IconCategory[];\r\n /** Filter by domain */\r\n domains?: DomainCategory[];\r\n /** Filter by use case */\r\n useCases?: IconUseCase[];\r\n /** Filter by style */\r\n styles?: IconStyle[];\r\n /** Filter by size availability */\r\n sizes?: IconSizePixels[];\r\n /** Filter by icon set */\r\n sets?: string[];\r\n /** Include deprecated icons */\r\n includeDeprecated?: boolean;\r\n /** Search mode */\r\n mode?: 'exact' | 'fuzzy' | 'semantic';\r\n /** Fuzzy match threshold (0-1) */\r\n fuzzyThreshold?: number;\r\n /** Sort by */\r\n sortBy?: 'relevance' | 'name' | 'popularity' | 'recent';\r\n /** Sort direction */\r\n sortDir?: 'asc' | 'desc';\r\n /** Page number */\r\n page?: number;\r\n /** Page size */\r\n pageSize?: number;\r\n}\r\n\r\n/**\r\n * Icon search result.\r\n */\r\nexport interface IconSearchResult {\r\n /** Total matches */\r\n total: number;\r\n /** Current page */\r\n page: number;\r\n /** Page size */\r\n pageSize: number;\r\n /** Results */\r\n results: IconSearchHit[];\r\n /** Search suggestions */\r\n suggestions?: string[];\r\n /** Related searches */\r\n relatedSearches?: string[];\r\n /** Facets for filtering */\r\n facets?: IconSearchFacets;\r\n}\r\n\r\n/**\r\n * Individual search hit.\r\n */\r\nexport interface IconSearchHit {\r\n /** Icon metadata */\r\n icon: IconMetadata;\r\n /** Relevance score (0-100) */\r\n score: number;\r\n /** Matched fields */\r\n matchedFields: string[];\r\n /** Highlighted name */\r\n highlightedName?: string;\r\n /** Matched keywords */\r\n matchedKeywords?: string[];\r\n}\r\n\r\n/**\r\n * Search facets for filtering.\r\n */\r\nexport interface IconSearchFacets {\r\n /** Category counts */\r\n categories: Record<IconCategory, number>;\r\n /** Domain counts */\r\n domains: Record<DomainCategory, number>;\r\n /** Style counts */\r\n styles: Record<IconStyle, number>;\r\n /** Set counts */\r\n sets: Record<string, number>;\r\n}\r\n\r\n/**\r\n * Semantic search configuration (AI-powered).\r\n */\r\nexport interface SemanticSearchConfig {\r\n /** Enable semantic search */\r\n enabled: boolean;\r\n /** Embedding model */\r\n model: 'openai' | 'cohere' | 'local';\r\n /** Similarity threshold */\r\n threshold: number;\r\n /** Maximum results to re-rank */\r\n maxRerank: number;\r\n /** Cache embeddings */\r\n cacheEmbeddings: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// ICON EDITOR\r\n// =============================================================================\r\n\r\n/**\r\n * Icon editor configuration.\r\n */\r\nexport interface IconEditorConfig {\r\n /** Canvas size */\r\n canvasSize: number;\r\n /** Grid size */\r\n gridSize: number;\r\n /** Show grid */\r\n showGrid: boolean;\r\n /** Snap to grid */\r\n snapToGrid: boolean;\r\n /** Show guides */\r\n showGuides: boolean;\r\n /** Default stroke width */\r\n defaultStrokeWidth: number;\r\n /** Default fill color */\r\n defaultFill: string;\r\n /** Default stroke color */\r\n defaultStroke: string;\r\n /** Undo history limit */\r\n undoLimit: number;\r\n /** Auto-save interval (ms) */\r\n autoSaveInterval?: number;\r\n}\r\n\r\n/**\r\n * Icon editing operation.\r\n */\r\nexport interface IconEditOperation {\r\n /** Operation type */\r\n type: IconEditOperationType;\r\n /** Operation parameters */\r\n params: Record<string, unknown>;\r\n /** Timestamp */\r\n timestamp: string;\r\n}\r\n\r\n/**\r\n * Types of edit operations.\r\n */\r\nexport type IconEditOperationType =\r\n | 'add-path'\r\n | 'remove-path'\r\n | 'modify-path'\r\n | 'set-fill'\r\n | 'set-stroke'\r\n | 'transform'\r\n | 'flip-h'\r\n | 'flip-v'\r\n | 'rotate'\r\n | 'scale'\r\n | 'combine'\r\n | 'subtract'\r\n | 'intersect'\r\n | 'exclude'\r\n | 'simplify'\r\n | 'optimize';\r\n\r\n/**\r\n * Icon transformation.\r\n */\r\nexport interface IconTransform {\r\n /** Translation X */\r\n translateX: number;\r\n /** Translation Y */\r\n translateY: number;\r\n /** Scale X */\r\n scaleX: number;\r\n /** Scale Y */\r\n scaleY: number;\r\n /** Rotation in degrees */\r\n rotate: number;\r\n /** Rotation origin X */\r\n originX: number;\r\n /** Rotation origin Y */\r\n originY: number;\r\n /** Skew X */\r\n skewX: number;\r\n /** Skew Y */\r\n skewY: number;\r\n}\r\n\r\n/**\r\n * Color modification options.\r\n */\r\nexport interface IconColorOptions {\r\n /** Primary color */\r\n primary: string;\r\n /** Secondary color (for duotone) */\r\n secondary?: string;\r\n /** Background color */\r\n background?: string;\r\n /** Opacity */\r\n opacity: number;\r\n /** Color mode */\r\n colorMode: 'single' | 'gradient' | 'duotone';\r\n /** Gradient configuration */\r\n gradient?: IconGradient;\r\n}\r\n\r\n/**\r\n * Gradient configuration for icons.\r\n */\r\nexport interface IconGradient {\r\n /** Gradient type */\r\n type: 'linear' | 'radial';\r\n /** Gradient angle (for linear) */\r\n angle?: number;\r\n /** Gradient stops */\r\n stops: GradientStop[];\r\n /** Center X (for radial) */\r\n cx?: number;\r\n /** Center Y (for radial) */\r\n cy?: number;\r\n /** Radius (for radial) */\r\n r?: number;\r\n}\r\n\r\n/**\r\n * Gradient color stop.\r\n */\r\nexport interface GradientStop {\r\n /** Offset (0-1) */\r\n offset: number;\r\n /** Color */\r\n color: string;\r\n /** Opacity */\r\n opacity?: number;\r\n}\r\n\r\n/**\r\n * Icon combination/composition.\r\n */\r\nexport interface IconComposition {\r\n /** Base icon */\r\n base: IconDefinition;\r\n /** Overlay icon (badge) */\r\n overlay?: IconDefinition;\r\n /** Overlay position */\r\n overlayPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'center';\r\n /** Overlay scale */\r\n overlayScale?: number;\r\n /** Overlay offset */\r\n overlayOffset?: { x: number; y: number };\r\n /** Whether to create cutout for overlay */\r\n cutout?: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// ICON SET CREATOR\r\n// =============================================================================\r\n\r\n/**\r\n * Icon set creation configuration.\r\n */\r\nexport interface IconSetCreatorConfig {\r\n /** Set name */\r\n name: string;\r\n /** Set prefix */\r\n prefix: string;\r\n /** Selected icons */\r\n icons: string[];\r\n /** Custom naming rules */\r\n naming: IconNamingConfig;\r\n /** Export configuration */\r\n export: IconSetExportConfig;\r\n /** Include metadata */\r\n includeMetadata: boolean;\r\n /** Tree-shaking support */\r\n treeShakeable: boolean;\r\n}\r\n\r\n/**\r\n * Naming configuration for icon sets.\r\n */\r\nexport interface IconNamingConfig {\r\n /** Case style */\r\n caseStyle: 'camelCase' | 'PascalCase' | 'kebab-case' | 'snake_case';\r\n /** Prefix to add */\r\n prefix?: string;\r\n /** Suffix to add */\r\n suffix?: string;\r\n /** Word replacements */\r\n replacements?: Record<string, string>;\r\n /** Remove words */\r\n removeWords?: string[];\r\n}\r\n\r\n/**\r\n * Icon set export configuration.\r\n */\r\nexport interface IconSetExportConfig {\r\n /** Export formats */\r\n formats: IconExportFormat[];\r\n /** Output directory */\r\n outputDir: string;\r\n /** Generate index file */\r\n generateIndex: boolean;\r\n /** Generate TypeScript types */\r\n generateTypes: boolean;\r\n /** Generate CSS */\r\n generateCSS: boolean;\r\n /** Generate icon font */\r\n generateFont: boolean;\r\n /** Font configuration */\r\n fontConfig?: IconFontConfig;\r\n /** Sprite configuration */\r\n spriteConfig?: IconSpriteConfig;\r\n}\r\n\r\n/**\r\n * Icon export formats.\r\n */\r\nexport type IconExportFormat =\r\n | 'svg'\r\n | 'png'\r\n | 'webp'\r\n | 'ico'\r\n | 'icns'\r\n | 'pdf'\r\n | 'jsx'\r\n | 'tsx'\r\n | 'vue'\r\n | 'svelte'\r\n | 'json'\r\n | 'css'\r\n | 'scss'\r\n | 'woff2'\r\n | 'ttf';\r\n\r\n/**\r\n * Icon font generation configuration.\r\n */\r\nexport interface IconFontConfig {\r\n /** Font family name */\r\n fontName: string;\r\n /** Class prefix */\r\n classPrefix: string;\r\n /** Unicode starting point */\r\n unicodeStart: number;\r\n /** Font formats to generate */\r\n formats: ('woff2' | 'woff' | 'ttf' | 'eot' | 'svg')[];\r\n /** Normalize icon sizes */\r\n normalize: boolean;\r\n /** Center icons */\r\n centerHorizontally: boolean;\r\n centerVertically: boolean;\r\n /** Font height */\r\n fontHeight: number;\r\n /** Descent */\r\n descent: number;\r\n /** Round values */\r\n round: number;\r\n}\r\n\r\n/**\r\n * SVG sprite configuration.\r\n */\r\nexport interface IconSpriteConfig {\r\n /** Sprite filename */\r\n filename: string;\r\n /** Symbol mode (versus inline) */\r\n symbolMode: boolean;\r\n /** Include style element */\r\n includeStyle: boolean;\r\n /** Namespace prefix */\r\n symbolPrefix: string;\r\n}\r\n\r\n// =============================================================================\r\n// ICON PREVIEW\r\n// =============================================================================\r\n\r\n/**\r\n * Icon preview configuration.\r\n */\r\nexport interface IconPreviewConfig {\r\n /** Preview sizes */\r\n sizes: IconSizePixels[];\r\n /** Show in both themes */\r\n showBothThemes: boolean;\r\n /** Background options */\r\n backgrounds: PreviewBackground[];\r\n /** Show grid */\r\n showGrid: boolean;\r\n /** Grid color */\r\n gridColor: string;\r\n /** Animation preview */\r\n animationPreview: boolean;\r\n /** Compare mode */\r\n compareMode: boolean;\r\n /** Compare icons */\r\n compareIcons?: string[];\r\n}\r\n\r\n/**\r\n * Preview background options.\r\n */\r\nexport interface PreviewBackground {\r\n /** Background name */\r\n name: string;\r\n /** Background color or image */\r\n value: string;\r\n /** Whether it's a pattern */\r\n isPattern?: boolean;\r\n /** Contrast for icon color suggestion */\r\n suggestedIconColor?: string;\r\n}\r\n\r\n/**\r\n * Animation preview configuration.\r\n */\r\nexport interface IconAnimationPreview {\r\n /** Animation type */\r\n type: IconAnimationType;\r\n /** Duration in ms */\r\n duration: number;\r\n /** Easing function */\r\n easing: string;\r\n /** Iteration count */\r\n iterations: number | 'infinite';\r\n /** Direction */\r\n direction: 'normal' | 'reverse' | 'alternate' | 'alternate-reverse';\r\n /** Delay in ms */\r\n delay: number;\r\n}\r\n\r\n/**\r\n * Icon animation types.\r\n */\r\nexport type IconAnimationType =\r\n | 'spin'\r\n | 'pulse'\r\n | 'bounce'\r\n | 'shake'\r\n | 'flip'\r\n | 'beat'\r\n | 'fade'\r\n | 'beat-fade'\r\n | 'spin-pulse'\r\n | 'custom';\r\n\r\n// =============================================================================\r\n// FAVICON GENERATOR\r\n// =============================================================================\r\n\r\n/**\r\n * Favicon generation configuration.\r\n */\r\nexport interface FaviconGeneratorConfig {\r\n /** Source icon */\r\n sourceIcon: IconDefinition | string; // icon ID or definition\r\n /** App name */\r\n appName: string;\r\n /** Short name */\r\n shortName: string;\r\n /** Theme color */\r\n themeColor: string;\r\n /** Background color */\r\n backgroundColor: string;\r\n /** Display mode */\r\n display: 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser';\r\n /** Orientation */\r\n orientation: 'any' | 'portrait' | 'landscape';\r\n /** Start URL */\r\n startUrl: string;\r\n /** Sizes to generate */\r\n sizes: FaviconSize[];\r\n /** Generate manifest.json */\r\n generateManifest: boolean;\r\n /** Generate browserconfig.xml (Windows) */\r\n generateBrowserConfig: boolean;\r\n /** Output configuration */\r\n output: FaviconOutputConfig;\r\n}\r\n\r\n/**\r\n * Favicon sizes to generate.\r\n */\r\nexport interface FaviconSize {\r\n /** Width */\r\n width: number;\r\n /** Height */\r\n height: number;\r\n /** Purpose */\r\n purpose: 'any' | 'maskable' | 'monochrome' | 'favicon' | 'apple-touch';\r\n /** Filename */\r\n filename?: string;\r\n /** Format */\r\n format: 'png' | 'ico' | 'svg';\r\n}\r\n\r\n/**\r\n * Standard favicon sizes.\r\n */\r\nexport const STANDARD_FAVICON_SIZES: FaviconSize[] = [\r\n { width: 16, height: 16, purpose: 'favicon', format: 'ico' },\r\n { width: 32, height: 32, purpose: 'favicon', format: 'png' },\r\n { width: 48, height: 48, purpose: 'favicon', format: 'png' },\r\n { width: 180, height: 180, purpose: 'apple-touch', format: 'png' },\r\n { width: 192, height: 192, purpose: 'any', format: 'png' },\r\n { width: 512, height: 512, purpose: 'any', format: 'png' },\r\n { width: 512, height: 512, purpose: 'maskable', format: 'png' },\r\n];\r\n\r\n/**\r\n * Favicon output configuration.\r\n */\r\nexport interface FaviconOutputConfig {\r\n /** Output directory */\r\n outputDir: string;\r\n /** Base path for URLs */\r\n basePath: string;\r\n /** Generate HTML link tags */\r\n generateHtml: boolean;\r\n /** Generate meta tags */\r\n generateMeta: boolean;\r\n}\r\n\r\n/**\r\n * Generated favicon result.\r\n */\r\nexport interface FaviconGenerationResult {\r\n /** Generated files */\r\n files: GeneratedFile[];\r\n /** HTML to include */\r\n html: string;\r\n /** manifest.json content */\r\n manifest?: Record<string, unknown>;\r\n /** browserconfig.xml content */\r\n browserConfig?: string;\r\n}\r\n\r\n/**\r\n * Generated file information.\r\n */\r\nexport interface GeneratedFile {\r\n /** Filename */\r\n filename: string;\r\n /** File path */\r\n path: string;\r\n /** File size in bytes */\r\n size: number;\r\n /** MIME type */\r\n mimeType: string;\r\n /** Dimensions if image */\r\n dimensions?: { width: number; height: number };\r\n}\r\n\r\n// =============================================================================\r\n// CROSS-FRAMEWORK SUPPORT\r\n// =============================================================================\r\n\r\n/**\r\n * Framework-specific icon component configuration.\r\n */\r\nexport interface FrameworkIconConfig {\r\n /** Component name */\r\n componentName: string;\r\n /** File extension */\r\n fileExtension: string;\r\n /** Import style */\r\n importStyle: 'named' | 'default' | 'namespace';\r\n /** Props interface name */\r\n propsInterfaceName: string;\r\n /** Supports tree-shaking */\r\n treeShakeable: boolean;\r\n /** SSR support */\r\n ssrSupport: boolean;\r\n /** TypeScript support */\r\n typeScriptSupport: boolean;\r\n}\r\n\r\n/**\r\n * React icon component props.\r\n */\r\nexport interface ReactIconProps {\r\n /** Icon size */\r\n size?: IconSize | number;\r\n /** Icon color */\r\n color?: string;\r\n /** Additional class names */\r\n className?: string;\r\n /** Inline styles */\r\n style?: React.CSSProperties;\r\n /** Title for accessibility */\r\n title?: string;\r\n /** Description for accessibility */\r\n desc?: string;\r\n /** Whether icon is decorative (aria-hidden) */\r\n decorative?: boolean;\r\n /** Animation */\r\n animation?: IconAnimationType;\r\n /** Animation duration */\r\n animationDuration?: number;\r\n /** onClick handler */\r\n onClick?: (event: React.MouseEvent) => void;\r\n}\r\n\r\n/**\r\n * Vue icon component props.\r\n */\r\nexport interface VueIconProps {\r\n /** Icon size */\r\n size?: IconSize | number;\r\n /** Icon color */\r\n color?: string;\r\n /** Additional class names */\r\n class?: string;\r\n /** Title for accessibility */\r\n title?: string;\r\n /** Animation */\r\n animation?: IconAnimationType;\r\n}\r\n\r\n/**\r\n * Angular icon component inputs.\r\n */\r\nexport interface AngularIconInputs {\r\n /** Icon name */\r\n name: string;\r\n /** Icon size */\r\n size: IconSize | number;\r\n /** Icon color */\r\n color: string;\r\n /** Title for accessibility */\r\n title: string;\r\n /** Animation */\r\n animation: IconAnimationType;\r\n}\r\n\r\n/**\r\n * Web Component (Lit) icon properties.\r\n */\r\nexport interface WebComponentIconProps {\r\n /** Icon name */\r\n name: string;\r\n /** Icon size */\r\n size: IconSize | number;\r\n /** Icon color */\r\n color: string;\r\n /** Title for accessibility */\r\n title: string;\r\n}\r\n\r\n/**\r\n * Blazor icon parameters.\r\n */\r\nexport interface BlazorIconParameters {\r\n /** Icon name */\r\n Name: string;\r\n /** Icon size */\r\n Size: IconSize | number;\r\n /** Icon color */\r\n Color: string;\r\n /** CSS class */\r\n CssClass: string;\r\n /** Title for accessibility */\r\n Title: string;\r\n}\r\n\r\n/**\r\n * Flutter IconData equivalent.\r\n */\r\nexport interface FlutterIconData {\r\n /** Codepoint */\r\n codePoint: number;\r\n /** Font family */\r\n fontFamily: string;\r\n /** Font package */\r\n fontPackage: string;\r\n /** Match text direction */\r\n matchTextDirection: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// DESIGN TOOL INTEGRATION\r\n// =============================================================================\r\n\r\n/**\r\n * Figma plugin configuration.\r\n */\r\nexport interface FigmaPluginConfig {\r\n /** Plugin ID */\r\n pluginId: string;\r\n /** Sync configuration */\r\n sync: FigmaSyncConfig;\r\n /** Insert options */\r\n insertOptions: FigmaInsertOptions;\r\n}\r\n\r\n/**\r\n * Figma sync configuration.\r\n */\r\nexport interface FigmaSyncConfig {\r\n /** Auto-sync enabled */\r\n autoSync: boolean;\r\n /** Sync interval in minutes */\r\n syncInterval: number;\r\n /** Which collections to sync */\r\n collections: string[];\r\n /** Sync direction */\r\n direction: 'push' | 'pull' | 'both';\r\n}\r\n\r\n/**\r\n * Figma insert options.\r\n */\r\nexport interface FigmaInsertOptions {\r\n /** Insert as component */\r\n asComponent: boolean;\r\n /** Auto-layout */\r\n autoLayout: boolean;\r\n /** Default size */\r\n defaultSize: number;\r\n /** Maintain aspect ratio */\r\n maintainAspectRatio: boolean;\r\n}\r\n\r\n/**\r\n * Sketch plugin configuration.\r\n */\r\nexport interface SketchPluginConfig {\r\n /** Plugin identifier */\r\n identifier: string;\r\n /** Library configuration */\r\n library: SketchLibraryConfig;\r\n}\r\n\r\n/**\r\n * Sketch library configuration.\r\n */\r\nexport interface SketchLibraryConfig {\r\n /** Library name */\r\n name: string;\r\n /** Library path */\r\n path: string;\r\n /** Auto-update */\r\n autoUpdate: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// ICON ANALYTICS\r\n// =============================================================================\r\n\r\n/**\r\n * Icon analytics configuration.\r\n */\r\nexport interface IconAnalyticsConfig {\r\n /** Enable analytics */\r\n enabled: boolean;\r\n /** Track usage */\r\n trackUsage: boolean;\r\n /** Track searches */\r\n trackSearches: boolean;\r\n /** Retention days */\r\n retentionDays: number;\r\n /** Anonymize data */\r\n anonymize: boolean;\r\n}\r\n\r\n/**\r\n * Icon analytics dashboard data.\r\n */\r\nexport interface IconAnalyticsDashboard {\r\n /** Time period */\r\n period: { start: string; end: string };\r\n /** Total icons used */\r\n totalIconsUsed: number;\r\n /** Unique icons used */\r\n uniqueIconsUsed: number;\r\n /** Most used icons */\r\n mostUsed: IconUsageStats[];\r\n /** Least used icons */\r\n leastUsed: IconUsageStats[];\r\n /** Unused icons */\r\n unusedIcons: string[];\r\n /** Search analytics */\r\n searchAnalytics: SearchAnalytics;\r\n /** Missing icon requests */\r\n missingIconRequests: MissingIconRequest[];\r\n}\r\n\r\n/**\r\n * Search analytics data.\r\n */\r\nexport interface SearchAnalytics {\r\n /** Total searches */\r\n totalSearches: number;\r\n /** Unique queries */\r\n uniqueQueries: number;\r\n /** Top queries */\r\n topQueries: { query: string; count: number }[];\r\n /** Zero-result queries */\r\n zeroResultQueries: { query: string; count: number }[];\r\n /** Average results per search */\r\n avgResultsPerSearch: number;\r\n /** Click-through rate */\r\n clickThroughRate: number;\r\n}\r\n\r\n/**\r\n * Missing icon request.\r\n */\r\nexport interface MissingIconRequest {\r\n /** Requested icon name/description */\r\n request: string;\r\n /** Number of times requested */\r\n count: number;\r\n /** First requested date */\r\n firstRequested: string;\r\n /** Users who requested */\r\n userCount: number;\r\n /** Suggested alternatives */\r\n suggestedAlternatives?: string[];\r\n}\r\n\r\n// =============================================================================\r\n// CURSOR ICONS\r\n// =============================================================================\r\n\r\n/**\r\n * Cursor icon definition.\r\n */\r\nexport interface CursorIconDefinition extends IconDefinition {\r\n /** Cursor type */\r\n cursorType: CursorType;\r\n /** Hotspot X coordinate */\r\n hotspotX: number;\r\n /** Hotspot Y coordinate */\r\n hotspotY: number;\r\n /** Animation frames (for animated cursors) */\r\n frames?: CursorFrame[];\r\n /** Frame rate for animation */\r\n frameRate?: number;\r\n}\r\n\r\n/**\r\n * Standard cursor types.\r\n */\r\nexport type CursorType =\r\n | 'pointer'\r\n | 'crosshair'\r\n | 'move'\r\n | 'resize-n'\r\n | 'resize-s'\r\n | 'resize-e'\r\n | 'resize-w'\r\n | 'resize-ne'\r\n | 'resize-nw'\r\n | 'resize-se'\r\n | 'resize-sw'\r\n | 'resize-ns'\r\n | 'resize-ew'\r\n | 'resize-nesw'\r\n | 'resize-nwse'\r\n | 'text'\r\n | 'cell'\r\n | 'grab'\r\n | 'grabbing'\r\n | 'zoom-in'\r\n | 'zoom-out'\r\n | 'rotate'\r\n | 'draw'\r\n | 'brush'\r\n | 'eraser'\r\n | 'eyedropper'\r\n | 'bucket'\r\n | 'pen'\r\n | 'line'\r\n | 'rectangle'\r\n | 'ellipse'\r\n | 'wait'\r\n | 'progress'\r\n | 'not-allowed'\r\n | 'help'\r\n | 'context-menu'\r\n | 'custom';\r\n\r\n/**\r\n * Cursor animation frame.\r\n */\r\nexport interface CursorFrame {\r\n /** Frame icon/image */\r\n icon: IconDefinition;\r\n /** Frame duration in ms */\r\n duration: number;\r\n}\r\n\r\n// =============================================================================\r\n// HIGH-DPI / DESKTOP ICONS\r\n// =============================================================================\r\n\r\n/**\r\n * Desktop/high-DPI icon configuration.\r\n */\r\nexport interface DesktopIconConfig {\r\n /** Base icon */\r\n baseIcon: IconDefinition;\r\n /** Sizes to generate */\r\n sizes: IconSizePixels[];\r\n /** High-DPI scales */\r\n scales: (1 | 1.5 | 2 | 3 | 4)[];\r\n /** Platform-specific exports */\r\n platforms: DesktopIconPlatform[];\r\n}\r\n\r\n/**\r\n * Desktop platform targets.\r\n */\r\nexport interface DesktopIconPlatform {\r\n /** Platform name */\r\n platform: 'windows' | 'macos' | 'linux';\r\n /** Format */\r\n format: 'ico' | 'icns' | 'png';\r\n /** Sizes for this platform */\r\n sizes: IconSizePixels[];\r\n /** Output filename */\r\n filename: string;\r\n}\r\n\r\n/**\r\n * Windows ICO file generation.\r\n */\r\nexport interface WindowsIcoConfig {\r\n /** Sizes to include */\r\n sizes: (16 | 32 | 48 | 64 | 128 | 256)[];\r\n /** Include 256-color versions */\r\n include256Color: boolean;\r\n /** Compression */\r\n compress: boolean;\r\n}\r\n\r\n/**\r\n * macOS ICNS file generation.\r\n */\r\nexport interface MacOSIcnsConfig {\r\n /** Sizes to include */\r\n sizes: (16 | 32 | 64 | 128 | 256 | 512 | 1024)[];\r\n /** Include @2x versions */\r\n includeRetina: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// THEMATIC ICON PACKAGES\r\n// =============================================================================\r\n\r\n/**\r\n * Thematic icon package definition.\r\n */\r\nexport interface ThematicIconPackage {\r\n /** Package name */\r\n name: string;\r\n /** npm package name */\r\n npmName: string;\r\n /** Description */\r\n description: string;\r\n /** Total icon count */\r\n iconCount: number;\r\n /** Categories included */\r\n categories: string[];\r\n /** Domains covered */\r\n domains: DomainCategory[];\r\n /** Dependencies on other packages */\r\n dependencies: string[];\r\n /** Version */\r\n version: string;\r\n}\r\n\r\n/**\r\n * Available thematic packages.\r\n */\r\nexport const THEMATIC_PACKAGES: ThematicIconPackage[] = [\r\n {\r\n name: 'Business Icons',\r\n npmName: '@nice2dev/icons-business',\r\n description: 'All ERP-related icons for business applications',\r\n iconCount: 500,\r\n categories: ['accounting', 'hr', 'crm', 'production', 'warehouse', 'sales', 'purchasing'],\r\n domains: ['business', 'finance', 'hr', 'logistics'],\r\n dependencies: [],\r\n version: '1.0.0',\r\n },\r\n {\r\n name: 'Education Icons',\r\n npmName: '@nice2dev/icons-education',\r\n description: 'Educational, scientific, and mathematical icons',\r\n iconCount: 300,\r\n categories: ['subjects', 'learning', 'school', 'science', 'math'],\r\n domains: ['education', 'science'],\r\n dependencies: [],\r\n version: '1.0.0',\r\n },\r\n {\r\n name: 'Tech Icons',\r\n npmName: '@nice2dev/icons-tech',\r\n description: 'Development tools, infrastructure, cloud, and containers',\r\n iconCount: 400,\r\n categories: ['devtools', 'infrastructure', 'cloud', 'containers', 'networking'],\r\n domains: ['technology'],\r\n dependencies: [],\r\n version: '1.0.0',\r\n },\r\n {\r\n name: 'Media Icons',\r\n npmName: '@nice2dev/icons-media',\r\n description: 'Audio, video, graphics, 3D, and streaming icons',\r\n iconCount: 350,\r\n categories: ['audio', 'video', 'graphics', '3d', 'streaming'],\r\n domains: ['creative'],\r\n dependencies: [],\r\n version: '1.0.0',\r\n },\r\n {\r\n name: 'Social Icons',\r\n npmName: '@nice2dev/icons-social',\r\n description: 'Social platforms, reactions, and messaging icons',\r\n iconCount: 200,\r\n categories: ['platforms', 'reactions', 'messaging'],\r\n domains: [],\r\n dependencies: [],\r\n version: '1.0.0',\r\n },\r\n {\r\n name: 'Game Icons',\r\n npmName: '@nice2dev/icons-game',\r\n description: 'Characters, items, UI elements, and game actions',\r\n iconCount: 400,\r\n categories: ['characters', 'items', 'ui', 'actions'],\r\n domains: ['gaming'],\r\n dependencies: [],\r\n version: '1.0.0',\r\n },\r\n {\r\n name: 'Life Management Icons',\r\n npmName: '@nice2dev/icons-life',\r\n description: 'Personal finance, health, productivity, and home icons',\r\n iconCount: 300,\r\n categories: ['finance', 'health', 'productivity', 'home', 'family'],\r\n domains: ['life-management'],\r\n dependencies: [],\r\n version: '1.0.0',\r\n },\r\n {\r\n name: 'All Icons',\r\n npmName: '@nice2dev/icons-all',\r\n description: 'Meta-package containing all icon packs',\r\n iconCount: 2500,\r\n categories: [],\r\n domains: [],\r\n dependencies: [\r\n '@nice2dev/icons-business',\r\n '@nice2dev/icons-education',\r\n '@nice2dev/icons-tech',\r\n '@nice2dev/icons-media',\r\n '@nice2dev/icons-social',\r\n '@nice2dev/icons-game',\r\n '@nice2dev/icons-life',\r\n ],\r\n version: '1.0.0',\r\n },\r\n];\r\n"],"names":["OPENAPI_LINT_RULES","formatBytes","bytes","decimals","k","dm","sizes","i","formatSpeed","bytesPerSecond","unit","value","formatDuration","seconds","hours","minutes","secs","calculateETA","remainingBytes","speedBytesPerSecond","parseDownloadUrl","url","parseMagnetLink","parsed","filename","extension","_a","protocol","getFileType","magnetUrl","params","infoHash","displayName","trackers","exactLength","keywords","types","type","extensions","generateDownloadId","validateChecksum","data","checksum","algorithm","hashBuffer","b","createDownloadSegments","totalSize","segmentCount","segmentSize","segments","start","end","DownloadManager","config","event","callback","listeners","error","options","id","download","urls","deleteFile","items","sum","d","totalDownloaded","status","category","abortController","controller","priority","direction","index","updates","limit","max","downloads","downloaded","total","totalSpeed","signal","response","contentLength","reader","_b","chunks","lastUpdate","bytesInInterval","done","now","elapsed","speed","offset","chunk","blob","a","auth","samples","queued","priorityOrder","downloadManagerInstance","getDownloadManager","disposeDownloadManager","useDownloadManager","autoRefresh","refreshInterval","manager","useMemo","queue","setQueue","useState","stats","setStats","useEffect","handleQueueChange","unsubscribers","interval","unsub","activeDownloads","addDownload","useCallback","opts","addDownloads","generateInfoHash","chars","hash","generatePeerId","clientId","randomPart","parseMagnetUri","magnetUri","xt","createMagnetUri","torrent","tracker","calculatePieces","pieceSize","createPieceStatus","pieceCount","formatPeerCount","connected","calculateTorrentHealth","seeders","leechers","ratio","createFileSelection","files","f","filterFilesByExtension","ext","getVideoFiles","getAudioFiles","getLargestFile","largest","file","TorrentClient","magnetInfo","v","deleteData","fileIndex","wanted","enabled","torrents","totalDownload","totalUpload","downloadSpeedSum","uploadSpeedSum","totalPeers","t","baseSpeed","downloadSpeed","increment","uploadSpeed","createTorrent","name","comment","isPrivate","webSeeds","magnetLink","torrentFile","torrentClientInstance","getTorrentClient","disposeTorrentClient","useTorrentClient","client","setTorrents","statistics","setStatistics","handleUpdate","activeTorrents","uri","del","idx","w","en","lim","DEFAULT_TRACELESS_POLICY","DEFAULT_FULL_POLICY","MODE_CAPABILITIES","WCAG_AA_CONTRAST","WCAG_AAA_CONTRAST","DEFAULT_ACCESSIBILITY_CONFIG","COMMON_LOCALES","RTL_LOCALES","STANDARD_FAVICON_SIZES","THEMATIC_PACKAGES"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/api-designer.ts","../src/download-manager.ts","../src/torrent-client.ts","../src/traceless.ts","../src/accessibility-i18n.ts","../src/icon-tools.ts"],"sourcesContent":["/**\r\n * @file api-designer.ts\r\n * @module @nice2dev/ui-tools\r\n * @description PRO-13.1 — API Designer\r\n *\r\n * Types for API design tools: OpenAPI, GraphQL, AsyncAPI, Protocol Buffers,\r\n * Thrift, Avro, schema visualization, mock servers, code generation, and more.\r\n */\r\n\r\n// =============================================================================\r\n// Common Types\r\n// =============================================================================\r\n\r\n/** HTTP method type */\r\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'TRACE';\r\n\r\n/** Parameter location */\r\nexport type ParameterLocation = 'path' | 'query' | 'header' | 'cookie' | 'body';\r\n\r\n/** Data format type */\r\nexport type SchemaFormat =\r\n | 'int32'\r\n | 'int64'\r\n | 'float'\r\n | 'double'\r\n | 'byte'\r\n | 'binary'\r\n | 'date'\r\n | 'date-time'\r\n | 'password'\r\n | 'email'\r\n | 'uri'\r\n | 'uuid'\r\n | 'hostname'\r\n | 'ipv4'\r\n | 'ipv6';\r\n\r\n/** Primitive schema type */\r\nexport type SchemaType = 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object' | 'null';\r\n\r\n// =============================================================================\r\n// OpenAPI / Swagger Editor\r\n// =============================================================================\r\n\r\n/** OpenAPI specification document */\r\nexport interface OpenAPISpec {\r\n /** OpenAPI version (3.0.x, 3.1.x) */\r\n openapi: string;\r\n /** API information */\r\n info: OpenAPIInfo;\r\n /** Server URLs */\r\n servers?: OpenAPIServer[];\r\n /** API paths */\r\n paths: Record<string, OpenAPIPathItem>;\r\n /** Reusable components */\r\n components?: OpenAPIComponents;\r\n /** Security requirements */\r\n security?: OpenAPISecurityRequirement[];\r\n /** Tags for grouping */\r\n tags?: OpenAPITag[];\r\n /** External documentation */\r\n externalDocs?: OpenAPIExternalDocs;\r\n}\r\n\r\n/** API info object */\r\nexport interface OpenAPIInfo {\r\n /** API title */\r\n title: string;\r\n /** API version */\r\n version: string;\r\n /** API description */\r\n description?: string;\r\n /** Terms of service URL */\r\n termsOfService?: string;\r\n /** Contact information */\r\n contact?: OpenAPIContact;\r\n /** License information */\r\n license?: OpenAPILicense;\r\n}\r\n\r\n/** Contact information */\r\nexport interface OpenAPIContact {\r\n name?: string;\r\n url?: string;\r\n email?: string;\r\n}\r\n\r\n/** License information */\r\nexport interface OpenAPILicense {\r\n name: string;\r\n url?: string;\r\n identifier?: string; // SPDX identifier (3.1+)\r\n}\r\n\r\n/** Server object */\r\nexport interface OpenAPIServer {\r\n url: string;\r\n description?: string;\r\n variables?: Record<string, OpenAPIServerVariable>;\r\n}\r\n\r\n/** Server variable */\r\nexport interface OpenAPIServerVariable {\r\n default: string;\r\n description?: string;\r\n enum?: string[];\r\n}\r\n\r\n/** Path item object */\r\nexport interface OpenAPIPathItem {\r\n summary?: string;\r\n description?: string;\r\n get?: OpenAPIOperation;\r\n post?: OpenAPIOperation;\r\n put?: OpenAPIOperation;\r\n patch?: OpenAPIOperation;\r\n delete?: OpenAPIOperation;\r\n head?: OpenAPIOperation;\r\n options?: OpenAPIOperation;\r\n trace?: OpenAPIOperation;\r\n parameters?: OpenAPIParameter[];\r\n}\r\n\r\n/** Operation object */\r\nexport interface OpenAPIOperation {\r\n operationId?: string;\r\n summary?: string;\r\n description?: string;\r\n tags?: string[];\r\n parameters?: OpenAPIParameter[];\r\n requestBody?: OpenAPIRequestBody;\r\n responses: Record<string, OpenAPIResponse>;\r\n security?: OpenAPISecurityRequirement[];\r\n deprecated?: boolean;\r\n servers?: OpenAPIServer[];\r\n externalDocs?: OpenAPIExternalDocs;\r\n 'x-codegen-request-body-name'?: string;\r\n callbacks?: Record<string, Record<string, OpenAPIPathItem>>;\r\n}\r\n\r\n/** Parameter object */\r\nexport interface OpenAPIParameter {\r\n name: string;\r\n in: ParameterLocation;\r\n description?: string;\r\n required?: boolean;\r\n deprecated?: boolean;\r\n allowEmptyValue?: boolean;\r\n schema?: OpenAPISchema;\r\n style?: ParameterStyle;\r\n explode?: boolean;\r\n example?: unknown;\r\n examples?: Record<string, OpenAPIExample>;\r\n}\r\n\r\n/** Parameter serialization style */\r\nexport type ParameterStyle =\r\n | 'matrix'\r\n | 'label'\r\n | 'form'\r\n | 'simple'\r\n | 'spaceDelimited'\r\n | 'pipeDelimited'\r\n | 'deepObject';\r\n\r\n/** Request body object */\r\nexport interface OpenAPIRequestBody {\r\n description?: string;\r\n required?: boolean;\r\n content: Record<string, OpenAPIMediaType>;\r\n}\r\n\r\n/** Media type object */\r\nexport interface OpenAPIMediaType {\r\n schema?: OpenAPISchema;\r\n example?: unknown;\r\n examples?: Record<string, OpenAPIExample>;\r\n encoding?: Record<string, OpenAPIEncoding>;\r\n}\r\n\r\n/** Encoding object for multipart */\r\nexport interface OpenAPIEncoding {\r\n contentType?: string;\r\n headers?: Record<string, OpenAPIHeader>;\r\n style?: ParameterStyle;\r\n explode?: boolean;\r\n allowReserved?: boolean;\r\n}\r\n\r\n/** Header object */\r\nexport interface OpenAPIHeader extends Omit<OpenAPIParameter, 'name' | 'in'> {}\r\n\r\n/** Response object */\r\nexport interface OpenAPIResponse {\r\n description: string;\r\n headers?: Record<string, OpenAPIHeader>;\r\n content?: Record<string, OpenAPIMediaType>;\r\n links?: Record<string, OpenAPILink>;\r\n}\r\n\r\n/** Link object */\r\nexport interface OpenAPILink {\r\n operationRef?: string;\r\n operationId?: string;\r\n parameters?: Record<string, unknown>;\r\n requestBody?: unknown;\r\n description?: string;\r\n server?: OpenAPIServer;\r\n}\r\n\r\n/** Schema object */\r\nexport interface OpenAPISchema {\r\n $ref?: string;\r\n type?: SchemaType | SchemaType[];\r\n format?: SchemaFormat | string;\r\n title?: string;\r\n description?: string;\r\n default?: unknown;\r\n example?: unknown;\r\n enum?: unknown[];\r\n const?: unknown;\r\n nullable?: boolean; // 3.0 only, deprecated in 3.1\r\n readOnly?: boolean;\r\n writeOnly?: boolean;\r\n deprecated?: boolean;\r\n\r\n // String validation\r\n minLength?: number;\r\n maxLength?: number;\r\n pattern?: string;\r\n\r\n // Numeric validation\r\n minimum?: number;\r\n maximum?: number;\r\n exclusiveMinimum?: number | boolean;\r\n exclusiveMaximum?: number | boolean;\r\n multipleOf?: number;\r\n\r\n // Array validation\r\n items?: OpenAPISchema;\r\n minItems?: number;\r\n maxItems?: number;\r\n uniqueItems?: boolean;\r\n contains?: OpenAPISchema;\r\n minContains?: number;\r\n maxContains?: number;\r\n\r\n // Object validation\r\n properties?: Record<string, OpenAPISchema>;\r\n additionalProperties?: boolean | OpenAPISchema;\r\n required?: string[];\r\n minProperties?: number;\r\n maxProperties?: number;\r\n patternProperties?: Record<string, OpenAPISchema>;\r\n propertyNames?: OpenAPISchema;\r\n\r\n // Composition\r\n allOf?: OpenAPISchema[];\r\n oneOf?: OpenAPISchema[];\r\n anyOf?: OpenAPISchema[];\r\n not?: OpenAPISchema;\r\n discriminator?: OpenAPIDiscriminator;\r\n\r\n // External\r\n externalDocs?: OpenAPIExternalDocs;\r\n xml?: OpenAPIXml;\r\n}\r\n\r\n/** Discriminator object */\r\nexport interface OpenAPIDiscriminator {\r\n propertyName: string;\r\n mapping?: Record<string, string>;\r\n}\r\n\r\n/** XML object */\r\nexport interface OpenAPIXml {\r\n name?: string;\r\n namespace?: string;\r\n prefix?: string;\r\n attribute?: boolean;\r\n wrapped?: boolean;\r\n}\r\n\r\n/** Example object */\r\nexport interface OpenAPIExample {\r\n summary?: string;\r\n description?: string;\r\n value?: unknown;\r\n externalValue?: string;\r\n}\r\n\r\n/** Security scheme object */\r\nexport interface OpenAPISecurityScheme {\r\n type: 'apiKey' | 'http' | 'oauth2' | 'openIdConnect' | 'mutualTLS';\r\n description?: string;\r\n name?: string; // for apiKey\r\n in?: 'query' | 'header' | 'cookie'; // for apiKey\r\n scheme?: string; // for http\r\n bearerFormat?: string; // for http bearer\r\n flows?: OpenAPIOAuthFlows; // for oauth2\r\n openIdConnectUrl?: string; // for openIdConnect\r\n}\r\n\r\n/** OAuth flows object */\r\nexport interface OpenAPIOAuthFlows {\r\n implicit?: OpenAPIOAuthFlow;\r\n password?: OpenAPIOAuthFlow;\r\n clientCredentials?: OpenAPIOAuthFlow;\r\n authorizationCode?: OpenAPIOAuthFlow;\r\n}\r\n\r\n/** OAuth flow object */\r\nexport interface OpenAPIOAuthFlow {\r\n authorizationUrl?: string;\r\n tokenUrl?: string;\r\n refreshUrl?: string;\r\n scopes: Record<string, string>;\r\n}\r\n\r\n/** Security requirement object */\r\nexport type OpenAPISecurityRequirement = Record<string, string[]>;\r\n\r\n/** Tag object */\r\nexport interface OpenAPITag {\r\n name: string;\r\n description?: string;\r\n externalDocs?: OpenAPIExternalDocs;\r\n}\r\n\r\n/** External documentation object */\r\nexport interface OpenAPIExternalDocs {\r\n url: string;\r\n description?: string;\r\n}\r\n\r\n/** Components object */\r\nexport interface OpenAPIComponents {\r\n schemas?: Record<string, OpenAPISchema>;\r\n responses?: Record<string, OpenAPIResponse>;\r\n parameters?: Record<string, OpenAPIParameter>;\r\n examples?: Record<string, OpenAPIExample>;\r\n requestBodies?: Record<string, OpenAPIRequestBody>;\r\n headers?: Record<string, OpenAPIHeader>;\r\n securitySchemes?: Record<string, OpenAPISecurityScheme>;\r\n links?: Record<string, OpenAPILink>;\r\n callbacks?: Record<string, Record<string, OpenAPIPathItem>>;\r\n pathItems?: Record<string, OpenAPIPathItem>;\r\n}\r\n\r\n/** OpenAPI editor configuration */\r\nexport interface OpenAPIEditorConfig {\r\n /** Spec source (URL, file, or inline)*/\r\n source: OpenAPISource;\r\n /** Editor theme */\r\n theme?: 'light' | 'dark' | 'swagger';\r\n /** Enable spec validation */\r\n validation?: boolean;\r\n /** Validation rules */\r\n validationRules?: OpenAPIValidationConfig;\r\n /** Enable autocomplete */\r\n autocomplete?: boolean;\r\n /** Show preview panel */\r\n showPreview?: boolean;\r\n /** Preview layout */\r\n previewLayout?: 'split' | 'tabs';\r\n /** Enable YAML/JSON toggle */\r\n formatToggle?: boolean;\r\n /** Default format */\r\n defaultFormat?: 'yaml' | 'json';\r\n /** Read-only mode */\r\n readOnly?: boolean;\r\n /** Auto-save interval (ms) */\r\n autoSaveInterval?: number;\r\n /** Version history */\r\n enableHistory?: boolean;\r\n /** Collaboration mode */\r\n collaboration?: CollaborationConfig;\r\n}\r\n\r\n/** OpenAPI source configuration */\r\nexport interface OpenAPISource {\r\n type: 'url' | 'file' | 'inline';\r\n url?: string;\r\n content?: string;\r\n format?: 'yaml' | 'json';\r\n}\r\n\r\n/** Validation configuration */\r\nexport interface OpenAPIValidationConfig {\r\n /** Validate on change */\r\n validateOnChange?: boolean;\r\n /** Validation level */\r\n level?: 'error' | 'warning' | 'info';\r\n /** Rules to enable/disable */\r\n rules?: Record<string, boolean>;\r\n /** Custom validators */\r\n customValidators?: OpenAPIValidator[];\r\n}\r\n\r\n/** Custom validator */\r\nexport interface OpenAPIValidator {\r\n name: string;\r\n description?: string;\r\n validate: (spec: OpenAPISpec) => OpenAPIValidationResult[];\r\n}\r\n\r\n/** Validation result */\r\nexport interface OpenAPIValidationResult {\r\n level: 'error' | 'warning' | 'info';\r\n message: string;\r\n path: string;\r\n line?: number;\r\n column?: number;\r\n rule?: string;\r\n}\r\n\r\n/** Collaboration configuration */\r\nexport interface CollaborationConfig {\r\n enabled: boolean;\r\n provider?: 'yjs' | 'automerge' | 'custom';\r\n serverUrl?: string;\r\n roomId?: string;\r\n userName?: string;\r\n userColor?: string;\r\n}\r\n\r\n// =============================================================================\r\n// GraphQL Editor\r\n// =============================================================================\r\n\r\n/** GraphQL schema document */\r\nexport interface GraphQLSchemaDefinition {\r\n /** Raw SDL */\r\n sdl: string;\r\n /** Parsed types */\r\n types: GraphQLTypeDefinition[];\r\n /** Root query type name */\r\n queryType?: string;\r\n /** Root mutation type name */\r\n mutationType?: string;\r\n /** Root subscription type name */\r\n subscriptionType?: string;\r\n /** Directives */\r\n directives: GraphQLDirectiveDefinition[];\r\n}\r\n\r\n/** GraphQL type definition */\r\nexport interface GraphQLTypeDefinition {\r\n kind: GraphQLTypeKind;\r\n name: string;\r\n description?: string;\r\n fields?: GraphQLFieldDefinition[];\r\n interfaces?: string[];\r\n possibleTypes?: string[]; // for interface/union\r\n enumValues?: GraphQLEnumValue[];\r\n inputFields?: GraphQLInputValue[];\r\n directives?: GraphQLDirectiveUsage[];\r\n}\r\n\r\n/** GraphQL type kind */\r\nexport type GraphQLTypeKind = 'SCALAR' | 'OBJECT' | 'INTERFACE' | 'UNION' | 'ENUM' | 'INPUT_OBJECT';\r\n\r\n/** GraphQL field definition */\r\nexport interface GraphQLFieldDefinition {\r\n name: string;\r\n description?: string;\r\n type: GraphQLTypeRef;\r\n args?: GraphQLInputValue[];\r\n deprecationReason?: string;\r\n directives?: GraphQLDirectiveUsage[];\r\n}\r\n\r\n/** GraphQL type reference */\r\nexport interface GraphQLTypeRef {\r\n kind: 'SCALAR' | 'OBJECT' | 'INTERFACE' | 'UNION' | 'ENUM' | 'INPUT_OBJECT' | 'NON_NULL' | 'LIST';\r\n name?: string;\r\n ofType?: GraphQLTypeRef;\r\n}\r\n\r\n/** GraphQL input value (field arg or input field) */\r\nexport interface GraphQLInputValue {\r\n name: string;\r\n description?: string;\r\n type: GraphQLTypeRef;\r\n defaultValue?: string;\r\n deprecationReason?: string;\r\n directives?: GraphQLDirectiveUsage[];\r\n}\r\n\r\n/** GraphQL enum value */\r\nexport interface GraphQLEnumValue {\r\n name: string;\r\n description?: string;\r\n deprecationReason?: string;\r\n directives?: GraphQLDirectiveUsage[];\r\n}\r\n\r\n/** GraphQL directive definition */\r\nexport interface GraphQLDirectiveDefinition {\r\n name: string;\r\n description?: string;\r\n locations: GraphQLDirectiveLocation[];\r\n args?: GraphQLInputValue[];\r\n isRepeatable?: boolean;\r\n}\r\n\r\n/** GraphQL directive location */\r\nexport type GraphQLDirectiveLocation =\r\n | 'QUERY'\r\n | 'MUTATION'\r\n | 'SUBSCRIPTION'\r\n | 'FIELD'\r\n | 'FRAGMENT_DEFINITION'\r\n | 'FRAGMENT_SPREAD'\r\n | 'INLINE_FRAGMENT'\r\n | 'VARIABLE_DEFINITION'\r\n | 'SCHEMA'\r\n | 'SCALAR'\r\n | 'OBJECT'\r\n | 'FIELD_DEFINITION'\r\n | 'ARGUMENT_DEFINITION'\r\n | 'INTERFACE'\r\n | 'UNION'\r\n | 'ENUM'\r\n | 'ENUM_VALUE'\r\n | 'INPUT_OBJECT'\r\n | 'INPUT_FIELD_DEFINITION';\r\n\r\n/** GraphQL directive usage */\r\nexport interface GraphQLDirectiveUsage {\r\n name: string;\r\n args?: Record<string, unknown>;\r\n}\r\n\r\n/** GraphQL editor configuration */\r\nexport interface GraphQLEditorConfig {\r\n /** Schema source */\r\n source: GraphQLSource;\r\n /** Explorer enabled */\r\n showExplorer?: boolean;\r\n /** Documentation panel */\r\n showDocs?: boolean;\r\n /** Query history */\r\n enableHistory?: boolean;\r\n /** Prettify on save */\r\n prettify?: boolean;\r\n /** Tab size */\r\n tabSize?: number;\r\n /** Use tabs */\r\n useTabs?: boolean;\r\n /** Theme */\r\n theme?: 'light' | 'dark' | 'graphiql';\r\n /** Headers for introspection */\r\n headers?: Record<string, string>;\r\n /** Subscription endpoint */\r\n subscriptionEndpoint?: string;\r\n}\r\n\r\n/** GraphQL source */\r\nexport interface GraphQLSource {\r\n type: 'url' | 'file' | 'inline';\r\n /** Introspection endpoint URL */\r\n url?: string;\r\n /** SDL content */\r\n sdl?: string;\r\n /** File path */\r\n path?: string;\r\n}\r\n\r\n// =============================================================================\r\n// AsyncAPI Editor\r\n// =============================================================================\r\n\r\n/** AsyncAPI specification document */\r\nexport interface AsyncAPISpec {\r\n asyncapi: string;\r\n info: AsyncAPIInfo;\r\n servers?: Record<string, AsyncAPIServer>;\r\n channels: Record<string, AsyncAPIChannel>;\r\n components?: AsyncAPIComponents;\r\n tags?: AsyncAPITag[];\r\n externalDocs?: AsyncAPIExternalDocs;\r\n defaultContentType?: string;\r\n}\r\n\r\n/** AsyncAPI info */\r\nexport interface AsyncAPIInfo {\r\n title: string;\r\n version: string;\r\n description?: string;\r\n termsOfService?: string;\r\n contact?: AsyncAPIContact;\r\n license?: AsyncAPILicense;\r\n}\r\n\r\n/** AsyncAPI contact */\r\nexport interface AsyncAPIContact {\r\n name?: string;\r\n url?: string;\r\n email?: string;\r\n}\r\n\r\n/** AsyncAPI license */\r\nexport interface AsyncAPILicense {\r\n name: string;\r\n url?: string;\r\n}\r\n\r\n/** AsyncAPI server */\r\nexport interface AsyncAPIServer {\r\n url: string;\r\n protocol: AsyncAPIProtocol;\r\n protocolVersion?: string;\r\n description?: string;\r\n variables?: Record<string, AsyncAPIServerVariable>;\r\n security?: Record<string, string[]>[];\r\n bindings?: AsyncAPIServerBindings;\r\n}\r\n\r\n/** AsyncAPI protocol */\r\nexport type AsyncAPIProtocol =\r\n | 'amqp'\r\n | 'amqps'\r\n | 'http'\r\n | 'https'\r\n | 'kafka'\r\n | 'kafka-secure'\r\n | 'mqtt'\r\n | 'mqtts'\r\n | 'ws'\r\n | 'wss'\r\n | 'stomp'\r\n | 'stomps'\r\n | 'jms'\r\n | 'nats'\r\n | 'redis'\r\n | 'sns'\r\n | 'sqs'\r\n | 'pulsar'\r\n | 'solace';\r\n\r\n/** Server variable */\r\nexport interface AsyncAPIServerVariable {\r\n default?: string;\r\n description?: string;\r\n enum?: string[];\r\n examples?: string[];\r\n}\r\n\r\n/** Server bindings */\r\nexport interface AsyncAPIServerBindings {\r\n mqtt?: MqttServerBinding;\r\n kafka?: KafkaServerBinding;\r\n amqp?: AmqpServerBinding;\r\n [key: string]: unknown;\r\n}\r\n\r\n/** MQTT server binding */\r\nexport interface MqttServerBinding {\r\n clientId?: string;\r\n cleanSession?: boolean;\r\n lastWill?: MqttLastWill;\r\n keepAlive?: number;\r\n}\r\n\r\n/** MQTT last will */\r\nexport interface MqttLastWill {\r\n topic: string;\r\n qos?: 0 | 1 | 2;\r\n message?: string;\r\n retain?: boolean;\r\n}\r\n\r\n/** Kafka server binding */\r\nexport interface KafkaServerBinding {\r\n schemaRegistryUrl?: string;\r\n schemaRegistryVendor?: string;\r\n}\r\n\r\n/** AMQP server binding */\r\nexport interface AmqpServerBinding {}\r\n\r\n/** AsyncAPI channel */\r\nexport interface AsyncAPIChannel {\r\n description?: string;\r\n subscribe?: AsyncAPIOperation;\r\n publish?: AsyncAPIOperation;\r\n parameters?: Record<string, AsyncAPIParameter>;\r\n bindings?: AsyncAPIChannelBindings;\r\n}\r\n\r\n/** Channel bindings */\r\nexport interface AsyncAPIChannelBindings {\r\n kafka?: KafkaChannelBinding;\r\n amqp?: AmqpChannelBinding;\r\n [key: string]: unknown;\r\n}\r\n\r\n/** Kafka channel binding */\r\nexport interface KafkaChannelBinding {\r\n topic?: string;\r\n partitions?: number;\r\n replicas?: number;\r\n topicConfiguration?: Record<string, unknown>;\r\n}\r\n\r\n/** AMQP channel binding */\r\nexport interface AmqpChannelBinding {\r\n is?: 'queue' | 'routingKey';\r\n exchange?: AmqpExchange;\r\n queue?: AmqpQueue;\r\n}\r\n\r\n/** AMQP exchange */\r\nexport interface AmqpExchange {\r\n name?: string;\r\n type?: 'topic' | 'direct' | 'fanout' | 'default' | 'headers';\r\n durable?: boolean;\r\n autoDelete?: boolean;\r\n vhost?: string;\r\n}\r\n\r\n/** AMQP queue */\r\nexport interface AmqpQueue {\r\n name?: string;\r\n durable?: boolean;\r\n exclusive?: boolean;\r\n autoDelete?: boolean;\r\n vhost?: string;\r\n}\r\n\r\n/** AsyncAPI operation */\r\nexport interface AsyncAPIOperation {\r\n operationId?: string;\r\n summary?: string;\r\n description?: string;\r\n tags?: AsyncAPITag[];\r\n externalDocs?: AsyncAPIExternalDocs;\r\n bindings?: AsyncAPIOperationBindings;\r\n traits?: AsyncAPIOperationTrait[];\r\n message?: AsyncAPIMessage | AsyncAPIMessageOneOf;\r\n security?: Record<string, string[]>[];\r\n}\r\n\r\n/** Operation bindings */\r\nexport interface AsyncAPIOperationBindings {\r\n kafka?: KafkaOperationBinding;\r\n amqp?: AmqpOperationBinding;\r\n [key: string]: unknown;\r\n}\r\n\r\n/** Kafka operation binding */\r\nexport interface KafkaOperationBinding {\r\n groupId?: AsyncAPISchema;\r\n clientId?: AsyncAPISchema;\r\n}\r\n\r\n/** AMQP operation binding */\r\nexport interface AmqpOperationBinding {\r\n expiration?: number;\r\n userId?: string;\r\n cc?: string[];\r\n priority?: number;\r\n deliveryMode?: 1 | 2;\r\n mandatory?: boolean;\r\n bcc?: string[];\r\n replyTo?: string;\r\n timestamp?: boolean;\r\n ack?: boolean;\r\n}\r\n\r\n/** Operation trait */\r\nexport interface AsyncAPIOperationTrait {\r\n operationId?: string;\r\n summary?: string;\r\n description?: string;\r\n tags?: AsyncAPITag[];\r\n externalDocs?: AsyncAPIExternalDocs;\r\n bindings?: AsyncAPIOperationBindings;\r\n}\r\n\r\n/** AsyncAPI message */\r\nexport interface AsyncAPIMessage {\r\n messageId?: string;\r\n headers?: AsyncAPISchema;\r\n payload?: AsyncAPISchema;\r\n correlationId?: AsyncAPICorrelationId;\r\n schemaFormat?: string;\r\n contentType?: string;\r\n name?: string;\r\n title?: string;\r\n summary?: string;\r\n description?: string;\r\n tags?: AsyncAPITag[];\r\n externalDocs?: AsyncAPIExternalDocs;\r\n bindings?: AsyncAPIMessageBindings;\r\n examples?: AsyncAPIMessageExample[];\r\n traits?: AsyncAPIMessageTrait[];\r\n}\r\n\r\n/** Message oneOf */\r\nexport interface AsyncAPIMessageOneOf {\r\n oneOf: AsyncAPIMessage[];\r\n}\r\n\r\n/** Message bindings */\r\nexport interface AsyncAPIMessageBindings {\r\n kafka?: KafkaMessageBinding;\r\n amqp?: AmqpMessageBinding;\r\n [key: string]: unknown;\r\n}\r\n\r\n/** Kafka message binding */\r\nexport interface KafkaMessageBinding {\r\n key?: AsyncAPISchema;\r\n}\r\n\r\n/** AMQP message binding */\r\nexport interface AmqpMessageBinding {\r\n contentEncoding?: string;\r\n messageType?: string;\r\n}\r\n\r\n/** Message example */\r\nexport interface AsyncAPIMessageExample {\r\n name?: string;\r\n summary?: string;\r\n headers?: Record<string, unknown>;\r\n payload?: unknown;\r\n}\r\n\r\n/** Message trait */\r\nexport interface AsyncAPIMessageTrait {\r\n messageId?: string;\r\n headers?: AsyncAPISchema;\r\n correlationId?: AsyncAPICorrelationId;\r\n schemaFormat?: string;\r\n contentType?: string;\r\n name?: string;\r\n title?: string;\r\n summary?: string;\r\n description?: string;\r\n tags?: AsyncAPITag[];\r\n externalDocs?: AsyncAPIExternalDocs;\r\n bindings?: AsyncAPIMessageBindings;\r\n examples?: AsyncAPIMessageExample[];\r\n}\r\n\r\n/** Correlation ID */\r\nexport interface AsyncAPICorrelationId {\r\n description?: string;\r\n location: string;\r\n}\r\n\r\n/** AsyncAPI parameter */\r\nexport interface AsyncAPIParameter {\r\n description?: string;\r\n schema?: AsyncAPISchema;\r\n location?: string;\r\n}\r\n\r\n/** AsyncAPI schema (JSON Schema) */\r\nexport interface AsyncAPISchema extends OpenAPISchema {\r\n // AsyncAPI uses JSON Schema with some additions\r\n}\r\n\r\n/** AsyncAPI tag */\r\nexport interface AsyncAPITag {\r\n name: string;\r\n description?: string;\r\n externalDocs?: AsyncAPIExternalDocs;\r\n}\r\n\r\n/** AsyncAPI external docs */\r\nexport interface AsyncAPIExternalDocs {\r\n url: string;\r\n description?: string;\r\n}\r\n\r\n/** AsyncAPI components */\r\nexport interface AsyncAPIComponents {\r\n schemas?: Record<string, AsyncAPISchema>;\r\n messages?: Record<string, AsyncAPIMessage>;\r\n securitySchemes?: Record<string, AsyncAPISecurityScheme>;\r\n parameters?: Record<string, AsyncAPIParameter>;\r\n correlationIds?: Record<string, AsyncAPICorrelationId>;\r\n operationTraits?: Record<string, AsyncAPIOperationTrait>;\r\n messageTraits?: Record<string, AsyncAPIMessageTrait>;\r\n serverBindings?: Record<string, AsyncAPIServerBindings>;\r\n channelBindings?: Record<string, AsyncAPIChannelBindings>;\r\n operationBindings?: Record<string, AsyncAPIOperationBindings>;\r\n messageBindings?: Record<string, AsyncAPIMessageBindings>;\r\n}\r\n\r\n/** AsyncAPI security scheme */\r\nexport interface AsyncAPISecurityScheme {\r\n type:\r\n | 'userPassword'\r\n | 'apiKey'\r\n | 'X509'\r\n | 'symmetricEncryption'\r\n | 'asymmetricEncryption'\r\n | 'httpApiKey'\r\n | 'http'\r\n | 'oauth2'\r\n | 'openIdConnect'\r\n | 'plain'\r\n | 'scramSha256'\r\n | 'scramSha512'\r\n | 'gssapi';\r\n description?: string;\r\n name?: string;\r\n in?: 'user' | 'password' | 'query' | 'header' | 'cookie';\r\n scheme?: string;\r\n bearerFormat?: string;\r\n flows?: AsyncAPIOAuthFlows;\r\n openIdConnectUrl?: string;\r\n}\r\n\r\n/** OAuth flows for AsyncAPI */\r\nexport interface AsyncAPIOAuthFlows {\r\n implicit?: AsyncAPIOAuthFlow;\r\n password?: AsyncAPIOAuthFlow;\r\n clientCredentials?: AsyncAPIOAuthFlow;\r\n authorizationCode?: AsyncAPIOAuthFlow;\r\n}\r\n\r\n/** OAuth flow */\r\nexport interface AsyncAPIOAuthFlow {\r\n authorizationUrl?: string;\r\n tokenUrl?: string;\r\n refreshUrl?: string;\r\n scopes: Record<string, string>;\r\n}\r\n\r\n/** AsyncAPI editor configuration */\r\nexport interface AsyncAPIEditorConfig {\r\n source: AsyncAPISource;\r\n validation?: boolean;\r\n theme?: 'light' | 'dark';\r\n showPreview?: boolean;\r\n formatToggle?: boolean;\r\n readOnly?: boolean;\r\n}\r\n\r\n/** AsyncAPI source */\r\nexport interface AsyncAPISource {\r\n type: 'url' | 'file' | 'inline';\r\n url?: string;\r\n content?: string;\r\n format?: 'yaml' | 'json';\r\n}\r\n\r\n// =============================================================================\r\n// Protocol Buffers Editor\r\n// =============================================================================\r\n\r\n/** Protobuf file definition */\r\nexport interface ProtobufDefinition {\r\n syntax: 'proto2' | 'proto3';\r\n package?: string;\r\n imports: ProtobufImport[];\r\n options: ProtobufOption[];\r\n messages: ProtobufMessage[];\r\n enums: ProtobufEnum[];\r\n services: ProtobufService[];\r\n}\r\n\r\n/** Protobuf import */\r\nexport interface ProtobufImport {\r\n path: string;\r\n public?: boolean;\r\n weak?: boolean;\r\n}\r\n\r\n/** Protobuf option */\r\nexport interface ProtobufOption {\r\n name: string;\r\n value: unknown;\r\n}\r\n\r\n/** Protobuf message */\r\nexport interface ProtobufMessage {\r\n name: string;\r\n fields: ProtobufField[];\r\n nestedMessages: ProtobufMessage[];\r\n nestedEnums: ProtobufEnum[];\r\n oneofs: ProtobufOneof[];\r\n options: ProtobufOption[];\r\n reserved: ProtobufReserved[];\r\n extensions: ProtobufExtension[];\r\n comments?: string;\r\n}\r\n\r\n/** Protobuf field */\r\nexport interface ProtobufField {\r\n name: string;\r\n number: number;\r\n type: string;\r\n label?: 'optional' | 'required' | 'repeated';\r\n options?: ProtobufOption[];\r\n map?: ProtobufMapType;\r\n comments?: string;\r\n}\r\n\r\n/** Protobuf map type */\r\nexport interface ProtobufMapType {\r\n keyType: string;\r\n valueType: string;\r\n}\r\n\r\n/** Protobuf oneof */\r\nexport interface ProtobufOneof {\r\n name: string;\r\n fields: ProtobufField[];\r\n options?: ProtobufOption[];\r\n}\r\n\r\n/** Protobuf reserved */\r\nexport interface ProtobufReserved {\r\n ranges?: Array<number | { start: number; end: number }>;\r\n names?: string[];\r\n}\r\n\r\n/** Protobuf extension */\r\nexport interface ProtobufExtension {\r\n extendee: string;\r\n fields: ProtobufField[];\r\n}\r\n\r\n/** Protobuf enum */\r\nexport interface ProtobufEnum {\r\n name: string;\r\n values: ProtobufEnumValue[];\r\n options?: ProtobufOption[];\r\n reserved?: ProtobufReserved[];\r\n comments?: string;\r\n}\r\n\r\n/** Protobuf enum value */\r\nexport interface ProtobufEnumValue {\r\n name: string;\r\n number: number;\r\n options?: ProtobufOption[];\r\n comments?: string;\r\n}\r\n\r\n/** Protobuf service */\r\nexport interface ProtobufService {\r\n name: string;\r\n methods: ProtobufMethod[];\r\n options?: ProtobufOption[];\r\n comments?: string;\r\n}\r\n\r\n/** Protobuf method */\r\nexport interface ProtobufMethod {\r\n name: string;\r\n inputType: string;\r\n outputType: string;\r\n clientStreaming?: boolean;\r\n serverStreaming?: boolean;\r\n options?: ProtobufOption[];\r\n comments?: string;\r\n}\r\n\r\n/** Protobuf editor configuration */\r\nexport interface ProtobufEditorConfig {\r\n source: ProtobufSource;\r\n syntax?: 'proto2' | 'proto3';\r\n validation?: boolean;\r\n theme?: 'light' | 'dark';\r\n showLineNumbers?: boolean;\r\n includePaths?: string[];\r\n}\r\n\r\n/** Protobuf source */\r\nexport interface ProtobufSource {\r\n type: 'file' | 'inline';\r\n path?: string;\r\n content?: string;\r\n}\r\n\r\n// =============================================================================\r\n// Apache Thrift Editor\r\n// =============================================================================\r\n\r\n/** Thrift document */\r\nexport interface ThriftDocument {\r\n headers: ThriftHeader[];\r\n definitions: ThriftDefinition[];\r\n}\r\n\r\n/** Thrift header */\r\nexport interface ThriftHeader {\r\n type: 'include' | 'cppInclude' | 'namespace';\r\n value: string;\r\n scope?: string;\r\n}\r\n\r\n/** Thrift definition */\r\nexport type ThriftDefinition =\r\n | ThriftConst\r\n | ThriftTypedef\r\n | ThriftEnum\r\n | ThriftStruct\r\n | ThriftUnion\r\n | ThriftException\r\n | ThriftService;\r\n\r\n/** Thrift constant */\r\nexport interface ThriftConst {\r\n kind: 'const';\r\n name: string;\r\n type: ThriftType;\r\n value: unknown;\r\n}\r\n\r\n/** Thrift typedef */\r\nexport interface ThriftTypedef {\r\n kind: 'typedef';\r\n name: string;\r\n type: ThriftType;\r\n}\r\n\r\n/** Thrift enum */\r\nexport interface ThriftEnum {\r\n kind: 'enum';\r\n name: string;\r\n members: ThriftEnumMember[];\r\n}\r\n\r\n/** Thrift enum member */\r\nexport interface ThriftEnumMember {\r\n name: string;\r\n value?: number;\r\n}\r\n\r\n/** Thrift struct */\r\nexport interface ThriftStruct {\r\n kind: 'struct';\r\n name: string;\r\n fields: ThriftField[];\r\n annotations?: Record<string, string>;\r\n}\r\n\r\n/** Thrift union */\r\nexport interface ThriftUnion {\r\n kind: 'union';\r\n name: string;\r\n fields: ThriftField[];\r\n}\r\n\r\n/** Thrift exception */\r\nexport interface ThriftException {\r\n kind: 'exception';\r\n name: string;\r\n fields: ThriftField[];\r\n}\r\n\r\n/** Thrift field */\r\nexport interface ThriftField {\r\n id?: number;\r\n name: string;\r\n type: ThriftType;\r\n requiredness?: 'required' | 'optional';\r\n defaultValue?: unknown;\r\n annotations?: Record<string, string>;\r\n}\r\n\r\n/** Thrift type */\r\nexport interface ThriftType {\r\n kind: 'base' | 'identifier' | 'map' | 'set' | 'list';\r\n name?: string; // for base and identifier\r\n keyType?: ThriftType; // for map\r\n valueType?: ThriftType; // for map, set, list\r\n}\r\n\r\n/** Thrift service */\r\nexport interface ThriftService {\r\n kind: 'service';\r\n name: string;\r\n extends?: string;\r\n functions: ThriftFunction[];\r\n annotations?: Record<string, string>;\r\n}\r\n\r\n/** Thrift function */\r\nexport interface ThriftFunction {\r\n name: string;\r\n returnType: ThriftType | 'void';\r\n oneway?: boolean;\r\n parameters: ThriftField[];\r\n throws?: ThriftField[];\r\n annotations?: Record<string, string>;\r\n}\r\n\r\n/** Thrift editor configuration */\r\nexport interface ThriftEditorConfig {\r\n source: ThriftSource;\r\n validation?: boolean;\r\n theme?: 'light' | 'dark';\r\n includePaths?: string[];\r\n}\r\n\r\n/** Thrift source */\r\nexport interface ThriftSource {\r\n type: 'file' | 'inline';\r\n path?: string;\r\n content?: string;\r\n}\r\n\r\n// =============================================================================\r\n// Apache Avro Editor\r\n// =============================================================================\r\n\r\n/** Avro schema */\r\nexport type AvroSchema =\r\n | AvroPrimitive\r\n | AvroRecord\r\n | AvroEnum\r\n | AvroArray\r\n | AvroMap\r\n | AvroUnion\r\n | AvroFixed\r\n | AvroNamedType\r\n | AvroLogicalType;\r\n\r\n/** Avro primitive types */\r\nexport type AvroPrimitive =\r\n | 'null'\r\n | 'boolean'\r\n | 'int'\r\n | 'long'\r\n | 'float'\r\n | 'double'\r\n | 'bytes'\r\n | 'string';\r\n\r\n/** Avro record schema */\r\nexport interface AvroRecord {\r\n type: 'record';\r\n name: string;\r\n namespace?: string;\r\n doc?: string;\r\n aliases?: string[];\r\n fields: AvroField[];\r\n}\r\n\r\n/** Avro field */\r\nexport interface AvroField {\r\n name: string;\r\n type: AvroSchema;\r\n doc?: string;\r\n default?: unknown;\r\n order?: 'ascending' | 'descending' | 'ignore';\r\n aliases?: string[];\r\n}\r\n\r\n/** Avro enum schema */\r\nexport interface AvroEnum {\r\n type: 'enum';\r\n name: string;\r\n namespace?: string;\r\n doc?: string;\r\n aliases?: string[];\r\n symbols: string[];\r\n default?: string;\r\n}\r\n\r\n/** Avro array schema */\r\nexport interface AvroArray {\r\n type: 'array';\r\n items: AvroSchema;\r\n}\r\n\r\n/** Avro map schema */\r\nexport interface AvroMap {\r\n type: 'map';\r\n values: AvroSchema;\r\n}\r\n\r\n/** Avro union (array of types) */\r\nexport type AvroUnion = AvroSchema[];\r\n\r\n/** Avro fixed schema */\r\nexport interface AvroFixed {\r\n type: 'fixed';\r\n name: string;\r\n namespace?: string;\r\n aliases?: string[];\r\n size: number;\r\n}\r\n\r\n/** Named type reference */\r\nexport type AvroNamedType = string;\r\n\r\n/** Avro logical type */\r\nexport interface AvroLogicalType {\r\n type: AvroPrimitive | AvroFixed | 'bytes' | 'string';\r\n logicalType:\r\n | 'decimal'\r\n | 'uuid'\r\n | 'date'\r\n | 'time-millis'\r\n | 'time-micros'\r\n | 'timestamp-millis'\r\n | 'timestamp-micros'\r\n | 'duration'\r\n | 'local-timestamp-millis'\r\n | 'local-timestamp-micros';\r\n precision?: number;\r\n scale?: number;\r\n}\r\n\r\n/** Avro protocol */\r\nexport interface AvroProtocol {\r\n protocol: string;\r\n namespace?: string;\r\n doc?: string;\r\n types?: AvroSchema[];\r\n messages?: Record<string, AvroMessage>;\r\n}\r\n\r\n/** Avro message (RPC) */\r\nexport interface AvroMessage {\r\n doc?: string;\r\n request: AvroField[];\r\n response: AvroSchema;\r\n errors?: AvroSchema[];\r\n one_way?: boolean;\r\n}\r\n\r\n/** Avro editor configuration */\r\nexport interface AvroEditorConfig {\r\n source: AvroSource;\r\n validation?: boolean;\r\n theme?: 'light' | 'dark';\r\n schemaRegistry?: AvroSchemaRegistryConfig;\r\n}\r\n\r\n/** Avro source */\r\nexport interface AvroSource {\r\n type: 'file' | 'inline' | 'registry';\r\n path?: string;\r\n content?: string;\r\n subject?: string;\r\n version?: number | 'latest';\r\n}\r\n\r\n/** Schema registry configuration */\r\nexport interface AvroSchemaRegistryConfig {\r\n url: string;\r\n auth?: {\r\n type: 'basic' | 'bearer';\r\n username?: string;\r\n password?: string;\r\n token?: string;\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// Schema Visualization\r\n// =============================================================================\r\n\r\n/** Schema diagram configuration */\r\nexport interface SchemaDiagramConfig {\r\n /** Schema source */\r\n schema: SchemaSource;\r\n /** Diagram layout */\r\n layout?: DiagramLayout;\r\n /** Show relationships */\r\n showRelationships?: boolean;\r\n /** Show field types */\r\n showTypes?: boolean;\r\n /** Show descriptions */\r\n showDescriptions?: boolean;\r\n /** Collapsible nodes */\r\n collapsible?: boolean;\r\n /** Zoom controls */\r\n zoomControls?: boolean;\r\n /** Pan enabled */\r\n panEnabled?: boolean;\r\n /** Export formats */\r\n exportFormats?: DiagramExportFormat[];\r\n /** Theme */\r\n theme?: 'light' | 'dark';\r\n /** Custom colors */\r\n colors?: DiagramColors;\r\n}\r\n\r\n/** Schema source for visualization */\r\nexport interface SchemaSource {\r\n type: 'openapi' | 'graphql' | 'asyncapi' | 'protobuf' | 'avro' | 'jsonschema';\r\n content: string | object;\r\n format?: 'yaml' | 'json' | 'sdl' | 'proto';\r\n}\r\n\r\n/** Diagram layout options */\r\nexport interface DiagramLayout {\r\n algorithm: 'dagre' | 'elk' | 'force' | 'hierarchy' | 'radial';\r\n direction?: 'TB' | 'BT' | 'LR' | 'RL';\r\n nodeSpacing?: number;\r\n rankSpacing?: number;\r\n grouping?: 'none' | 'namespace' | 'tag';\r\n}\r\n\r\n/** Diagram export format */\r\nexport type DiagramExportFormat = 'png' | 'svg' | 'pdf' | 'json';\r\n\r\n/** Diagram colors */\r\nexport interface DiagramColors {\r\n background?: string;\r\n node?: string;\r\n nodeBorder?: string;\r\n nodeText?: string;\r\n edge?: string;\r\n edgeLabel?: string;\r\n highlight?: string;\r\n}\r\n\r\n/** Diagram node */\r\nexport interface DiagramNode {\r\n id: string;\r\n type: 'type' | 'endpoint' | 'channel' | 'message' | 'service' | 'method';\r\n label: string;\r\n description?: string;\r\n properties?: DiagramNodeProperty[];\r\n group?: string;\r\n x?: number;\r\n y?: number;\r\n collapsed?: boolean;\r\n}\r\n\r\n/** Diagram node property */\r\nexport interface DiagramNodeProperty {\r\n name: string;\r\n type: string;\r\n required?: boolean;\r\n deprecated?: boolean;\r\n description?: string;\r\n}\r\n\r\n/** Diagram edge */\r\nexport interface DiagramEdge {\r\n id: string;\r\n source: string;\r\n target: string;\r\n label?: string;\r\n type: 'reference' | 'inheritance' | 'composition' | 'association' | 'dependency';\r\n cardinality?: string;\r\n}\r\n\r\n// =============================================================================\r\n// Mock Server\r\n// =============================================================================\r\n\r\n/** Mock server configuration */\r\nexport interface MockServerConfig {\r\n /** Schema source */\r\n schema: SchemaSource;\r\n /** Server port */\r\n port?: number;\r\n /** Host */\r\n host?: string;\r\n /** Base path */\r\n basePath?: string;\r\n /** Response delay (ms) */\r\n delay?: number | { min: number; max: number };\r\n /** Mock data configuration */\r\n mockData?: MockDataConfig;\r\n /** CORS configuration */\r\n cors?: MockCorsConfig;\r\n /** Request logging */\r\n logging?: boolean;\r\n /** Record requests */\r\n recording?: boolean;\r\n /** Dynamic mocks */\r\n dynamicMocks?: MockOverride[];\r\n /** Proxy fallback */\r\n proxy?: MockProxyConfig;\r\n}\r\n\r\n/** Mock data configuration */\r\nexport interface MockDataConfig {\r\n /** Use schema examples */\r\n useExamples?: boolean;\r\n /** Generate random data */\r\n generateRandom?: boolean;\r\n /** Faker.js locale */\r\n locale?: string;\r\n /** Custom generators */\r\n generators?: Record<string, MockGenerator>;\r\n /** Field overrides */\r\n fieldOverrides?: Record<string, unknown>;\r\n}\r\n\r\n/** Mock data generator */\r\nexport interface MockGenerator {\r\n type: 'faker' | 'custom' | 'static';\r\n fakerMethod?: string;\r\n customFn?: string;\r\n staticValue?: unknown;\r\n}\r\n\r\n/** Mock CORS config */\r\nexport interface MockCorsConfig {\r\n enabled?: boolean;\r\n origin?: string | string[];\r\n methods?: string[];\r\n headers?: string[];\r\n credentials?: boolean;\r\n}\r\n\r\n/** Mock override */\r\nexport interface MockOverride {\r\n path: string;\r\n method?: HttpMethod;\r\n response?: MockResponse;\r\n condition?: MockCondition;\r\n priority?: number;\r\n}\r\n\r\n/** Mock response */\r\nexport interface MockResponse {\r\n statusCode?: number;\r\n headers?: Record<string, string>;\r\n body?: unknown;\r\n delay?: number;\r\n file?: string;\r\n}\r\n\r\n/** Mock condition */\r\nexport interface MockCondition {\r\n query?: Record<string, string | RegExp>;\r\n headers?: Record<string, string | RegExp>;\r\n body?: Record<string, unknown>;\r\n jsonPath?: string;\r\n jsonPathValue?: unknown;\r\n}\r\n\r\n/** Mock proxy config */\r\nexport interface MockProxyConfig {\r\n target: string;\r\n paths?: string[];\r\n changeOrigin?: boolean;\r\n rewrite?: Record<string, string>;\r\n}\r\n\r\n/** Mock server status */\r\nexport interface MockServerStatus {\r\n running: boolean;\r\n port?: number;\r\n host?: string;\r\n startTime?: Date;\r\n requestCount: number;\r\n endpoints: MockEndpointStatus[];\r\n}\r\n\r\n/** Mock endpoint status */\r\nexport interface MockEndpointStatus {\r\n path: string;\r\n method: HttpMethod;\r\n hitCount: number;\r\n lastRequest?: Date;\r\n averageLatency?: number;\r\n}\r\n\r\n// =============================================================================\r\n// Code Generation\r\n// =============================================================================\r\n\r\n/** Code generation configuration */\r\nexport interface CodeGenConfig {\r\n /** Schema source */\r\n schema: SchemaSource;\r\n /** Output language */\r\n language: CodeGenLanguage;\r\n /** Output type (client/server) */\r\n outputType: 'client' | 'server' | 'both' | 'types';\r\n /** Framework */\r\n framework?: string;\r\n /** Output directory */\r\n outputDir?: string;\r\n /** Package/namespace name */\r\n packageName?: string;\r\n /** Generation options */\r\n options?: CodeGenOptions;\r\n /** Template overrides */\r\n templates?: CodeGenTemplate[];\r\n}\r\n\r\n/** Supported languages / framework targets for code generation */\r\nexport type CodeGenLanguage =\r\n | 'typescript'\r\n | 'javascript'\r\n | 'python'\r\n | 'java'\r\n | 'kotlin'\r\n | 'csharp'\r\n | 'go'\r\n | 'rust'\r\n | 'ruby'\r\n | 'php'\r\n | 'swift'\r\n | 'dart'\r\n // Framework targets (TS/JS based)\r\n | 'nextjs'\r\n | 'nuxt'\r\n | 'sveltekit'\r\n | 'remix'\r\n // Cross-platform / mobile / .NET\r\n | 'react-native'\r\n | 'flutter'\r\n | 'blazor';\r\n\r\n/** Code generation options */\r\nexport interface CodeGenOptions {\r\n /** Include documentation */\r\n includeDocs?: boolean;\r\n /** Include examples */\r\n includeExamples?: boolean;\r\n /** Generate validators */\r\n generateValidators?: boolean;\r\n /** Generate mocks */\r\n generateMocks?: boolean;\r\n /** Enum style */\r\n enumStyle?: 'string' | 'numeric' | 'const';\r\n /** Date/time library */\r\n dateTimeLibrary?: string;\r\n /** HTTP client library */\r\n httpClient?: string;\r\n /** Use optional chaining */\r\n useOptionalChaining?: boolean;\r\n /** Strict null checks */\r\n strictNullChecks?: boolean;\r\n /** Generate index file */\r\n generateIndex?: boolean;\r\n /** File naming convention */\r\n fileNaming?: 'camelCase' | 'PascalCase' | 'snake_case' | 'kebab-case';\r\n}\r\n\r\n/** Custom template */\r\nexport interface CodeGenTemplate {\r\n name: string;\r\n template: string;\r\n outputPath: string;\r\n condition?: string;\r\n}\r\n\r\n/** Code generation result */\r\nexport interface CodeGenResult {\r\n success: boolean;\r\n files: GeneratedFile[];\r\n errors?: CodeGenError[];\r\n warnings?: CodeGenWarning[];\r\n}\r\n\r\n/** Generated file */\r\nexport interface GeneratedFile {\r\n path: string;\r\n content: string;\r\n size: number;\r\n hash?: string;\r\n}\r\n\r\n/** Code generation error */\r\nexport interface CodeGenError {\r\n message: string;\r\n location?: string;\r\n code?: string;\r\n}\r\n\r\n/** Code generation warning */\r\nexport interface CodeGenWarning {\r\n message: string;\r\n location?: string;\r\n code?: string;\r\n}\r\n\r\n// =============================================================================\r\n// API Documentation\r\n// =============================================================================\r\n\r\n/** Documentation configuration */\r\nexport interface APIDocConfig {\r\n /** Schema source */\r\n schema: SchemaSource;\r\n /** Documentation style */\r\n style: 'swagger-ui' | 'redoc' | 'stoplight' | 'slate' | 'custom';\r\n /** Theme */\r\n theme?: DocTheme;\r\n /** Logo */\r\n logo?: DocLogo;\r\n /** Navigation */\r\n navigation?: DocNavigation;\r\n /** Custom sections */\r\n sections?: DocSection[];\r\n /** Code samples */\r\n codeSamples?: DocCodeSampleConfig;\r\n /** Try-it-out */\r\n tryItOut?: boolean;\r\n /** Authentication */\r\n auth?: DocAuthConfig;\r\n /** Output format */\r\n output?: 'html' | 'markdown' | 'pdf';\r\n}\r\n\r\n/** Documentation theme */\r\nexport interface DocTheme {\r\n primaryColor?: string;\r\n accentColor?: string;\r\n textColor?: string;\r\n backgroundColor?: string;\r\n codeBackground?: string;\r\n fontFamily?: string;\r\n codeFontFamily?: string;\r\n}\r\n\r\n/** Documentation logo */\r\nexport interface DocLogo {\r\n url: string;\r\n altText?: string;\r\n link?: string;\r\n height?: number;\r\n}\r\n\r\n/** Documentation navigation */\r\nexport interface DocNavigation {\r\n position?: 'left' | 'right' | 'top';\r\n collapsed?: boolean;\r\n searchEnabled?: boolean;\r\n tagGroups?: DocTagGroup[];\r\n}\r\n\r\n/** Tag group */\r\nexport interface DocTagGroup {\r\n name: string;\r\n tags: string[];\r\n}\r\n\r\n/** Custom documentation section */\r\nexport interface DocSection {\r\n title: string;\r\n content: string;\r\n position?: 'before' | 'after';\r\n target?: string;\r\n}\r\n\r\n/** Code sample configuration */\r\nexport interface DocCodeSampleConfig {\r\n enabled?: boolean;\r\n languages?: DocCodeLanguage[];\r\n defaultLanguage?: string;\r\n}\r\n\r\n/** Code sample language */\r\nexport interface DocCodeLanguage {\r\n name: string;\r\n label: string;\r\n prism?: string;\r\n generator?: 'automatic' | 'manual';\r\n}\r\n\r\n/** Documentation auth config */\r\nexport interface DocAuthConfig {\r\n enabled?: boolean;\r\n persistAuth?: boolean;\r\n defaultScheme?: string;\r\n credentials?: Record<string, string>;\r\n}\r\n\r\n// =============================================================================\r\n// Breaking Change Detection\r\n// =============================================================================\r\n\r\n/** Version diff configuration */\r\nexport interface VersionDiffConfig {\r\n /** Old version */\r\n oldVersion: SchemaVersion;\r\n /** New version */\r\n newVersion: SchemaVersion;\r\n /** Rules */\r\n rules?: BreakingChangeRules;\r\n /** Output format */\r\n outputFormat?: 'json' | 'markdown' | 'html';\r\n}\r\n\r\n/** Schema version */\r\nexport interface SchemaVersion {\r\n source: SchemaSource;\r\n version?: string;\r\n label?: string;\r\n}\r\n\r\n/** Breaking change rules */\r\nexport interface BreakingChangeRules {\r\n /** Treat removals as breaking */\r\n removalsBreaking?: boolean;\r\n /** Treat type changes as breaking */\r\n typeChangesBreaking?: boolean;\r\n /** Treat required changes as breaking */\r\n requiredChangesBreaking?: boolean;\r\n /** Allow deprecation grace period */\r\n deprecationGracePeriod?: boolean;\r\n /** Custom rules */\r\n customRules?: BreakingChangeRule[];\r\n}\r\n\r\n/** Custom breaking change rule */\r\nexport interface BreakingChangeRule {\r\n name: string;\r\n description?: string;\r\n severity: 'error' | 'warning' | 'info';\r\n check: string; // JSONPath or custom expression\r\n}\r\n\r\n/** Version diff result */\r\nexport interface VersionDiffResult {\r\n compatible: boolean;\r\n breakingChanges: SchemaChange[];\r\n nonBreakingChanges: SchemaChange[];\r\n deprecations: SchemaChange[];\r\n additions: SchemaChange[];\r\n summary: DiffSummary;\r\n}\r\n\r\n/** Schema change */\r\nexport interface SchemaChange {\r\n type: 'addition' | 'removal' | 'modification' | 'deprecation';\r\n severity: 'breaking' | 'non-breaking' | 'info';\r\n path: string;\r\n message: string;\r\n oldValue?: unknown;\r\n newValue?: unknown;\r\n rule?: string;\r\n}\r\n\r\n/** Diff summary */\r\nexport interface DiffSummary {\r\n totalChanges: number;\r\n breakingCount: number;\r\n nonBreakingCount: number;\r\n additionCount: number;\r\n removalCount: number;\r\n modificationCount: number;\r\n}\r\n\r\n// =============================================================================\r\n// API Linting\r\n// =============================================================================\r\n\r\n/** Linting configuration */\r\nexport interface APILintConfig {\r\n /** Schema source */\r\n schema: SchemaSource;\r\n /** Ruleset */\r\n ruleset?: 'spectral:oas' | 'spectral:asyncapi' | 'custom';\r\n /** Custom rules path */\r\n customRulesPath?: string;\r\n /** Rule overrides */\r\n rules?: Record<string, APILintRuleSeverity>;\r\n /** Output format */\r\n outputFormat?: 'json' | 'pretty' | 'stylish';\r\n}\r\n\r\n/** Rule severity */\r\nexport type APILintRuleSeverity = 'off' | 'warn' | 'error';\r\n\r\n/** Linting result */\r\nexport interface APILintResult {\r\n valid: boolean;\r\n errors: APILintIssue[];\r\n warnings: APILintIssue[];\r\n info: APILintIssue[];\r\n}\r\n\r\n/** Linting issue */\r\nexport interface APILintIssue {\r\n code: string;\r\n message: string;\r\n severity: 'error' | 'warning' | 'info';\r\n path: string[];\r\n range?: {\r\n start: { line: number; character: number };\r\n end: { line: number; character: number };\r\n };\r\n source?: string;\r\n}\r\n\r\n/** Built-in linting rules */\r\nexport interface APILintRuleDefinition {\r\n name: string;\r\n description: string;\r\n severity: APILintRuleSeverity;\r\n category: 'naming' | 'structure' | 'documentation' | 'security' | 'performance' | 'compatibility';\r\n fixable?: boolean;\r\n}\r\n\r\n/** Common OpenAPI linting rules */\r\nexport const OPENAPI_LINT_RULES: Record<string, APILintRuleDefinition> = {\r\n 'operation-operationId': {\r\n name: 'operation-operationId',\r\n description: 'Operation must have an operationId',\r\n severity: 'error',\r\n category: 'structure',\r\n fixable: false,\r\n },\r\n 'operation-description': {\r\n name: 'operation-description',\r\n description: 'Operation should have a description',\r\n severity: 'warn',\r\n category: 'documentation',\r\n fixable: false,\r\n },\r\n 'info-contact': {\r\n name: 'info-contact',\r\n description: 'Info object should have contact information',\r\n severity: 'warn',\r\n category: 'documentation',\r\n fixable: false,\r\n },\r\n 'no-$ref-siblings': {\r\n name: 'no-$ref-siblings',\r\n description: 'A $ref object must not have sibling properties',\r\n severity: 'error',\r\n category: 'structure',\r\n fixable: false,\r\n },\r\n 'path-params': {\r\n name: 'path-params',\r\n description: 'Path parameters must be defined',\r\n severity: 'error',\r\n category: 'structure',\r\n fixable: false,\r\n },\r\n};\r\n\r\n// =============================================================================\r\n// Editor Events\r\n// =============================================================================\r\n\r\n/** Editor change event */\r\nexport interface APIEditorChangeEvent {\r\n type: 'change' | 'save' | 'validate' | 'format';\r\n content: string;\r\n format: 'yaml' | 'json';\r\n timestamp: Date;\r\n valid?: boolean;\r\n errors?: OpenAPIValidationResult[];\r\n}\r\n\r\n/** Editor selection event */\r\nexport interface APIEditorSelectionEvent {\r\n path: string;\r\n range: {\r\n start: { line: number; column: number };\r\n end: { line: number; column: number };\r\n };\r\n selectedText: string;\r\n}\r\n\r\n/** Editor navigation event */\r\nexport interface APIEditorNavigationEvent {\r\n from: string;\r\n to: string;\r\n type: 'reference' | 'definition' | 'usage';\r\n}\r\n","/**\r\n * @file download-manager.ts\r\n * @module @nice2dev/ui-tools\r\n * @description PRO-31.1 — Core Download Manager Service\r\n *\r\n * Provides download management with multi-protocol support, segmented downloads,\r\n * queue management, bandwidth throttling, and scheduling.\r\n */\r\n\r\nimport type {\r\n DownloadItem,\r\n DownloadStatus,\r\n DownloadPriority,\r\n DownloadManagerConfig,\r\n DownloadQueue,\r\n DownloadCategory,\r\n TransferSpeed,\r\n TransferStats,\r\n BandwidthLimit,\r\n URLParseResult,\r\n DownloadProtocol,\r\n DownloadSchedule as _DownloadSchedule,\r\n FileChecksum,\r\n DownloadSource,\r\n MagnetLinkInfo,\r\n} from './download-torrent';\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Utility Functions\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\n/**\r\n * Formats bytes to human-readable string.\r\n */\r\nexport function formatBytes(bytes: number, decimals = 2): string {\r\n if (bytes === 0) {\r\n return '0 B';\r\n }\r\n const k = 1024;\r\n const dm = decimals < 0 ? 0 : decimals;\r\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];\r\n}\r\n\r\n/**\r\n * Formats speed to TransferSpeed object.\r\n */\r\nexport function formatSpeed(bytesPerSecond: number): TransferSpeed {\r\n const k = 1024;\r\n let unit: TransferSpeed['displayUnit'] = 'B/s';\r\n let value = bytesPerSecond;\r\n\r\n if (bytesPerSecond >= k * k * k) {\r\n unit = 'GB/s';\r\n value = bytesPerSecond / (k * k * k);\r\n } else if (bytesPerSecond >= k * k) {\r\n unit = 'MB/s';\r\n value = bytesPerSecond / (k * k);\r\n } else if (bytesPerSecond >= k) {\r\n unit = 'KB/s';\r\n value = bytesPerSecond / k;\r\n }\r\n\r\n return {\r\n bytesPerSecond,\r\n displayValue: value.toFixed(2),\r\n displayUnit: unit,\r\n };\r\n}\r\n\r\n/**\r\n * Formats duration in seconds to human-readable string.\r\n */\r\nexport function formatDuration(seconds: number): string {\r\n if (!isFinite(seconds) || seconds < 0) {\r\n return '∞';\r\n }\r\n\r\n const hours = Math.floor(seconds / 3600);\r\n const minutes = Math.floor((seconds % 3600) / 60);\r\n const secs = Math.floor(seconds % 60);\r\n\r\n if (hours > 0) {\r\n return `${hours}h ${minutes}m`;\r\n } else if (minutes > 0) {\r\n return `${minutes}m ${secs}s`;\r\n }\r\n return `${secs}s`;\r\n}\r\n\r\n/**\r\n * Calculates ETA based on remaining bytes and speed.\r\n */\r\nexport function calculateETA(\r\n remainingBytes: number,\r\n speedBytesPerSecond: number,\r\n): number | undefined {\r\n if (speedBytesPerSecond <= 0) {\r\n return undefined;\r\n }\r\n return Math.ceil(remainingBytes / speedBytesPerSecond);\r\n}\r\n\r\n/**\r\n * Parses a URL to extract download information.\r\n */\r\nexport function parseDownloadUrl(url: string): URLParseResult {\r\n // Handle magnet links\r\n if (url.startsWith('magnet:')) {\r\n return parseMagnetLink(url);\r\n }\r\n\r\n try {\r\n const parsed = new URL(url);\r\n const pathname = decodeURIComponent(parsed.pathname);\r\n const filename = pathname.split('/').pop() || 'download';\r\n const extension = filename.includes('.') ? filename.split('.').pop()?.toLowerCase() : undefined;\r\n\r\n let protocol: DownloadProtocol = 'https';\r\n if (parsed.protocol === 'http:') {\r\n protocol = 'http';\r\n } else if (parsed.protocol === 'ftp:') {\r\n protocol = 'ftp';\r\n } else if (parsed.protocol === 'sftp:') {\r\n protocol = 'sftp';\r\n }\r\n\r\n return {\r\n url,\r\n protocol,\r\n host: parsed.host,\r\n filename,\r\n extension,\r\n fileType: extension ? getFileType(extension) : undefined,\r\n resumable: protocol === 'https' || protocol === 'http', // Likely resumable for HTTP(S)\r\n requiresAuth: !!parsed.username,\r\n isMagnet: false,\r\n isMetalink: false,\r\n };\r\n } catch {\r\n return {\r\n url,\r\n protocol: 'https',\r\n host: 'unknown',\r\n filename: 'download',\r\n resumable: false,\r\n isMagnet: false,\r\n isMetalink: false,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Parses a magnet link.\r\n */\r\nexport function parseMagnetLink(magnetUrl: string): URLParseResult {\r\n const params = new URLSearchParams(magnetUrl.replace('magnet:?', ''));\r\n const xt = params.get('xt') || '';\r\n const infoHash = xt.replace('urn:btih:', '');\r\n const displayName = params.get('dn') || 'Unknown Torrent';\r\n const trackers = params.getAll('tr');\r\n const exactLength = params.get('xl') ? parseInt(params.get('xl')!, 10) : undefined;\r\n const keywords = params.get('kt')?.split('+') || [];\r\n\r\n const magnetInfo: MagnetLinkInfo = {\r\n infoHash,\r\n displayName,\r\n trackers,\r\n exactLength,\r\n keywords,\r\n };\r\n\r\n return {\r\n url: magnetUrl,\r\n protocol: 'bittorrent',\r\n host: 'bittorrent',\r\n filename: displayName,\r\n size: exactLength,\r\n resumable: true,\r\n isMagnet: true,\r\n isMetalink: false,\r\n magnetInfo,\r\n };\r\n}\r\n\r\n/**\r\n * Gets file type category from extension.\r\n */\r\nexport function getFileType(extension: string): string {\r\n const types: Record<string, string[]> = {\r\n video: ['mp4', 'mkv', 'avi', 'mov', 'wmv', 'flv', 'webm', 'm4v', 'mpeg', 'mpg', '3gp'],\r\n audio: ['mp3', 'flac', 'wav', 'aac', 'ogg', 'wma', 'm4a', 'opus', 'aiff'],\r\n image: ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp', 'ico', 'tiff', 'raw'],\r\n document: ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'rtf', 'odt'],\r\n archive: ['zip', 'rar', '7z', 'tar', 'gz', 'bz2', 'xz', 'iso'],\r\n executable: ['exe', 'msi', 'dmg', 'app', 'deb', 'rpm', 'apk'],\r\n code: ['js', 'ts', 'py', 'java', 'cpp', 'c', 'cs', 'go', 'rs', 'rb', 'php'],\r\n };\r\n\r\n for (const [type, extensions] of Object.entries(types)) {\r\n if (extensions.includes(extension.toLowerCase())) {\r\n return type;\r\n }\r\n }\r\n return 'other';\r\n}\r\n\r\n/**\r\n * Generates a unique download ID.\r\n */\r\nexport function generateDownloadId(): string {\r\n return `dl_${Date.now().toString(36)}_${Math.random().toString(36).substring(2, 9)}`;\r\n}\r\n\r\n/**\r\n * Validates a checksum against file data.\r\n */\r\nexport async function validateChecksum(\r\n data: ArrayBuffer,\r\n checksum: FileChecksum,\r\n): Promise<boolean> {\r\n if (typeof crypto === 'undefined' || !crypto.subtle) {\r\n console.warn('Web Crypto API not available for checksum validation');\r\n return true; // Skip validation\r\n }\r\n\r\n const algorithmMap: Record<string, string> = {\r\n sha256: 'SHA-256',\r\n sha512: 'SHA-512',\r\n sha1: 'SHA-1',\r\n };\r\n\r\n const algorithm = algorithmMap[checksum.algorithm];\r\n if (!algorithm) {\r\n console.warn(`Unsupported checksum algorithm: ${checksum.algorithm}`);\r\n return true;\r\n }\r\n\r\n const hashBuffer = await crypto.subtle.digest(algorithm, data);\r\n const hashArray = Array.from(new Uint8Array(hashBuffer));\r\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\r\n\r\n return hashHex.toLowerCase() === checksum.value.toLowerCase();\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Download Segment Manager\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\nexport interface DownloadSegment {\r\n index: number;\r\n start: number;\r\n end: number;\r\n downloaded: number;\r\n status: 'pending' | 'downloading' | 'completed' | 'failed';\r\n retries: number;\r\n}\r\n\r\n/**\r\n * Creates segments for parallel downloading.\r\n */\r\nexport function createDownloadSegments(totalSize: number, segmentCount: number): DownloadSegment[] {\r\n if (totalSize <= 0 || segmentCount <= 0) {\r\n return [];\r\n }\r\n\r\n const segmentSize = Math.ceil(totalSize / segmentCount);\r\n const segments: DownloadSegment[] = [];\r\n\r\n for (let i = 0; i < segmentCount; i++) {\r\n const start = i * segmentSize;\r\n const end = Math.min(start + segmentSize - 1, totalSize - 1);\r\n\r\n segments.push({\r\n index: i,\r\n start,\r\n end,\r\n downloaded: 0,\r\n status: 'pending',\r\n retries: 0,\r\n });\r\n }\r\n\r\n return segments;\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Download Manager Class\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\nexport type DownloadEventType =\r\n | 'added'\r\n | 'started'\r\n | 'progress'\r\n | 'paused'\r\n | 'resumed'\r\n | 'completed'\r\n | 'failed'\r\n | 'cancelled'\r\n | 'queue-changed';\r\n\r\nexport interface DownloadEvent {\r\n type: DownloadEventType;\r\n download?: DownloadItem;\r\n queue?: DownloadQueue;\r\n error?: Error;\r\n}\r\n\r\nexport type DownloadEventCallback = (event: DownloadEvent) => void;\r\n\r\n/**\r\n * Core Download Manager service.\r\n */\r\nexport class DownloadManager {\r\n private config: DownloadManagerConfig;\r\n private downloads: Map<string, DownloadItem> = new Map();\r\n private activeDownloads: Set<string> = new Set();\r\n private abortControllers: Map<string, AbortController> = new Map();\r\n private speedSamples: Map<string, number[]> = new Map();\r\n private eventListeners: Map<DownloadEventType, Set<DownloadEventCallback>> = new Map();\r\n private updateInterval: ReturnType<typeof setInterval> | null = null;\r\n\r\n constructor(config: Partial<DownloadManagerConfig> = {}) {\r\n this.config = {\r\n defaultDownloadPath: config.defaultDownloadPath ?? '/downloads',\r\n maxConcurrentDownloads: config.maxConcurrentDownloads ?? 3,\r\n bandwidthLimit: config.bandwidthLimit,\r\n retryAttempts: config.retryAttempts ?? 3,\r\n retryDelay: config.retryDelay ?? 5000,\r\n autoStart: config.autoStart ?? true,\r\n resumeOnStartup: config.resumeOnStartup ?? true,\r\n categories: config.categories ?? [],\r\n fileTypeFilters: config.fileTypeFilters ?? [],\r\n };\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Event Handling\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Subscribes to download events.\r\n */\r\n on(event: DownloadEventType, callback: DownloadEventCallback): () => void {\r\n if (!this.eventListeners.has(event)) {\r\n this.eventListeners.set(event, new Set());\r\n }\r\n this.eventListeners.get(event)!.add(callback);\r\n return () => this.eventListeners.get(event)?.delete(callback);\r\n }\r\n\r\n /**\r\n * Emits a download event.\r\n */\r\n private emit(event: DownloadEvent): void {\r\n const listeners = this.eventListeners.get(event.type);\r\n if (listeners) {\r\n for (const callback of listeners) {\r\n try {\r\n callback(event);\r\n } catch (error) {\r\n console.error('Download event listener error:', error);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Queue Management\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Adds a download to the queue.\r\n */\r\n addDownload(\r\n url: string,\r\n options: Partial<{\r\n filename: string;\r\n path: string;\r\n priority: DownloadPriority;\r\n category: string;\r\n checksum: FileChecksum;\r\n autoStart: boolean;\r\n headers: Record<string, string>;\r\n }> = {},\r\n ): DownloadItem {\r\n const parsed = parseDownloadUrl(url);\r\n const id = generateDownloadId();\r\n\r\n const download: DownloadItem = {\r\n id,\r\n url,\r\n filename: options.filename ?? parsed.filename,\r\n path: options.path ?? this.config.defaultDownloadPath,\r\n status: 'queued',\r\n priority: options.priority ?? 'normal',\r\n size: parsed.size,\r\n downloadedBytes: 0,\r\n progress: 0,\r\n speed: formatSpeed(0),\r\n addedDate: new Date(),\r\n retryCount: 0,\r\n category: options.category ?? this.detectCategory(parsed.extension),\r\n source: {\r\n type: parsed.isMagnet ? 'magnet' : 'direct',\r\n protocol: parsed.protocol,\r\n host: parsed.host,\r\n },\r\n checksum: options.checksum,\r\n };\r\n\r\n this.downloads.set(id, download);\r\n this.emit({ type: 'added', download });\r\n this.emitQueueChanged();\r\n\r\n // Auto-start if configured and queue has capacity\r\n if (\r\n (options.autoStart ?? this.config.autoStart) &&\r\n this.activeDownloads.size < this.config.maxConcurrentDownloads\r\n ) {\r\n this.startDownload(id);\r\n }\r\n\r\n return download;\r\n }\r\n\r\n /**\r\n * Adds multiple downloads from URLs.\r\n */\r\n addDownloads(\r\n urls: string[],\r\n options: Partial<{\r\n path: string;\r\n priority: DownloadPriority;\r\n category: string;\r\n autoStart: boolean;\r\n }> = {},\r\n ): DownloadItem[] {\r\n return urls.map((url) => this.addDownload(url, options));\r\n }\r\n\r\n /**\r\n * Removes a download from the queue.\r\n */\r\n removeDownload(id: string, deleteFile = false): boolean {\r\n const download = this.downloads.get(id);\r\n if (!download) {\r\n return false;\r\n }\r\n\r\n // Cancel if active\r\n this.cancelDownload(id);\r\n\r\n this.downloads.delete(id);\r\n this.emitQueueChanged();\r\n\r\n // Note: File deletion would require file system access\r\n if (deleteFile) {\r\n console.warn('File deletion not implemented in browser environment');\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Gets a download by ID.\r\n */\r\n getDownload(id: string): DownloadItem | undefined {\r\n return this.downloads.get(id);\r\n }\r\n\r\n /**\r\n * Gets all downloads.\r\n */\r\n getAllDownloads(): DownloadItem[] {\r\n return Array.from(this.downloads.values());\r\n }\r\n\r\n /**\r\n * Gets the download queue summary.\r\n */\r\n getQueue(): DownloadQueue {\r\n const items = this.getAllDownloads();\r\n const totalSize = items.reduce((sum, d) => sum + (d.size ?? 0), 0);\r\n const totalDownloaded = items.reduce((sum, d) => sum + d.downloadedBytes, 0);\r\n\r\n return {\r\n items,\r\n totalSize,\r\n totalProgress: totalSize > 0 ? (totalDownloaded / totalSize) * 100 : 0,\r\n activeDownloads: this.activeDownloads.size,\r\n queuedDownloads: items.filter((d) => d.status === 'queued').length,\r\n completedDownloads: items.filter((d) => d.status === 'completed').length,\r\n };\r\n }\r\n\r\n /**\r\n * Gets downloads by status.\r\n */\r\n getDownloadsByStatus(status: DownloadStatus): DownloadItem[] {\r\n return this.getAllDownloads().filter((d) => d.status === status);\r\n }\r\n\r\n /**\r\n * Gets downloads by category.\r\n */\r\n getDownloadsByCategory(category: string): DownloadItem[] {\r\n return this.getAllDownloads().filter((d) => d.category === category);\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Download Control\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Starts a download.\r\n */\r\n async startDownload(id: string): Promise<void> {\r\n const download = this.downloads.get(id);\r\n if (!download) {\r\n return;\r\n }\r\n\r\n if (download.status === 'downloading') {\r\n return;\r\n }\r\n if (this.activeDownloads.size >= this.config.maxConcurrentDownloads) {\r\n download.status = 'queued';\r\n return;\r\n }\r\n\r\n download.status = 'downloading';\r\n download.startedDate = new Date();\r\n this.activeDownloads.add(id);\r\n\r\n const abortController = new AbortController();\r\n this.abortControllers.set(id, abortController);\r\n this.speedSamples.set(id, []);\r\n\r\n this.emit({ type: 'started', download });\r\n\r\n try {\r\n await this.executeDownload(download, abortController.signal);\r\n\r\n download.status = 'completed';\r\n download.completedDate = new Date();\r\n download.progress = 100;\r\n this.emit({ type: 'completed', download });\r\n } catch (error) {\r\n if (abortController.signal.aborted) {\r\n // Cancelled by user\r\n return;\r\n }\r\n\r\n download.errorMessage = error instanceof Error ? error.message : 'Download failed';\r\n\r\n // Retry logic\r\n if (download.retryCount < this.config.retryAttempts) {\r\n download.retryCount++;\r\n download.status = 'queued';\r\n setTimeout(() => this.startDownload(id), this.config.retryDelay);\r\n } else {\r\n download.status = 'failed';\r\n this.emit({\r\n type: 'failed',\r\n download,\r\n error: error instanceof Error ? error : new Error(String(error)),\r\n });\r\n }\r\n } finally {\r\n this.activeDownloads.delete(id);\r\n this.abortControllers.delete(id);\r\n this.speedSamples.delete(id);\r\n this.emitQueueChanged();\r\n\r\n // Start next in queue\r\n this.processQueue();\r\n }\r\n }\r\n\r\n /**\r\n * Pauses a download.\r\n */\r\n pauseDownload(id: string): void {\r\n const download = this.downloads.get(id);\r\n if (!download || download.status !== 'downloading') {\r\n return;\r\n }\r\n\r\n const controller = this.abortControllers.get(id);\r\n if (controller) {\r\n controller.abort();\r\n }\r\n\r\n download.status = 'paused';\r\n this.activeDownloads.delete(id);\r\n this.emit({ type: 'paused', download });\r\n this.emitQueueChanged();\r\n\r\n // Start next in queue\r\n this.processQueue();\r\n }\r\n\r\n /**\r\n * Resumes a paused download.\r\n */\r\n resumeDownload(id: string): void {\r\n const download = this.downloads.get(id);\r\n if (!download || download.status !== 'paused') {\r\n return;\r\n }\r\n\r\n download.status = 'queued';\r\n this.emit({ type: 'resumed', download });\r\n this.startDownload(id);\r\n }\r\n\r\n /**\r\n * Cancels a download.\r\n */\r\n cancelDownload(id: string): void {\r\n const download = this.downloads.get(id);\r\n if (!download) {\r\n return;\r\n }\r\n\r\n const controller = this.abortControllers.get(id);\r\n if (controller) {\r\n controller.abort();\r\n }\r\n\r\n download.status = 'cancelled';\r\n this.activeDownloads.delete(id);\r\n this.emit({ type: 'cancelled', download });\r\n this.emitQueueChanged();\r\n\r\n this.processQueue();\r\n }\r\n\r\n /**\r\n * Pauses all active downloads.\r\n */\r\n pauseAll(): void {\r\n for (const id of this.activeDownloads) {\r\n this.pauseDownload(id);\r\n }\r\n }\r\n\r\n /**\r\n * Resumes all paused downloads.\r\n */\r\n resumeAll(): void {\r\n for (const download of this.downloads.values()) {\r\n if (download.status === 'paused') {\r\n this.resumeDownload(download.id);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Cancels all downloads.\r\n */\r\n cancelAll(): void {\r\n for (const id of this.downloads.keys()) {\r\n this.cancelDownload(id);\r\n }\r\n }\r\n\r\n /**\r\n * Changes download priority.\r\n */\r\n setPriority(id: string, priority: DownloadPriority): void {\r\n const download = this.downloads.get(id);\r\n if (download) {\r\n download.priority = priority;\r\n this.emitQueueChanged();\r\n }\r\n }\r\n\r\n /**\r\n * Moves a download in the queue.\r\n */\r\n moveInQueue(id: string, direction: 'up' | 'down' | 'top' | 'bottom'): void {\r\n const items = this.getAllDownloads().filter((d) => d.status === 'queued');\r\n const index = items.findIndex((d) => d.id === id);\r\n if (index === -1) {\r\n return;\r\n }\r\n\r\n // Re-prioritize based on direction\r\n switch (direction) {\r\n case 'top':\r\n items[index].priority = 'critical';\r\n break;\r\n case 'up':\r\n if (items[index].priority === 'normal') {\r\n items[index].priority = 'high';\r\n } else if (items[index].priority === 'low') {\r\n items[index].priority = 'normal';\r\n }\r\n break;\r\n case 'down':\r\n if (items[index].priority === 'normal') {\r\n items[index].priority = 'low';\r\n } else if (items[index].priority === 'high') {\r\n items[index].priority = 'normal';\r\n }\r\n break;\r\n case 'bottom':\r\n items[index].priority = 'low';\r\n break;\r\n }\r\n\r\n this.emitQueueChanged();\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Configuration\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Gets the current configuration.\r\n */\r\n getConfig(): DownloadManagerConfig {\r\n return { ...this.config };\r\n }\r\n\r\n /**\r\n * Updates the configuration.\r\n */\r\n updateConfig(updates: Partial<DownloadManagerConfig>): void {\r\n this.config = { ...this.config, ...updates };\r\n }\r\n\r\n /**\r\n * Sets bandwidth limit.\r\n */\r\n setBandwidthLimit(limit: BandwidthLimit | undefined): void {\r\n this.config.bandwidthLimit = limit;\r\n }\r\n\r\n /**\r\n * Sets maximum concurrent downloads.\r\n */\r\n setMaxConcurrentDownloads(max: number): void {\r\n this.config.maxConcurrentDownloads = max;\r\n this.processQueue();\r\n }\r\n\r\n /**\r\n * Adds a download category.\r\n */\r\n addCategory(category: DownloadCategory): void {\r\n this.config.categories = [...(this.config.categories ?? []), category];\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Statistics\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Gets overall transfer statistics.\r\n */\r\n getStats(): TransferStats {\r\n const downloads = this.getAllDownloads();\r\n const downloaded = downloads.reduce((sum, d) => sum + d.downloadedBytes, 0);\r\n const total = downloads.reduce((sum, d) => sum + (d.size ?? 0), 0);\r\n\r\n // Calculate aggregate speed\r\n let totalSpeed = 0;\r\n for (const id of this.activeDownloads) {\r\n const download = this.downloads.get(id);\r\n if (download) {\r\n totalSpeed += download.speed.bytesPerSecond;\r\n }\r\n }\r\n\r\n return {\r\n downloaded,\r\n uploaded: 0,\r\n remaining: total - downloaded,\r\n total,\r\n progress: total > 0 ? (downloaded / total) * 100 : 0,\r\n downloadSpeed: formatSpeed(totalSpeed),\r\n uploadSpeed: formatSpeed(0),\r\n eta: totalSpeed > 0 ? calculateETA(total - downloaded, totalSpeed) : undefined,\r\n };\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Private Methods\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Executes the actual download using Fetch API.\r\n */\r\n private async executeDownload(download: DownloadItem, signal: AbortSignal): Promise<void> {\r\n const response = await fetch(download.url, {\r\n signal,\r\n headers: download.source?.auth ? this.buildAuthHeaders(download.source.auth) : undefined,\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\r\n }\r\n\r\n const contentLength = response.headers.get('content-length');\r\n if (contentLength) {\r\n download.size = parseInt(contentLength, 10);\r\n }\r\n\r\n const reader = response.body?.getReader();\r\n if (!reader) {\r\n throw new Error('Response body is not readable');\r\n }\r\n\r\n const chunks: Uint8Array[] = [];\r\n let lastUpdate = Date.now();\r\n let bytesInInterval = 0;\r\n\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n\r\n if (done) {\r\n break;\r\n }\r\n\r\n chunks.push(value);\r\n download.downloadedBytes += value.length;\r\n bytesInInterval += value.length;\r\n\r\n // Update progress\r\n if (download.size) {\r\n download.progress = (download.downloadedBytes / download.size) * 100;\r\n }\r\n\r\n // Calculate speed every 500ms\r\n const now = Date.now();\r\n const elapsed = now - lastUpdate;\r\n if (elapsed >= 500) {\r\n const speed = (bytesInInterval / elapsed) * 1000;\r\n this.updateSpeed(download.id, speed);\r\n download.speed = formatSpeed(speed);\r\n download.eta = download.size\r\n ? calculateETA(download.size - download.downloadedBytes, speed)\r\n : undefined;\r\n\r\n this.emit({ type: 'progress', download });\r\n\r\n lastUpdate = now;\r\n bytesInInterval = 0;\r\n }\r\n }\r\n\r\n // Combine chunks and validate checksum if provided\r\n const data = new Uint8Array(download.downloadedBytes);\r\n let offset = 0;\r\n for (const chunk of chunks) {\r\n data.set(chunk, offset);\r\n offset += chunk.length;\r\n }\r\n\r\n if (download.checksum) {\r\n const valid = await validateChecksum(data.buffer, download.checksum);\r\n if (!valid) {\r\n throw new Error('Checksum validation failed');\r\n }\r\n download.checksum.verified = true;\r\n }\r\n\r\n // In a browser environment, we'd typically create a blob and trigger download\r\n // For Node.js/Electron, we'd write to the file system\r\n this.handleDownloadComplete(download, data);\r\n }\r\n\r\n /**\r\n * Handles completed download data.\r\n */\r\n private handleDownloadComplete(download: DownloadItem, data: Uint8Array): void {\r\n // Create blob and download link for browser\r\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\r\n const blob = new Blob([new Uint8Array(data)]);\r\n const url = URL.createObjectURL(blob);\r\n const a = document.createElement('a');\r\n a.href = url;\r\n a.download = download.filename;\r\n document.body.appendChild(a);\r\n a.click();\r\n document.body.removeChild(a);\r\n URL.revokeObjectURL(url);\r\n }\r\n }\r\n\r\n /**\r\n * Builds authentication headers.\r\n */\r\n private buildAuthHeaders(auth: DownloadSource['auth']): Record<string, string> {\r\n if (!auth) {\r\n return {};\r\n }\r\n\r\n switch (auth.type) {\r\n case 'basic': {\r\n const credentials = btoa(`${auth.username}:${auth.password}`);\r\n return { Authorization: `Basic ${credentials}` };\r\n }\r\n case 'bearer':\r\n return { Authorization: `Bearer ${auth.token}` };\r\n case 'api_key':\r\n return { 'X-API-Key': auth.apiKey ?? '' };\r\n default:\r\n return {};\r\n }\r\n }\r\n\r\n /**\r\n * Updates speed tracking for a download.\r\n */\r\n private updateSpeed(id: string, speed: number): void {\r\n const samples = this.speedSamples.get(id) || [];\r\n samples.push(speed);\r\n\r\n // Keep last 10 samples for smoothing\r\n if (samples.length > 10) {\r\n samples.shift();\r\n }\r\n\r\n this.speedSamples.set(id, samples);\r\n }\r\n\r\n /**\r\n * Processes the download queue.\r\n */\r\n private processQueue(): void {\r\n if (this.activeDownloads.size >= this.config.maxConcurrentDownloads) {\r\n return;\r\n }\r\n\r\n // Get queued downloads sorted by priority\r\n const queued = this.getDownloadsByStatus('queued').sort((a, b) => {\r\n const priorityOrder = { critical: 0, high: 1, normal: 2, low: 3 };\r\n return priorityOrder[a.priority] - priorityOrder[b.priority];\r\n });\r\n\r\n for (const download of queued) {\r\n if (this.activeDownloads.size >= this.config.maxConcurrentDownloads) {\r\n break;\r\n }\r\n this.startDownload(download.id);\r\n }\r\n }\r\n\r\n /**\r\n * Detects category from file extension.\r\n */\r\n private detectCategory(extension?: string): string | undefined {\r\n if (!extension || !this.config.categories) {\r\n return undefined;\r\n }\r\n\r\n for (const category of this.config.categories) {\r\n if (category.fileTypes?.includes(extension.toLowerCase())) {\r\n return category.id;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Emits a queue changed event.\r\n */\r\n private emitQueueChanged(): void {\r\n this.emit({ type: 'queue-changed', queue: this.getQueue() });\r\n }\r\n\r\n /**\r\n * Disposes the download manager.\r\n */\r\n dispose(): void {\r\n this.cancelAll();\r\n if (this.updateInterval) {\r\n clearInterval(this.updateInterval);\r\n }\r\n this.eventListeners.clear();\r\n this.downloads.clear();\r\n }\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Singleton Instance\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\nlet downloadManagerInstance: DownloadManager | null = null;\r\n\r\n/**\r\n * Gets or creates the download manager singleton.\r\n */\r\nexport function getDownloadManager(config?: Partial<DownloadManagerConfig>): DownloadManager {\r\n if (!downloadManagerInstance) {\r\n downloadManagerInstance = new DownloadManager(config);\r\n }\r\n return downloadManagerInstance;\r\n}\r\n\r\n/**\r\n * Disposes the download manager singleton.\r\n */\r\nexport function disposeDownloadManager(): void {\r\n downloadManagerInstance?.dispose();\r\n downloadManagerInstance = null;\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n React Hook\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\nimport { useState, useEffect, useCallback, useMemo } from 'react';\r\n\r\nexport interface UseDownloadManagerOptions {\r\n config?: Partial<DownloadManagerConfig>;\r\n autoRefresh?: boolean;\r\n refreshInterval?: number;\r\n}\r\n\r\nexport interface UseDownloadManagerReturn {\r\n /** Queue state */\r\n queue: DownloadQueue;\r\n /** Transfer stats */\r\n stats: TransferStats;\r\n /** Active downloads */\r\n activeDownloads: DownloadItem[];\r\n /** Add a download */\r\n addDownload: (\r\n url: string,\r\n options?: Parameters<DownloadManager['addDownload']>[1],\r\n ) => DownloadItem;\r\n /** Add multiple downloads */\r\n addDownloads: (\r\n urls: string[],\r\n options?: Parameters<DownloadManager['addDownloads']>[1],\r\n ) => DownloadItem[];\r\n /** Start a download */\r\n startDownload: (id: string) => void;\r\n /** Pause a download */\r\n pauseDownload: (id: string) => void;\r\n /** Resume a download */\r\n resumeDownload: (id: string) => void;\r\n /** Cancel a download */\r\n cancelDownload: (id: string) => void;\r\n /** Remove a download */\r\n removeDownload: (id: string, deleteFile?: boolean) => void;\r\n /** Pause all downloads */\r\n pauseAll: () => void;\r\n /** Resume all downloads */\r\n resumeAll: () => void;\r\n /** Set bandwidth limit */\r\n setBandwidthLimit: (limit: BandwidthLimit | undefined) => void;\r\n /** Set priority */\r\n setPriority: (id: string, priority: DownloadPriority) => void;\r\n}\r\n\r\n/**\r\n * React hook for download manager.\r\n */\r\nexport function useDownloadManager(\r\n options: UseDownloadManagerOptions = {},\r\n): UseDownloadManagerReturn {\r\n const { config, autoRefresh = true, refreshInterval = 1000 } = options;\r\n\r\n const manager = useMemo(() => getDownloadManager(config), [config]);\r\n\r\n const [queue, setQueue] = useState<DownloadQueue>(manager.getQueue());\r\n const [stats, setStats] = useState<TransferStats>(manager.getStats());\r\n\r\n useEffect(() => {\r\n const handleQueueChange = () => {\r\n setQueue(manager.getQueue());\r\n setStats(manager.getStats());\r\n };\r\n\r\n const unsubscribers = [\r\n manager.on('added', handleQueueChange),\r\n manager.on('started', handleQueueChange),\r\n manager.on('progress', handleQueueChange),\r\n manager.on('paused', handleQueueChange),\r\n manager.on('resumed', handleQueueChange),\r\n manager.on('completed', handleQueueChange),\r\n manager.on('failed', handleQueueChange),\r\n manager.on('cancelled', handleQueueChange),\r\n manager.on('queue-changed', handleQueueChange),\r\n ];\r\n\r\n // Auto-refresh for active downloads\r\n let interval: ReturnType<typeof setInterval> | undefined;\r\n if (autoRefresh) {\r\n interval = setInterval(() => {\r\n if (manager.getQueue().activeDownloads > 0) {\r\n handleQueueChange();\r\n }\r\n }, refreshInterval);\r\n }\r\n\r\n return () => {\r\n unsubscribers.forEach((unsub) => unsub());\r\n if (interval) {\r\n clearInterval(interval);\r\n }\r\n };\r\n }, [manager, autoRefresh, refreshInterval]);\r\n\r\n const activeDownloads = useMemo(\r\n () => queue.items.filter((d) => d.status === 'downloading'),\r\n [queue],\r\n );\r\n\r\n const addDownload = useCallback(\r\n (url: string, opts?: Parameters<DownloadManager['addDownload']>[1]) =>\r\n manager.addDownload(url, opts),\r\n [manager],\r\n );\r\n\r\n const addDownloads = useCallback(\r\n (urls: string[], opts?: Parameters<DownloadManager['addDownloads']>[1]) =>\r\n manager.addDownloads(urls, opts),\r\n [manager],\r\n );\r\n\r\n return {\r\n queue,\r\n stats,\r\n activeDownloads,\r\n addDownload,\r\n addDownloads,\r\n startDownload: useCallback((id) => manager.startDownload(id), [manager]),\r\n pauseDownload: useCallback((id) => manager.pauseDownload(id), [manager]),\r\n resumeDownload: useCallback((id) => manager.resumeDownload(id), [manager]),\r\n cancelDownload: useCallback((id) => manager.cancelDownload(id), [manager]),\r\n removeDownload: useCallback(\r\n (id, deleteFile) => manager.removeDownload(id, deleteFile),\r\n [manager],\r\n ),\r\n pauseAll: useCallback(() => manager.pauseAll(), [manager]),\r\n resumeAll: useCallback(() => manager.resumeAll(), [manager]),\r\n setBandwidthLimit: useCallback((limit) => manager.setBandwidthLimit(limit), [manager]),\r\n setPriority: useCallback((id, priority) => manager.setPriority(id, priority), [manager]),\r\n };\r\n}\r\n","/**\r\n * @file torrent-client.ts\r\n * @module @nice2dev/ui-tools\r\n * @description PRO-31.2 — BitTorrent Client Service\r\n *\r\n * Provides BitTorrent functionality including magnet handling, DHT, PEX,\r\n * selective file download, sequential downloading, and torrent creation.\r\n */\r\n\r\nimport { formatSpeed, calculateETA } from './download-manager';\r\nimport type {\r\n Torrent,\r\n TorrentFile,\r\n TorrentClientConfig,\r\n TorrentTracker,\r\n Peer,\r\n TorrentStatus,\r\n DownloadPriority,\r\n TorrentDashboardStats,\r\n TransferSpeed as _TransferSpeed,\r\n MagnetLinkInfo,\r\n PieceStatus,\r\n TorrentCreationOptions as _TorrentCreationOptions,\r\n CreatedTorrent,\r\n BandwidthLimit as _BandwidthLimit,\r\n} from './download-torrent';\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Torrent Utilities\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\n/**\r\n * Generates an info hash from torrent metadata.\r\n */\r\nexport function generateInfoHash(): string {\r\n const chars = '0123456789abcdef';\r\n let hash = '';\r\n for (let i = 0; i < 40; i++) {\r\n hash += chars[Math.floor(Math.random() * chars.length)];\r\n }\r\n return hash;\r\n}\r\n\r\n/**\r\n * Generates a peer ID.\r\n */\r\nexport function generatePeerId(): string {\r\n const clientId = '-NI0100-'; // NI = Nice2Dev, version 01.00\r\n const randomPart = Array.from({ length: 12 }, () =>\r\n Math.floor(Math.random() * 256)\r\n .toString(16)\r\n .padStart(2, '0'),\r\n ).join('');\r\n return clientId + randomPart;\r\n}\r\n\r\n/**\r\n * Parses a magnet link.\r\n */\r\nexport function parseMagnetUri(magnetUri: string): MagnetLinkInfo | null {\r\n if (!magnetUri.startsWith('magnet:?')) {\r\n return null;\r\n }\r\n\r\n const params = new URLSearchParams(magnetUri.replace('magnet:?', ''));\r\n\r\n const xt = params.get('xt');\r\n if (!xt) {\r\n return null;\r\n }\r\n\r\n const infoHash = xt.replace('urn:btih:', '');\r\n const displayName = params.get('dn') || undefined;\r\n const trackers = params.getAll('tr');\r\n const exactLength = params.get('xl') ? parseInt(params.get('xl')!, 10) : undefined;\r\n const keywords = params.get('kt')?.split('+') || undefined;\r\n\r\n return {\r\n infoHash,\r\n displayName,\r\n trackers: trackers.length > 0 ? trackers : undefined,\r\n exactLength,\r\n keywords,\r\n };\r\n}\r\n\r\n/**\r\n * Creates a magnet URI from torrent info.\r\n */\r\nexport function createMagnetUri(torrent: {\r\n infoHash: string;\r\n name: string;\r\n trackers?: string[];\r\n size?: number;\r\n}): string {\r\n const params = new URLSearchParams();\r\n params.set('xt', `urn:btih:${torrent.infoHash}`);\r\n params.set('dn', torrent.name);\r\n\r\n if (torrent.size) {\r\n params.set('xl', torrent.size.toString());\r\n }\r\n\r\n if (torrent.trackers) {\r\n for (const tracker of torrent.trackers) {\r\n params.append('tr', tracker);\r\n }\r\n }\r\n\r\n return `magnet:?${params.toString()}`;\r\n}\r\n\r\n/**\r\n * Calculates pieces for a file.\r\n */\r\nexport function calculatePieces(totalSize: number, pieceSize: number = 262144): number {\r\n return Math.ceil(totalSize / pieceSize);\r\n}\r\n\r\n/**\r\n * Creates piece array for a torrent.\r\n */\r\nexport function createPieceStatus(pieceCount: number): PieceStatus[] {\r\n return Array.from({ length: pieceCount }, () => 'missing' as PieceStatus);\r\n}\r\n\r\n/**\r\n * Formats peer count display.\r\n */\r\nexport function formatPeerCount(connected: number, total: number): string {\r\n return `${connected}/${total}`;\r\n}\r\n\r\n/**\r\n * Calculates torrent health based on seeders and leechers.\r\n */\r\nexport function calculateTorrentHealth(\r\n seeders: number,\r\n leechers: number,\r\n): 'excellent' | 'good' | 'fair' | 'poor' | 'dead' {\r\n if (seeders === 0) {\r\n return 'dead';\r\n }\r\n const ratio = seeders / (leechers + 1);\r\n if (ratio >= 2 && seeders >= 10) {\r\n return 'excellent';\r\n }\r\n if (ratio >= 1 && seeders >= 5) {\r\n return 'good';\r\n }\r\n if (seeders >= 1) {\r\n return 'fair';\r\n }\r\n return 'poor';\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Torrent File Selection\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\n/**\r\n * Creates a file selection map from torrent files.\r\n */\r\nexport function createFileSelection(files: TorrentFile[]): Map<number, boolean> {\r\n return new Map(files.map((f) => [f.index, f.wanted]));\r\n}\r\n\r\n/**\r\n * Filters files by extension.\r\n */\r\nexport function filterFilesByExtension(files: TorrentFile[], extensions: string[]): TorrentFile[] {\r\n return files.filter((f) => {\r\n const ext = f.name.split('.').pop()?.toLowerCase();\r\n return ext && extensions.includes(ext);\r\n });\r\n}\r\n\r\n/**\r\n * Gets video files from torrent.\r\n */\r\nexport function getVideoFiles(files: TorrentFile[]): TorrentFile[] {\r\n const videoExtensions = ['mp4', 'mkv', 'avi', 'mov', 'wmv', 'flv', 'webm', 'm4v', 'mpeg', 'mpg'];\r\n return filterFilesByExtension(files, videoExtensions);\r\n}\r\n\r\n/**\r\n * Gets audio files from torrent.\r\n */\r\nexport function getAudioFiles(files: TorrentFile[]): TorrentFile[] {\r\n const audioExtensions = ['mp3', 'flac', 'wav', 'aac', 'ogg', 'wma', 'm4a', 'opus'];\r\n return filterFilesByExtension(files, audioExtensions);\r\n}\r\n\r\n/**\r\n * Gets largest file in torrent.\r\n */\r\nexport function getLargestFile(files: TorrentFile[]): TorrentFile | undefined {\r\n return files.reduce(\r\n (largest, file) => (file.size > (largest?.size ?? 0) ? file : largest),\r\n undefined as TorrentFile | undefined,\r\n );\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Torrent Event System\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\nexport type TorrentEventType =\r\n | 'added'\r\n | 'metadata'\r\n | 'started'\r\n | 'progress'\r\n | 'piece'\r\n | 'paused'\r\n | 'resumed'\r\n | 'completed'\r\n | 'seeding'\r\n | 'failed'\r\n | 'removed'\r\n | 'peer-connect'\r\n | 'peer-disconnect'\r\n | 'tracker-update';\r\n\r\nexport interface TorrentEvent {\r\n type: TorrentEventType;\r\n torrent?: Torrent;\r\n peer?: Peer;\r\n tracker?: TorrentTracker;\r\n pieceIndex?: number;\r\n error?: Error;\r\n}\r\n\r\nexport type TorrentEventCallback = (event: TorrentEvent) => void;\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Internal Torrent State (extends Torrent with additional runtime state)\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\ninterface InternalTorrentState extends Torrent {\r\n magnetUri?: string;\r\n startedDate?: Date;\r\n sequentialDownload?: boolean;\r\n selectedFiles?: number[];\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Torrent Client Class\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\n/**\r\n * BitTorrent Client service.\r\n */\r\nexport class TorrentClient {\r\n private config: TorrentClientConfig;\r\n private torrents: Map<string, InternalTorrentState> = new Map();\r\n private eventListeners: Map<TorrentEventType, Set<TorrentEventCallback>> = new Map();\r\n private peerId: string;\r\n private updateIntervals: Map<string, ReturnType<typeof setInterval>> = new Map();\r\n\r\n constructor(config: Partial<TorrentClientConfig> = {}) {\r\n this.peerId = generatePeerId();\r\n this.config = {\r\n downloadPath: config.downloadPath ?? '/downloads/torrents',\r\n tempPath: config.tempPath,\r\n maxActiveTorrents: config.maxActiveTorrents ?? 5,\r\n maxActiveSeedsperTorrent: config.maxActiveSeedsperTorrent ?? 50,\r\n maxConnectionsPerTorrent: config.maxConnectionsPerTorrent ?? 50,\r\n maxGlobalConnections: config.maxGlobalConnections ?? 200,\r\n bandwidthLimit: config.bandwidthLimit ?? { enabled: false, unit: 'MB/s' },\r\n dhtEnabled: config.dhtEnabled ?? true,\r\n pexEnabled: config.pexEnabled ?? true,\r\n lpdEnabled: config.lpdEnabled ?? true,\r\n upnpEnabled: config.upnpEnabled ?? true,\r\n natPmpEnabled: config.natPmpEnabled ?? true,\r\n encryptionMode: config.encryptionMode ?? 'enabled',\r\n ipv6Enabled: config.ipv6Enabled ?? true,\r\n listeningPort: config.listeningPort ?? 6881,\r\n proxySettings: config.proxySettings,\r\n };\r\n\r\n if (this.config.dhtEnabled) {\r\n this.initDHT();\r\n }\r\n if (this.config.pexEnabled) {\r\n this.initPEX();\r\n }\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Event Handling\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Subscribes to torrent events.\r\n */\r\n on(event: TorrentEventType, callback: TorrentEventCallback): () => void {\r\n if (!this.eventListeners.has(event)) {\r\n this.eventListeners.set(event, new Set());\r\n }\r\n this.eventListeners.get(event)!.add(callback);\r\n return () => this.eventListeners.get(event)?.delete(callback);\r\n }\r\n\r\n /**\r\n * Emits a torrent event.\r\n */\r\n private emit(event: TorrentEvent): void {\r\n const listeners = this.eventListeners.get(event.type);\r\n if (listeners) {\r\n for (const callback of listeners) {\r\n try {\r\n callback(event);\r\n } catch (error) {\r\n console.error('Torrent event listener error:', error);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Torrent Management\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Adds a torrent from magnet URI.\r\n */\r\n addMagnet(\r\n magnetUri: string,\r\n options: Partial<{\r\n path: string;\r\n priority: DownloadPriority;\r\n autoStart: boolean;\r\n sequentialDownload: boolean;\r\n selectedFiles: number[];\r\n }> = {},\r\n ): Torrent | null {\r\n const magnetInfo = parseMagnetUri(magnetUri);\r\n if (!magnetInfo) {\r\n console.error('Invalid magnet URI');\r\n return null;\r\n }\r\n\r\n // Check if already added\r\n if (this.torrents.has(magnetInfo.infoHash)) {\r\n return this.torrents.get(magnetInfo.infoHash)!;\r\n }\r\n\r\n const torrent = this.createTorrent({\r\n infoHash: magnetInfo.infoHash,\r\n name: magnetInfo.displayName ?? 'Unknown Torrent',\r\n size: magnetInfo.exactLength,\r\n trackers: magnetInfo.trackers,\r\n magnetUri,\r\n ...options,\r\n });\r\n\r\n this.torrents.set(torrent.infoHash, torrent);\r\n this.emit({ type: 'added', torrent });\r\n\r\n if (options.autoStart !== false) {\r\n this.startTorrent(torrent.infoHash);\r\n }\r\n\r\n return torrent;\r\n }\r\n\r\n /**\r\n * Adds a torrent from .torrent file data.\r\n */\r\n addTorrentFile(\r\n data: ArrayBuffer,\r\n options: Partial<{\r\n path: string;\r\n priority: DownloadPriority;\r\n autoStart: boolean;\r\n sequentialDownload: boolean;\r\n selectedFiles: number[];\r\n }> = {},\r\n ): Torrent | null {\r\n // In a real implementation, this would parse the bencode data\r\n // For now, we create a mock torrent\r\n const infoHash = generateInfoHash();\r\n\r\n const torrent = this.createTorrent({\r\n infoHash,\r\n name: 'Torrent from file',\r\n ...options,\r\n });\r\n\r\n this.torrents.set(torrent.infoHash, torrent);\r\n this.emit({ type: 'added', torrent });\r\n\r\n if (options.autoStart !== false) {\r\n this.startTorrent(torrent.infoHash);\r\n }\r\n\r\n return torrent;\r\n }\r\n\r\n /**\r\n * Creates a new torrent structure.\r\n */\r\n private createTorrent(params: {\r\n infoHash: string;\r\n name: string;\r\n size?: number;\r\n trackers?: string[];\r\n magnetUri?: string;\r\n path?: string;\r\n priority?: DownloadPriority;\r\n sequentialDownload?: boolean;\r\n selectedFiles?: number[];\r\n }): InternalTorrentState {\r\n const pieceCount = params.size ? calculatePieces(params.size) : 0;\r\n\r\n const trackers: TorrentTracker[] = (params.trackers || this.getDefaultTrackers())\r\n .filter((v, i, a) => a.indexOf(v) === i) // Deduplicate\r\n .map((url, index) => ({\r\n url,\r\n tier: Math.floor(index / 3),\r\n status: 'not_contacted' as const,\r\n seeds: undefined,\r\n leechers: undefined,\r\n }));\r\n\r\n return {\r\n id: `torrent_${Date.now().toString(36)}_${Math.random().toString(36).substring(2, 9)}`,\r\n infoHash: params.infoHash,\r\n name: params.name,\r\n status: 'queued',\r\n priority: params.priority ?? 'normal',\r\n\r\n // Size info\r\n size: params.size ?? 0,\r\n downloadedBytes: 0,\r\n uploadedBytes: 0,\r\n progress: 0,\r\n ratio: 0,\r\n\r\n // Speed\r\n downloadSpeed: formatSpeed(0),\r\n uploadSpeed: formatSpeed(0),\r\n\r\n // Peers\r\n seeds: 0,\r\n peers: 0,\r\n\r\n // Trackers\r\n trackers,\r\n\r\n // Files\r\n files: [],\r\n pieces: createPieceStatus(pieceCount),\r\n\r\n // Configuration\r\n savePath: params.path ?? this.config.downloadPath,\r\n isPrivate: false,\r\n\r\n // Metadata\r\n magnetUri: params.magnetUri,\r\n addedDate: new Date(),\r\n sequentialDownload: params.sequentialDownload ?? false,\r\n selectedFiles: params.selectedFiles ?? [],\r\n };\r\n }\r\n\r\n /**\r\n * Removes a torrent.\r\n */\r\n removeTorrent(infoHash: string, deleteData = false): boolean {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return false;\r\n }\r\n\r\n this.stopTorrent(infoHash);\r\n this.torrents.delete(infoHash);\r\n\r\n this.emit({ type: 'removed', torrent });\r\n\r\n if (deleteData) {\r\n console.warn('Data deletion not implemented in browser environment');\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Gets a torrent by info hash.\r\n */\r\n getTorrent(infoHash: string): Torrent | undefined {\r\n return this.torrents.get(infoHash);\r\n }\r\n\r\n /**\r\n * Gets all torrents.\r\n */\r\n getAllTorrents(): Torrent[] {\r\n return Array.from(this.torrents.values());\r\n }\r\n\r\n /**\r\n * Gets torrents by status.\r\n */\r\n getTorrentsByStatus(status: TorrentStatus): Torrent[] {\r\n return this.getAllTorrents().filter((t) => t.status === status);\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Torrent Control\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Starts a torrent.\r\n */\r\n startTorrent(infoHash: string): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n if (torrent.status === 'downloading' || torrent.status === 'seeding') {\r\n return;\r\n }\r\n\r\n // If no files yet (magnet), try to fetch metadata\r\n if (torrent.files.length === 0 && torrent.magnetUri) {\r\n torrent.status = 'checking'; // Use 'checking' for metadata fetch\r\n this.fetchMetadata(torrent);\r\n } else {\r\n torrent.status = 'downloading';\r\n torrent.startedDate = new Date();\r\n }\r\n\r\n this.emit({ type: 'started', torrent });\r\n this.simulateTorrentProgress(infoHash);\r\n }\r\n\r\n /**\r\n * Pauses a torrent.\r\n */\r\n pauseTorrent(infoHash: string): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n const interval = this.updateIntervals.get(infoHash);\r\n if (interval) {\r\n clearInterval(interval);\r\n this.updateIntervals.delete(infoHash);\r\n }\r\n\r\n torrent.status = 'paused';\r\n torrent.downloadSpeed = formatSpeed(0);\r\n torrent.uploadSpeed = formatSpeed(0);\r\n\r\n this.emit({ type: 'paused', torrent });\r\n }\r\n\r\n /**\r\n * Resumes a torrent.\r\n */\r\n resumeTorrent(infoHash: string): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent || torrent.status !== 'paused') {\r\n return;\r\n }\r\n\r\n torrent.status = torrent.progress >= 100 ? 'seeding' : 'downloading';\r\n this.emit({ type: 'resumed', torrent });\r\n this.simulateTorrentProgress(infoHash);\r\n }\r\n\r\n /**\r\n * Stops a torrent.\r\n */\r\n stopTorrent(infoHash: string): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n const interval = this.updateIntervals.get(infoHash);\r\n if (interval) {\r\n clearInterval(interval);\r\n this.updateIntervals.delete(infoHash);\r\n }\r\n\r\n torrent.status = 'stopped';\r\n torrent.downloadSpeed = formatSpeed(0);\r\n torrent.uploadSpeed = formatSpeed(0);\r\n }\r\n\r\n /**\r\n * Forces recheck of torrent.\r\n */\r\n recheckTorrent(infoHash: string): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n torrent.status = 'checking';\r\n // Simulate recheck\r\n setTimeout(() => {\r\n if (torrent.status === 'checking') {\r\n torrent.status = torrent.progress >= 100 ? 'seeding' : 'queued';\r\n }\r\n }, 2000);\r\n }\r\n\r\n /**\r\n * Force announces to trackers.\r\n */\r\n announceToTrackers(infoHash: string): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n for (const tracker of torrent.trackers) {\r\n tracker.status = 'updating';\r\n // Simulate tracker update\r\n setTimeout(\r\n () => {\r\n tracker.status = 'working';\r\n tracker.lastAnnounce = new Date();\r\n tracker.seeds = Math.floor(Math.random() * 100);\r\n tracker.leechers = Math.floor(Math.random() * 50);\r\n this.emit({ type: 'tracker-update', torrent, tracker });\r\n },\r\n 1000 + Math.random() * 2000,\r\n );\r\n }\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n File Selection\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Sets file priority/selection.\r\n */\r\n setFileSelection(infoHash: string, fileIndex: number, wanted: boolean): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n const file = torrent.files.find((f) => f.index === fileIndex);\r\n if (file) {\r\n file.wanted = wanted;\r\n file.priority = wanted ? 'normal' : 'skip';\r\n\r\n if (torrent.selectedFiles) {\r\n if (wanted && !torrent.selectedFiles.includes(fileIndex)) {\r\n torrent.selectedFiles.push(fileIndex);\r\n } else if (!wanted) {\r\n torrent.selectedFiles = torrent.selectedFiles.filter((i: number) => i !== fileIndex);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Sets priority for a file.\r\n */\r\n setFilePriority(\r\n infoHash: string,\r\n fileIndex: number,\r\n priority: 'skip' | 'low' | 'normal' | 'high',\r\n ): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n const file = torrent.files.find((f) => f.index === fileIndex);\r\n if (file) {\r\n file.priority = priority;\r\n file.wanted = priority !== 'skip';\r\n }\r\n }\r\n\r\n /**\r\n * Selects all files.\r\n */\r\n selectAllFiles(infoHash: string): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n for (const file of torrent.files) {\r\n file.wanted = true;\r\n file.priority = 'normal';\r\n }\r\n if (torrent.selectedFiles !== undefined) {\r\n torrent.selectedFiles = torrent.files.map((f) => f.index);\r\n }\r\n }\r\n\r\n /**\r\n * Deselects all files.\r\n */\r\n deselectAllFiles(infoHash: string): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n return;\r\n }\r\n\r\n for (const file of torrent.files) {\r\n file.wanted = false;\r\n file.priority = 'skip';\r\n }\r\n if (torrent.selectedFiles !== undefined) {\r\n torrent.selectedFiles = [];\r\n }\r\n }\r\n\r\n /**\r\n * Sets sequential download mode.\r\n */\r\n setSequentialDownload(infoHash: string, enabled: boolean): void {\r\n const torrent = this.torrents.get(infoHash);\r\n if (torrent) {\r\n torrent.sequentialDownload = enabled;\r\n }\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Configuration\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Gets client configuration.\r\n */\r\n getConfig(): TorrentClientConfig {\r\n return { ...this.config };\r\n }\r\n\r\n /**\r\n * Updates client configuration.\r\n */\r\n updateConfig(updates: Partial<TorrentClientConfig>): void {\r\n this.config = { ...this.config, ...updates };\r\n }\r\n\r\n /**\r\n * Sets download speed limit.\r\n */\r\n setDownloadLimit(bytesPerSecond: number | undefined): void {\r\n if (bytesPerSecond !== undefined) {\r\n this.config.bandwidthLimit = {\r\n ...this.config.bandwidthLimit,\r\n download: bytesPerSecond,\r\n enabled: true,\r\n };\r\n } else {\r\n this.config.bandwidthLimit = {\r\n ...this.config.bandwidthLimit,\r\n download: undefined,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Sets upload speed limit.\r\n */\r\n setUploadLimit(bytesPerSecond: number | undefined): void {\r\n if (bytesPerSecond !== undefined) {\r\n this.config.bandwidthLimit = {\r\n ...this.config.bandwidthLimit,\r\n upload: bytesPerSecond,\r\n enabled: true,\r\n };\r\n } else {\r\n this.config.bandwidthLimit = {\r\n ...this.config.bandwidthLimit,\r\n upload: undefined,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Enables or disables DHT.\r\n */\r\n setDHTEnabled(enabled: boolean): void {\r\n this.config.dhtEnabled = enabled;\r\n if (enabled) {\r\n this.initDHT();\r\n }\r\n }\r\n\r\n /**\r\n * Enables or disables PEX.\r\n */\r\n setPEXEnabled(enabled: boolean): void {\r\n this.config.pexEnabled = enabled;\r\n if (enabled) {\r\n this.initPEX();\r\n }\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Statistics\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Gets overall client statistics.\r\n */\r\n getStatistics(): TorrentDashboardStats {\r\n const torrents = this.getAllTorrents();\r\n\r\n let totalDownload = 0;\r\n let totalUpload = 0;\r\n let downloadSpeedSum = 0;\r\n let uploadSpeedSum = 0;\r\n let totalPeers = 0;\r\n\r\n for (const t of torrents) {\r\n totalDownload += t.downloadedBytes;\r\n totalUpload += t.uploadedBytes;\r\n downloadSpeedSum += t.downloadSpeed.bytesPerSecond;\r\n uploadSpeedSum += t.uploadSpeed.bytesPerSecond;\r\n totalPeers += t.peers;\r\n }\r\n\r\n return {\r\n activeSeeders: torrents.filter((t) => t.status === 'seeding').length,\r\n activeDownloads: torrents.filter((t) => t.status === 'downloading').length,\r\n totalDownloaded: totalDownload,\r\n totalUploaded: totalUpload,\r\n downloadSpeed: formatSpeed(downloadSpeedSum),\r\n uploadSpeed: formatSpeed(uploadSpeedSum),\r\n globalRatio: totalDownload > 0 ? totalUpload / totalDownload : 0,\r\n dhtNodes: this.config.dhtEnabled ? Math.floor(Math.random() * 500 + 100) : 0,\r\n totalPeers,\r\n sessionDuration: 0, // Would track actual session time\r\n };\r\n }\r\n\r\n /* ─────────────────────────────────────────────────────────────────────────────\r\n Private Methods\r\n ───────────────────────────────────────────────────────────────────────────── */\r\n\r\n /**\r\n * Gets default trackers.\r\n */\r\n private getDefaultTrackers(): string[] {\r\n return [\r\n 'udp://tracker.opentrackr.org:1337/announce',\r\n 'udp://tracker.openbittorrent.com:6969/announce',\r\n 'udp://open.stealth.si:80/announce',\r\n 'udp://tracker.torrent.eu.org:451/announce',\r\n ];\r\n }\r\n\r\n /**\r\n * Initializes DHT.\r\n */\r\n private initDHT(): void {\r\n console.log('DHT initialized');\r\n }\r\n\r\n /**\r\n * Initializes PEX.\r\n */\r\n private initPEX(): void {\r\n console.log('PEX initialized');\r\n }\r\n\r\n /**\r\n * Fetches torrent metadata from magnet.\r\n */\r\n private fetchMetadata(torrent: InternalTorrentState): void {\r\n // Simulate metadata fetch\r\n setTimeout(\r\n () => {\r\n if (torrent.status !== 'checking') {\r\n return;\r\n }\r\n\r\n // Create mock files\r\n torrent.files = [\r\n {\r\n index: 0,\r\n name: `${torrent.name}.mkv`,\r\n path: `${torrent.name}/${torrent.name}.mkv`,\r\n size: Math.floor(Math.random() * 2000000000) + 500000000, // 500MB - 2.5GB\r\n progress: 0,\r\n downloaded: 0,\r\n priority: 'normal',\r\n wanted: true,\r\n },\r\n {\r\n index: 1,\r\n name: 'sample.mp4',\r\n path: `${torrent.name}/sample.mp4`,\r\n size: Math.floor(Math.random() * 50000000) + 10000000, // 10-60MB\r\n progress: 0,\r\n downloaded: 0,\r\n priority: 'normal',\r\n wanted: true,\r\n },\r\n {\r\n index: 2,\r\n name: 'readme.txt',\r\n path: `${torrent.name}/readme.txt`,\r\n size: 1024,\r\n progress: 0,\r\n downloaded: 0,\r\n priority: 'low',\r\n wanted: true,\r\n },\r\n ];\r\n\r\n torrent.size = torrent.files.reduce((sum, f) => sum + f.size, 0);\r\n torrent.selectedFiles = torrent.files.map((f) => f.index);\r\n torrent.pieces = createPieceStatus(calculatePieces(torrent.size));\r\n torrent.status = 'downloading';\r\n\r\n this.emit({ type: 'metadata', torrent });\r\n this.emit({ type: 'started', torrent });\r\n },\r\n 2000 + Math.random() * 3000,\r\n );\r\n }\r\n\r\n /**\r\n * Simulates torrent progress for demo purposes.\r\n */\r\n private simulateTorrentProgress(infoHash: string): void {\r\n if (this.updateIntervals.has(infoHash)) {\r\n clearInterval(this.updateIntervals.get(infoHash)!);\r\n }\r\n\r\n const interval = setInterval(() => {\r\n const torrent = this.torrents.get(infoHash);\r\n if (!torrent) {\r\n clearInterval(interval);\r\n return;\r\n }\r\n\r\n if (torrent.status !== 'downloading' && torrent.status !== 'seeding') {\r\n return;\r\n }\r\n\r\n // Simulate download progress\r\n if (torrent.status === 'downloading' && torrent.size > 0) {\r\n const baseSpeed = 1000000 + Math.random() * 5000000; // 1-6 MB/s\r\n const downloadSpeed = this.config.bandwidthLimit.download\r\n ? Math.min(baseSpeed, this.config.bandwidthLimit.download)\r\n : baseSpeed;\r\n\r\n const increment = downloadSpeed * (1 + Math.random() * 0.5);\r\n torrent.downloadedBytes = Math.min(torrent.downloadedBytes + increment, torrent.size);\r\n torrent.progress = (torrent.downloadedBytes / torrent.size) * 100;\r\n torrent.downloadSpeed = formatSpeed(downloadSpeed);\r\n torrent.uploadSpeed = formatSpeed(downloadSpeed * 0.1 * Math.random());\r\n\r\n // Update file progress\r\n for (const file of torrent.files) {\r\n if (file.wanted) {\r\n file.downloaded = Math.min(\r\n file.downloaded + increment * (file.size / torrent.size),\r\n file.size,\r\n );\r\n file.progress = (file.downloaded / file.size) * 100;\r\n }\r\n }\r\n\r\n // Simulate peers\r\n torrent.peers = Math.floor(Math.random() * 30) + 5;\r\n torrent.seeds = Math.floor(torrent.peers * 0.6);\r\n\r\n // Calculate ETA\r\n torrent.eta = calculateETA(torrent.size - torrent.downloadedBytes, downloadSpeed);\r\n\r\n this.emit({ type: 'progress', torrent });\r\n\r\n // Check if complete\r\n if (torrent.progress >= 100) {\r\n torrent.status = 'seeding';\r\n torrent.completedDate = new Date();\r\n torrent.progress = 100;\r\n torrent.downloadedBytes = torrent.size;\r\n this.emit({ type: 'completed', torrent });\r\n this.emit({ type: 'seeding', torrent });\r\n }\r\n }\r\n\r\n // Simulate seeding\r\n if (torrent.status === 'seeding') {\r\n const uploadSpeed = 500000 + Math.random() * 2000000; // 0.5-2.5 MB/s\r\n torrent.uploadedBytes += uploadSpeed;\r\n torrent.uploadSpeed = formatSpeed(uploadSpeed);\r\n torrent.downloadSpeed = formatSpeed(0);\r\n torrent.ratio = torrent.size > 0 ? torrent.uploadedBytes / torrent.size : 0;\r\n\r\n torrent.peers = Math.floor(Math.random() * 10) + 1;\r\n torrent.seeds = 0;\r\n }\r\n }, 1000);\r\n\r\n this.updateIntervals.set(infoHash, interval);\r\n }\r\n\r\n /**\r\n * Disposes the client.\r\n */\r\n dispose(): void {\r\n for (const interval of this.updateIntervals.values()) {\r\n clearInterval(interval);\r\n }\r\n this.updateIntervals.clear();\r\n this.torrents.clear();\r\n this.eventListeners.clear();\r\n }\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Torrent Creator\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\nexport interface CreateTorrentOptions {\r\n name: string;\r\n files: File[];\r\n trackers?: string[];\r\n comment?: string;\r\n isPrivate?: boolean;\r\n pieceSize?: number;\r\n webSeeds?: string[];\r\n source?: string;\r\n}\r\n\r\n/**\r\n * Creates a .torrent file (bencode output).\r\n *\r\n * Note: This is a simplified implementation. A full implementation would\r\n * use the bencode library and calculate proper piece hashes.\r\n */\r\nexport async function createTorrent(options: CreateTorrentOptions): Promise<CreatedTorrent> {\r\n const {\r\n name,\r\n files,\r\n trackers = [],\r\n comment,\r\n isPrivate = false,\r\n pieceSize = 262144,\r\n webSeeds = [],\r\n } = options;\r\n\r\n // Calculate total size\r\n const totalSize = files.reduce((sum, f) => sum + f.size, 0);\r\n\r\n // Generate mock info hash\r\n const infoHash = generateInfoHash();\r\n const pieceCount = calculatePieces(totalSize, pieceSize);\r\n\r\n // Create magnet URI\r\n const magnetLink = createMagnetUri({ infoHash, name, trackers, size: totalSize });\r\n\r\n // In a real implementation, we would bencode the torrent dict\r\n // For now, return a placeholder Uint8Array\r\n const encoder = new TextEncoder();\r\n const torrentFile = encoder.encode(\r\n JSON.stringify({\r\n announce: trackers[0] || '',\r\n info: {\r\n name,\r\n 'piece length': pieceSize,\r\n length: totalSize,\r\n private: isPrivate ? 1 : 0,\r\n },\r\n comment,\r\n 'url-list': webSeeds,\r\n }),\r\n );\r\n\r\n return {\r\n infoHash,\r\n magnetLink,\r\n torrentFile,\r\n size: totalSize,\r\n pieceCount,\r\n pieceSize,\r\n };\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n Singleton Instance\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\nlet torrentClientInstance: TorrentClient | null = null;\r\n\r\n/**\r\n * Gets or creates the torrent client singleton.\r\n */\r\nexport function getTorrentClient(config?: Partial<TorrentClientConfig>): TorrentClient {\r\n if (!torrentClientInstance) {\r\n torrentClientInstance = new TorrentClient(config);\r\n }\r\n return torrentClientInstance;\r\n}\r\n\r\n/**\r\n * Disposes the torrent client singleton.\r\n */\r\nexport function disposeTorrentClient(): void {\r\n torrentClientInstance?.dispose();\r\n torrentClientInstance = null;\r\n}\r\n\r\n/* ══════════════════════════════════════════════════════════════════════════════\r\n React Hook\r\n ══════════════════════════════════════════════════════════════════════════════ */\r\n\r\nimport { useState, useEffect, useCallback, useMemo } from 'react';\r\n\r\nexport interface UseTorrentClientOptions {\r\n config?: Partial<TorrentClientConfig>;\r\n autoRefresh?: boolean;\r\n refreshInterval?: number;\r\n}\r\n\r\nexport interface UseTorrentClientReturn {\r\n /** All torrents */\r\n torrents: Torrent[];\r\n /** Client statistics */\r\n statistics: TorrentDashboardStats;\r\n /** Active torrents */\r\n activeTorrents: Torrent[];\r\n /** Add magnet */\r\n addMagnet: (uri: string, options?: Parameters<TorrentClient['addMagnet']>[1]) => Torrent | null;\r\n /** Add torrent file */\r\n addTorrentFile: (\r\n data: ArrayBuffer,\r\n options?: Parameters<TorrentClient['addTorrentFile']>[1],\r\n ) => Torrent | null;\r\n /** Remove torrent */\r\n removeTorrent: (infoHash: string, deleteData?: boolean) => void;\r\n /** Start torrent */\r\n startTorrent: (infoHash: string) => void;\r\n /** Pause torrent */\r\n pauseTorrent: (infoHash: string) => void;\r\n /** Resume torrent */\r\n resumeTorrent: (infoHash: string) => void;\r\n /** Stop torrent */\r\n stopTorrent: (infoHash: string) => void;\r\n /** Set file selection */\r\n setFileSelection: (infoHash: string, fileIndex: number, wanted: boolean) => void;\r\n /** Set sequential download */\r\n setSequentialDownload: (infoHash: string, enabled: boolean) => void;\r\n /** Set download limit */\r\n setDownloadLimit: (bytesPerSecond: number | undefined) => void;\r\n /** Set upload limit */\r\n setUploadLimit: (bytesPerSecond: number | undefined) => void;\r\n /** Create torrent */\r\n createTorrent: typeof createTorrent;\r\n}\r\n\r\n/**\r\n * React hook for torrent client.\r\n */\r\nexport function useTorrentClient(options: UseTorrentClientOptions = {}): UseTorrentClientReturn {\r\n const { config, autoRefresh = true, refreshInterval = 1000 } = options;\r\n\r\n const client = useMemo(() => getTorrentClient(config), [config]);\r\n\r\n const [torrents, setTorrents] = useState<Torrent[]>(client.getAllTorrents());\r\n const [statistics, setStatistics] = useState<TorrentDashboardStats>(client.getStatistics());\r\n\r\n useEffect(() => {\r\n const handleUpdate = () => {\r\n setTorrents([...client.getAllTorrents()]);\r\n setStatistics(client.getStatistics());\r\n };\r\n\r\n const unsubscribers = [\r\n client.on('added', handleUpdate),\r\n client.on('metadata', handleUpdate),\r\n client.on('started', handleUpdate),\r\n client.on('progress', handleUpdate),\r\n client.on('paused', handleUpdate),\r\n client.on('resumed', handleUpdate),\r\n client.on('completed', handleUpdate),\r\n client.on('seeding', handleUpdate),\r\n client.on('failed', handleUpdate),\r\n client.on('removed', handleUpdate),\r\n ];\r\n\r\n // Auto-refresh\r\n let interval: ReturnType<typeof setInterval> | undefined;\r\n if (autoRefresh) {\r\n interval = setInterval(() => {\r\n if (\r\n client.getStatistics().activeDownloads > 0 ||\r\n client.getStatistics().activeSeeders > 0\r\n ) {\r\n handleUpdate();\r\n }\r\n }, refreshInterval);\r\n }\r\n\r\n return () => {\r\n unsubscribers.forEach((unsub) => unsub());\r\n if (interval) {\r\n clearInterval(interval);\r\n }\r\n };\r\n }, [client, autoRefresh, refreshInterval]);\r\n\r\n const activeTorrents = useMemo(\r\n () => torrents.filter((t) => t.status === 'downloading' || t.status === 'seeding'),\r\n [torrents],\r\n );\r\n\r\n return {\r\n torrents,\r\n statistics,\r\n activeTorrents,\r\n addMagnet: useCallback((uri, opts) => client.addMagnet(uri, opts), [client]),\r\n addTorrentFile: useCallback((data, opts) => client.addTorrentFile(data, opts), [client]),\r\n removeTorrent: useCallback((hash, del) => client.removeTorrent(hash, del), [client]),\r\n startTorrent: useCallback((hash) => client.startTorrent(hash), [client]),\r\n pauseTorrent: useCallback((hash) => client.pauseTorrent(hash), [client]),\r\n resumeTorrent: useCallback((hash) => client.resumeTorrent(hash), [client]),\r\n stopTorrent: useCallback((hash) => client.stopTorrent(hash), [client]),\r\n setFileSelection: useCallback(\r\n (hash, idx, w) => client.setFileSelection(hash, idx, w),\r\n [client],\r\n ),\r\n setSequentialDownload: useCallback(\r\n (hash, en) => client.setSequentialDownload(hash, en),\r\n [client],\r\n ),\r\n setDownloadLimit: useCallback((lim) => client.setDownloadLimit(lim), [client]),\r\n setUploadLimit: useCallback((lim) => client.setUploadLimit(lim), [client]),\r\n createTorrent,\r\n };\r\n}\r\n","/**\r\n * @fileoverview SEC-008: Traceless™ — Zero-Trace Privacy Architecture\r\n *\r\n * \"Your ERP. Zero traces. No cookie banners. Ever.\"\r\n *\r\n * This module provides TypeScript types and interfaces for the Traceless™\r\n * privacy architecture - a flagship feature that allows enterprise applications\r\n * to operate with zero client-side storage when required.\r\n *\r\n * @module @nice2dev/ui-tools/traceless\r\n */\r\n\r\n// =============================================================================\r\n// PRIVACY MODES\r\n// =============================================================================\r\n\r\n/**\r\n * Privacy mode levels from most restrictive to least restrictive.\r\n *\r\n * - `traceless`: Zero client-side storage. In-memory only. Full privacy.\r\n * - `ephemeral`: sessionStorage only. Cleared on tab close.\r\n * - `private`: sessionStorage + 1 httpOnly auth cookie.\r\n * - `balanced`: sessionStorage + localStorage. No cookies.\r\n * - `full`: All storage types including cookies. Requires consent banner.\r\n * - `custom`: Manually configured storage permissions.\r\n */\r\nexport type TracelessMode = 'traceless' | 'ephemeral' | 'private' | 'balanced' | 'full' | 'custom';\r\n\r\n/**\r\n * Storage capability flags for granular control.\r\n */\r\nexport interface StorageCapabilities {\r\n /** Whether cookies are allowed */\r\n cookiesAllowed: boolean;\r\n /** Whether localStorage is allowed */\r\n localStorageAllowed: boolean;\r\n /** Whether sessionStorage is allowed */\r\n sessionStorageAllowed: boolean;\r\n /** Whether IndexedDB is allowed */\r\n indexedDBAllowed?: boolean;\r\n /** Whether Web SQL is allowed (deprecated but still used) */\r\n webSQLAllowed?: boolean;\r\n /** Whether Service Workers can cache data */\r\n serviceWorkerCacheAllowed?: boolean;\r\n}\r\n\r\n/**\r\n * Main Traceless Policy interface - injected per-request.\r\n */\r\nexport interface ITracelessPolicy extends StorageCapabilities {\r\n /** Effective mode after resolution */\r\n effectiveMode: TracelessMode;\r\n /** Whether consent banner is required */\r\n consentRequired: boolean;\r\n /** Whether any form of persistence is allowed */\r\n canPersist: boolean;\r\n /** Source of the policy (instance, tenant, group, user) */\r\n policySource: PolicySource;\r\n /** Timestamp when policy was resolved */\r\n resolvedAt: string;\r\n /** Cache TTL in seconds */\r\n cacheTTL?: number;\r\n}\r\n\r\n/**\r\n * Source of the privacy policy in the hierarchy.\r\n */\r\nexport type PolicySource = 'instance' | 'tenant' | 'group' | 'user' | 'module' | 'computed';\r\n\r\n// =============================================================================\r\n// POLICY HIERARCHY\r\n// =============================================================================\r\n\r\n/**\r\n * Instance-level ceiling - the maximum permissions any tenant can have.\r\n */\r\nexport interface InstanceStorageCeiling {\r\n /** Maximum cookies permission for the instance */\r\n maxCookies: boolean;\r\n /** Maximum localStorage permission for the instance */\r\n maxLocalStorage: boolean;\r\n /** Maximum sessionStorage permission for the instance */\r\n maxSessionStorage: boolean;\r\n /** Maximum IndexedDB permission */\r\n maxIndexedDB?: boolean;\r\n /** Description of why ceiling is set this way */\r\n reason?: string;\r\n /** Who set this ceiling */\r\n configuredBy?: string;\r\n /** When ceiling was last modified */\r\n lastModified?: string;\r\n}\r\n\r\n/**\r\n * Tenant-level policy configuration.\r\n */\r\nexport interface TenantStoragePolicy {\r\n /** Tenant identifier */\r\n tenantId: string;\r\n /** Tenant's chosen privacy mode (must be <= instance ceiling) */\r\n mode: TracelessMode;\r\n /** Override for cookies (cannot exceed instance ceiling) */\r\n cookiesAllowed?: boolean;\r\n /** Override for localStorage (cannot exceed instance ceiling) */\r\n localStorageAllowed?: boolean;\r\n /** Override for sessionStorage (cannot exceed instance ceiling) */\r\n sessionStorageAllowed?: boolean;\r\n /** Default mode for new users */\r\n defaultUserMode?: TracelessMode;\r\n /** Whether users can adjust their privacy level */\r\n userAdjustmentAllowed: boolean;\r\n /** Minimum mode users must have (cannot go more permissive) */\r\n minimumUserMode?: TracelessMode;\r\n}\r\n\r\n/**\r\n * User group policy configuration.\r\n */\r\nexport interface GroupStoragePolicy {\r\n /** Group identifier */\r\n groupId: string;\r\n /** Group name for display */\r\n groupName: string;\r\n /** Privacy mode for this group */\r\n mode: TracelessMode;\r\n /** Custom storage capabilities for the group */\r\n capabilities?: Partial<StorageCapabilities>;\r\n /** Whether users in this group can adjust their level */\r\n userAdjustmentAllowed: boolean;\r\n /** Priority when user belongs to multiple groups */\r\n priority: number;\r\n}\r\n\r\n/**\r\n * User-level privacy preferences (self-lockdown).\r\n */\r\nexport interface UserPrivacyPreferences {\r\n /** User identifier */\r\n userId: string;\r\n /** User's chosen mode (can only be more restrictive than group) */\r\n mode: TracelessMode;\r\n /** Custom restrictions */\r\n restrictions?: Partial<StorageCapabilities>;\r\n /** When user last modified their preferences */\r\n lastModified: string;\r\n /** Device-specific overrides */\r\n deviceOverrides?: Record<string, TracelessMode>;\r\n}\r\n\r\n/**\r\n * Module minimum storage requirements.\r\n */\r\nexport interface ModuleStorageRequirement {\r\n /** Module identifier */\r\n moduleId: string;\r\n /** Module name */\r\n moduleName: string;\r\n /** Minimum storage needed for basic functionality */\r\n minStorageRequirement: Partial<StorageCapabilities>;\r\n /** Features that degrade gracefully without storage */\r\n degradableFeatures: DegradableFeature[];\r\n /** Features that are completely disabled without storage */\r\n disabledFeatures: string[];\r\n /** Warning message when storage is insufficient */\r\n insufficientStorageWarning?: string;\r\n}\r\n\r\n/**\r\n * A feature that can work with reduced functionality.\r\n */\r\nexport interface DegradableFeature {\r\n /** Feature identifier */\r\n featureId: string;\r\n /** Feature name */\r\n name: string;\r\n /** Description of full functionality */\r\n fullDescription: string;\r\n /** Description of degraded functionality */\r\n degradedDescription: string;\r\n /** What storage is needed for full functionality */\r\n requiredStorage: Partial<StorageCapabilities>;\r\n /** Impact level when degraded */\r\n degradedImpact: 'minor' | 'moderate' | 'significant';\r\n}\r\n\r\n// =============================================================================\r\n// POLICY RESOLUTION\r\n// =============================================================================\r\n\r\n/**\r\n * Policy resolution request.\r\n */\r\nexport interface PolicyResolutionRequest {\r\n /** Tenant context */\r\n tenantId?: string;\r\n /** User context */\r\n userId?: string;\r\n /** Device identifier for device-specific policies */\r\n deviceId?: string;\r\n /** Module requesting the policy */\r\n moduleId?: string;\r\n /** Whether to include detailed resolution trace */\r\n includeTrace?: boolean;\r\n}\r\n\r\n/**\r\n * Policy resolution response with computed policy.\r\n */\r\nexport interface PolicyResolutionResponse {\r\n /** The computed effective policy */\r\n policy: ITracelessPolicy;\r\n /** Resolution trace showing how policy was computed */\r\n trace?: PolicyResolutionTrace;\r\n /** Warnings about capability limitations */\r\n warnings?: PolicyWarning[];\r\n /** Cache key for this resolution */\r\n cacheKey?: string;\r\n}\r\n\r\n/**\r\n * Trace of how policy was resolved through the hierarchy.\r\n */\r\nexport interface PolicyResolutionTrace {\r\n /** Instance ceiling that was applied */\r\n instanceCeiling: InstanceStorageCeiling;\r\n /** Tenant policy that was applied */\r\n tenantPolicy?: TenantStoragePolicy;\r\n /** Group policies that were considered (in priority order) */\r\n groupPolicies?: GroupStoragePolicy[];\r\n /** User preferences that were applied */\r\n userPreferences?: UserPrivacyPreferences;\r\n /** Module requirements that were checked */\r\n moduleRequirements?: ModuleStorageRequirement[];\r\n /** Final computed result */\r\n computedResult: ITracelessPolicy;\r\n /** Resolution timestamp */\r\n resolvedAt: string;\r\n}\r\n\r\n/**\r\n * Warning about policy limitations.\r\n */\r\nexport interface PolicyWarning {\r\n /** Warning code */\r\n code: string;\r\n /** Warning message */\r\n message: string;\r\n /** Severity of the warning */\r\n severity: 'info' | 'warning' | 'error';\r\n /** Affected module or feature */\r\n affectedModule?: string;\r\n /** Suggestion for resolution */\r\n suggestion?: string;\r\n}\r\n\r\n// =============================================================================\r\n// STORAGE ADAPTER\r\n// =============================================================================\r\n\r\n/**\r\n * Storage backend types.\r\n */\r\nexport type StorageBackend = 'memory' | 'sessionStorage' | 'localStorage' | 'indexedDB' | 'cookie';\r\n\r\n/**\r\n * Unified Storage Adapter interface for all platforms.\r\n */\r\nexport interface IStorageAdapter {\r\n /** Get a value by key */\r\n get<T = unknown>(key: string): T | null;\r\n /** Get a value asynchronously (for IndexedDB) */\r\n getAsync<T = unknown>(key: string): Promise<T | null>;\r\n /** Set a value */\r\n set<T = unknown>(key: string, value: T): void;\r\n /** Set a value asynchronously */\r\n setAsync<T = unknown>(key: string, value: T): Promise<void>;\r\n /** Remove a value */\r\n remove(key: string): void;\r\n /** Remove a value asynchronously */\r\n removeAsync(key: string): Promise<void>;\r\n /** Clear all values (within namespace) */\r\n clear(): void;\r\n /** Clear all values asynchronously */\r\n clearAsync(): Promise<void>;\r\n /** Check if a key exists */\r\n has(key: string): boolean;\r\n /** Get all keys (within namespace) */\r\n keys(): string[];\r\n /** Get the current storage backend being used */\r\n getCurrentBackend(): StorageBackend;\r\n /** Check if storage is available */\r\n isAvailable(): boolean;\r\n}\r\n\r\n/**\r\n * Storage adapter configuration.\r\n */\r\nexport interface StorageAdapterConfig {\r\n /** Namespace prefix for all keys */\r\n namespace: string;\r\n /** Policy to respect */\r\n policy: ITracelessPolicy;\r\n /** Preferred backend (will fallback if not available) */\r\n preferredBackend?: StorageBackend;\r\n /** Whether to encrypt values */\r\n encrypt?: boolean;\r\n /** Encryption key (required if encrypt is true) */\r\n encryptionKey?: string;\r\n /** Default TTL for values in seconds */\r\n defaultTTL?: number;\r\n /** Event handlers */\r\n onStorageUnavailable?: (requestedBackend: StorageBackend) => void;\r\n onValueExpired?: (key: string) => void;\r\n onPolicyViolation?: (operation: string, requestedBackend: StorageBackend) => void;\r\n}\r\n\r\n/**\r\n * Storage item with metadata.\r\n */\r\nexport interface StorageItem<T = unknown> {\r\n /** The stored value */\r\n value: T;\r\n /** When the item was created */\r\n createdAt: string;\r\n /** When the item was last accessed */\r\n lastAccessedAt?: string;\r\n /** When the item expires (if applicable) */\r\n expiresAt?: string;\r\n /** Which backend is storing this item */\r\n backend: StorageBackend;\r\n /** Whether the item is encrypted */\r\n encrypted: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// REACT INTEGRATION\r\n// =============================================================================\r\n\r\n/**\r\n * React hook return type for useTracelessPolicy.\r\n */\r\nexport interface UseTracelessPolicyResult extends ITracelessPolicy {\r\n /** Whether policy is still loading */\r\n isLoading: boolean;\r\n /** Error if policy couldn't be loaded */\r\n error: Error | null;\r\n /** Refresh the policy */\r\n refresh: () => Promise<void>;\r\n /** Check if a specific operation is allowed */\r\n isAllowed: (operation: StorageOperation) => boolean;\r\n}\r\n\r\n/**\r\n * Storage operations that can be checked.\r\n */\r\nexport type StorageOperation =\r\n | 'setCookie'\r\n | 'readCookie'\r\n | 'setLocalStorage'\r\n | 'readLocalStorage'\r\n | 'setSessionStorage'\r\n | 'readSessionStorage'\r\n | 'useIndexedDB'\r\n | 'useServiceWorker';\r\n\r\n/**\r\n * Props for traceless-aware components.\r\n */\r\nexport interface TracelessAwareProps {\r\n /** Whether this component can use cookies */\r\n cookies?: boolean;\r\n /** Whether this component can use localStorage */\r\n localStorage?: boolean;\r\n /** Storage mode override */\r\n storageMode?: 'traceless' | 'ephemeral' | 'persistent' | 'auto';\r\n}\r\n\r\n/**\r\n * Context value for TracelessProvider.\r\n */\r\nexport interface TracelessContextValue {\r\n /** Current policy */\r\n policy: ITracelessPolicy;\r\n /** Storage adapter instance */\r\n storageAdapter: IStorageAdapter;\r\n /** Update user preferences */\r\n updatePreferences: (prefs: Partial<UserPrivacyPreferences>) => Promise<void>;\r\n /** Check if mode change is allowed */\r\n canChangeTo: (mode: TracelessMode) => boolean;\r\n}\r\n\r\n// =============================================================================\r\n// FLUTTER INTEGRATION\r\n// =============================================================================\r\n\r\n/**\r\n * Flutter storage adapter configuration.\r\n */\r\nexport interface FlutterStorageAdapterConfig {\r\n /** Namespace for SharedPreferences keys */\r\n namespace: string;\r\n /** Policy to respect */\r\n policy: ITracelessPolicy;\r\n /** Use flutter_secure_storage for sensitive data */\r\n useSecureStorage: boolean;\r\n /** Use Hive for complex data structures */\r\n useHive: boolean;\r\n /** Hive box name */\r\n hiveBoxName?: string;\r\n}\r\n\r\n// =============================================================================\r\n// COMPONENT-SPECIFIC STORAGE\r\n// =============================================================================\r\n\r\n/**\r\n * Storage scope for different component types.\r\n */\r\nexport interface ComponentStorageScope {\r\n /** Component type identifier */\r\n componentType: string;\r\n /** What data this component wants to store */\r\n dataCategories: ComponentDataCategory[];\r\n /** Required storage for basic functionality */\r\n requiredStorage: Partial<StorageCapabilities>;\r\n /** Behavior when storage is restricted */\r\n restrictedBehavior: RestrictedBehavior;\r\n}\r\n\r\n/**\r\n * Categories of data components might store.\r\n */\r\nexport type ComponentDataCategory =\r\n | 'layout' // Column widths, panel sizes\r\n | 'filters' // Filter states, search terms\r\n | 'sorting' // Sort column and direction\r\n | 'selection' // Selected items\r\n | 'view' // Current view mode\r\n | 'draft' // Unsaved content\r\n | 'preferences' // User preferences\r\n | 'history' // Action history\r\n | 'cache' // Performance cache\r\n | 'session' // Session state\r\n | 'auth'; // Authentication data\r\n\r\n/**\r\n * How component behaves when storage is restricted.\r\n */\r\nexport interface RestrictedBehavior {\r\n /** Behavior in traceless mode */\r\n traceless: GracefulDegradation;\r\n /** Behavior in ephemeral mode */\r\n ephemeral: GracefulDegradation;\r\n /** Behavior in private mode */\r\n private: GracefulDegradation;\r\n}\r\n\r\n/**\r\n * Graceful degradation configuration.\r\n */\r\nexport interface GracefulDegradation {\r\n /** What features work */\r\n availableFeatures: string[];\r\n /** What features are disabled */\r\n disabledFeatures: string[];\r\n /** Warning message to show user */\r\n userWarning?: string;\r\n /** Default values to use */\r\n defaults: Record<string, unknown>;\r\n}\r\n\r\n// =============================================================================\r\n// SPECIFIC COMPONENT CONFIGS\r\n// =============================================================================\r\n\r\n/**\r\n * NiceDataGrid storage config.\r\n */\r\nexport interface DataGridStorageConfig extends TracelessAwareProps {\r\n /** What to store */\r\n persist?: {\r\n columnOrder?: boolean;\r\n columnWidths?: boolean;\r\n sortState?: boolean;\r\n filterState?: boolean;\r\n pageSize?: boolean;\r\n hiddenColumns?: boolean;\r\n };\r\n /** Storage key for this grid instance */\r\n storageKey?: string;\r\n}\r\n\r\n/**\r\n * NiceKanban storage config.\r\n */\r\nexport interface KanbanStorageConfig extends TracelessAwareProps {\r\n /** What to store */\r\n persist?: {\r\n collapsedColumns?: boolean;\r\n swimlaneState?: boolean;\r\n filterState?: boolean;\r\n scrollPosition?: boolean;\r\n };\r\n /** Storage key for this board instance */\r\n storageKey?: string;\r\n}\r\n\r\n/**\r\n * NiceRichTextEditor storage config.\r\n */\r\nexport interface RichTextEditorStorageConfig extends TracelessAwareProps {\r\n /** Auto-save draft configuration */\r\n autosave?: {\r\n enabled: boolean;\r\n intervalMs: number;\r\n maxDrafts: number;\r\n };\r\n /** Storage key for drafts */\r\n draftKey?: string;\r\n /** Warning when draft might be lost */\r\n showDraftLossWarning?: boolean;\r\n}\r\n\r\n/**\r\n * NiceCalendar storage config.\r\n */\r\nexport interface CalendarStorageConfig extends TracelessAwareProps {\r\n /** What to store */\r\n persist?: {\r\n viewMode?: boolean;\r\n selectedDate?: boolean;\r\n timezone?: boolean;\r\n hiddenCalendars?: boolean;\r\n };\r\n /** Fall back to these defaults when no storage */\r\n defaults?: {\r\n viewMode?: 'day' | 'week' | 'month' | 'year';\r\n showWeekends?: boolean;\r\n };\r\n}\r\n\r\n/**\r\n * NiceLoginForm storage config.\r\n */\r\nexport interface LoginFormStorageConfig extends TracelessAwareProps {\r\n /** Whether \"Remember me\" option is shown */\r\n showRememberMe?: boolean;\r\n /** Whether to remember username */\r\n rememberUsername?: boolean;\r\n /** Cookie expiration for \"Remember me\" in days */\r\n rememberMeDays?: number;\r\n}\r\n\r\n// =============================================================================\r\n// CONSENT MANAGEMENT\r\n// =============================================================================\r\n\r\n/**\r\n * Consent state for cookie/storage usage.\r\n */\r\nexport interface ConsentState {\r\n /** Whether any consent has been given */\r\n hasConsent: boolean;\r\n /** Consent version (for managing consent changes) */\r\n consentVersion: string;\r\n /** When consent was last updated */\r\n consentUpdatedAt: string;\r\n /** Granular consent choices */\r\n choices: ConsentChoices;\r\n}\r\n\r\n/**\r\n * Granular consent choices.\r\n */\r\nexport interface ConsentChoices {\r\n /** Strictly necessary (cannot be disabled) */\r\n necessary: true;\r\n /** Functional cookies */\r\n functional?: boolean;\r\n /** Analytics cookies */\r\n analytics?: boolean;\r\n /** Marketing/targeting cookies */\r\n marketing?: boolean;\r\n /** Third-party cookies */\r\n thirdParty?: boolean;\r\n /** Custom consent categories */\r\n custom?: Record<string, boolean>;\r\n}\r\n\r\n/**\r\n * Consent panel configuration.\r\n */\r\nexport interface ConsentPanelConfig {\r\n /** Privacy mode determines if panel is shown */\r\n policyMode: TracelessMode;\r\n /** Available consent categories */\r\n categories: ConsentCategory[];\r\n /** Privacy policy URL */\r\n privacyPolicyUrl?: string;\r\n /** Cookie policy URL */\r\n cookiePolicyUrl?: string;\r\n /** Position of the banner */\r\n position?: 'top' | 'bottom' | 'center';\r\n /** Theme */\r\n theme?: 'light' | 'dark' | 'auto';\r\n /** Text customization */\r\n text?: ConsentPanelText;\r\n}\r\n\r\n/**\r\n * Consent category definition.\r\n */\r\nexport interface ConsentCategory {\r\n /** Category identifier */\r\n id: string;\r\n /** Display name */\r\n name: string;\r\n /** Description */\r\n description: string;\r\n /** Whether category is required */\r\n required: boolean;\r\n /** Default state if not required */\r\n defaultEnabled?: boolean;\r\n /** Cookies/storage used by this category */\r\n items?: ConsentItem[];\r\n}\r\n\r\n/**\r\n * Individual consent item (cookie or storage key).\r\n */\r\nexport interface ConsentItem {\r\n /** Item name */\r\n name: string;\r\n /** Provider/domain */\r\n provider: string;\r\n /** Purpose */\r\n purpose: string;\r\n /** Expiry */\r\n expiry?: string;\r\n /** Type */\r\n type: 'cookie' | 'localStorage' | 'sessionStorage' | 'indexedDB';\r\n}\r\n\r\n/**\r\n * Text customization for consent panel.\r\n */\r\nexport interface ConsentPanelText {\r\n /** Banner title */\r\n title?: string;\r\n /** Banner description */\r\n description?: string;\r\n /** Accept all button */\r\n acceptAll?: string;\r\n /** Reject all button */\r\n rejectAll?: string;\r\n /** Customize button */\r\n customize?: string;\r\n /** Save preferences button */\r\n savePreferences?: string;\r\n}\r\n\r\n// =============================================================================\r\n// AUDIT & COMPLIANCE\r\n// =============================================================================\r\n\r\n/**\r\n * Privacy policy change audit entry.\r\n */\r\nexport interface PolicyAuditEntry {\r\n /** Entry ID */\r\n id: string;\r\n /** Timestamp */\r\n timestamp: string;\r\n /** Who made the change */\r\n changedBy: string;\r\n /** What changed */\r\n changeType: PolicyChangeType;\r\n /** Previous mode */\r\n previousMode?: TracelessMode;\r\n /** New mode */\r\n newMode?: TracelessMode;\r\n /** Previous capabilities */\r\n previousCapabilities?: Partial<StorageCapabilities>;\r\n /** New capabilities */\r\n newCapabilities?: Partial<StorageCapabilities>;\r\n /** Reason for change */\r\n reason?: string;\r\n /** IP address */\r\n ipAddress?: string;\r\n /** User agent */\r\n userAgent?: string;\r\n /** Additional metadata */\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Types of policy changes.\r\n */\r\nexport type PolicyChangeType =\r\n | 'mode_change'\r\n | 'capability_change'\r\n | 'user_lockdown'\r\n | 'admin_override'\r\n | 'tenant_policy_update'\r\n | 'instance_ceiling_update'\r\n | 'group_policy_update';\r\n\r\n/**\r\n * Compliance report for Traceless mode.\r\n */\r\nexport interface TracelessComplianceReport {\r\n /** Report ID */\r\n reportId: string;\r\n /** Generated timestamp */\r\n generatedAt: string;\r\n /** Instance identifier */\r\n instanceId: string;\r\n /** Tenant identifier */\r\n tenantId?: string;\r\n /** Current mode */\r\n mode: TracelessMode;\r\n /** Storage capabilities summary */\r\n storageCapabilities: StorageCapabilities;\r\n /** Cookie count (should be 0 in traceless) */\r\n cookieCount: number;\r\n /** localStorage keys count */\r\n localStorageKeys: number;\r\n /** sessionStorage keys count */\r\n sessionStorageKeys: number;\r\n /** Whether consent banner is required */\r\n consentBannerRequired: boolean;\r\n /** Compliance statements */\r\n complianceStatements: ComplianceStatement[];\r\n /** Legal disclaimer */\r\n legalDisclaimer: string;\r\n}\r\n\r\n/**\r\n * Compliance statement for regulations.\r\n */\r\nexport interface ComplianceStatement {\r\n /** Regulation name */\r\n regulation: string;\r\n /** Relevant article/section */\r\n article?: string;\r\n /** Compliance status */\r\n status: 'compliant' | 'exempt' | 'requires_review';\r\n /** Explanation */\r\n explanation: string;\r\n}\r\n\r\n// =============================================================================\r\n// PRIVACY API ENDPOINTS\r\n// =============================================================================\r\n\r\n/**\r\n * Privacy API endpoint definitions.\r\n */\r\nexport interface PrivacyAPI {\r\n /** Get effective policy */\r\n getPolicy: () => Promise<ITracelessPolicy>;\r\n /** Update user preferences */\r\n updatePolicy: (prefs: Partial<UserPrivacyPreferences>) => Promise<ITracelessPolicy>;\r\n /** Get capabilities for current mode */\r\n getCapabilities: () => Promise<StorageCapabilities>;\r\n /** Get audit log */\r\n getAuditLog: (params: AuditLogParams) => Promise<PolicyAuditEntry[]>;\r\n /** Generate compliance report */\r\n generateComplianceReport: () => Promise<TracelessComplianceReport>;\r\n}\r\n\r\n/**\r\n * Audit log query parameters.\r\n */\r\nexport interface AuditLogParams {\r\n /** Start date */\r\n from?: string;\r\n /** End date */\r\n to?: string;\r\n /** Filter by user */\r\n userId?: string;\r\n /** Filter by change type */\r\n changeType?: PolicyChangeType;\r\n /** Page number */\r\n page?: number;\r\n /** Page size */\r\n pageSize?: number;\r\n}\r\n\r\n// =============================================================================\r\n// TESTING & SCANNING\r\n// =============================================================================\r\n\r\n/**\r\n * Storage scanner configuration for CI/CD.\r\n */\r\nexport interface StorageScannerConfig {\r\n /** Base URL to scan */\r\n baseUrl: string;\r\n /** Pages to visit */\r\n pages: string[];\r\n /** Expected mode */\r\n expectedMode: TracelessMode;\r\n /** Whether to fail on any cookie */\r\n failOnCookie: boolean;\r\n /** Whether to fail on any localStorage */\r\n failOnLocalStorage: boolean;\r\n /** Whether to fail on any sessionStorage */\r\n failOnSessionStorage: boolean;\r\n /** Timeout per page in ms */\r\n pageTimeout: number;\r\n /** Output format */\r\n outputFormat: 'json' | 'junit' | 'console';\r\n}\r\n\r\n/**\r\n * Storage scan result.\r\n */\r\nexport interface StorageScanResult {\r\n /** Scan timestamp */\r\n timestamp: string;\r\n /** Base URL scanned */\r\n baseUrl: string;\r\n /** Pages scanned */\r\n pagesScanned: number;\r\n /** Overall pass/fail */\r\n passed: boolean;\r\n /** Violations found */\r\n violations: StorageViolation[];\r\n /** Summary statistics */\r\n summary: StorageScanSummary;\r\n}\r\n\r\n/**\r\n * A storage violation found during scan.\r\n */\r\nexport interface StorageViolation {\r\n /** Page URL where violation occurred */\r\n pageUrl: string;\r\n /** Type of violation */\r\n type: 'cookie' | 'localStorage' | 'sessionStorage' | 'indexedDB';\r\n /** Key name */\r\n key: string;\r\n /** Value (may be truncated) */\r\n value?: string;\r\n /** Likely source/framework */\r\n suspectedSource?: string;\r\n /** Severity */\r\n severity: 'critical' | 'high' | 'medium' | 'low';\r\n}\r\n\r\n/**\r\n * Scan summary statistics.\r\n */\r\nexport interface StorageScanSummary {\r\n /** Total cookies found */\r\n totalCookies: number;\r\n /** Total localStorage keys */\r\n totalLocalStorageKeys: number;\r\n /** Total sessionStorage keys */\r\n totalSessionStorageKeys: number;\r\n /** Total IndexedDB databases */\r\n totalIndexedDBDatabases: number;\r\n /** Total violations */\r\n totalViolations: number;\r\n /** Violations by severity */\r\n violationsBySeverity: Record<string, number>;\r\n}\r\n\r\n// =============================================================================\r\n// EXPORT HELPERS\r\n// =============================================================================\r\n\r\n/**\r\n * Default traceless policy - maximum privacy.\r\n */\r\nexport const DEFAULT_TRACELESS_POLICY: ITracelessPolicy = {\r\n cookiesAllowed: false,\r\n localStorageAllowed: false,\r\n sessionStorageAllowed: false,\r\n indexedDBAllowed: false,\r\n webSQLAllowed: false,\r\n serviceWorkerCacheAllowed: false,\r\n effectiveMode: 'traceless',\r\n consentRequired: false,\r\n canPersist: false,\r\n policySource: 'instance',\r\n resolvedAt: new Date().toISOString(),\r\n};\r\n\r\n/**\r\n * Default full policy - all storage allowed.\r\n */\r\nexport const DEFAULT_FULL_POLICY: ITracelessPolicy = {\r\n cookiesAllowed: true,\r\n localStorageAllowed: true,\r\n sessionStorageAllowed: true,\r\n indexedDBAllowed: true,\r\n webSQLAllowed: true,\r\n serviceWorkerCacheAllowed: true,\r\n effectiveMode: 'full',\r\n consentRequired: true,\r\n canPersist: true,\r\n policySource: 'instance',\r\n resolvedAt: new Date().toISOString(),\r\n};\r\n\r\n/**\r\n * Mode to capabilities mapping.\r\n */\r\nexport const MODE_CAPABILITIES: Record<TracelessMode, StorageCapabilities> = {\r\n traceless: {\r\n cookiesAllowed: false,\r\n localStorageAllowed: false,\r\n sessionStorageAllowed: false,\r\n indexedDBAllowed: false,\r\n webSQLAllowed: false,\r\n serviceWorkerCacheAllowed: false,\r\n },\r\n ephemeral: {\r\n cookiesAllowed: false,\r\n localStorageAllowed: false,\r\n sessionStorageAllowed: true,\r\n indexedDBAllowed: false,\r\n webSQLAllowed: false,\r\n serviceWorkerCacheAllowed: false,\r\n },\r\n private: {\r\n cookiesAllowed: false, // except httpOnly auth\r\n localStorageAllowed: false,\r\n sessionStorageAllowed: true,\r\n indexedDBAllowed: false,\r\n webSQLAllowed: false,\r\n serviceWorkerCacheAllowed: false,\r\n },\r\n balanced: {\r\n cookiesAllowed: false,\r\n localStorageAllowed: true,\r\n sessionStorageAllowed: true,\r\n indexedDBAllowed: true,\r\n webSQLAllowed: false,\r\n serviceWorkerCacheAllowed: true,\r\n },\r\n full: {\r\n cookiesAllowed: true,\r\n localStorageAllowed: true,\r\n sessionStorageAllowed: true,\r\n indexedDBAllowed: true,\r\n webSQLAllowed: true,\r\n serviceWorkerCacheAllowed: true,\r\n },\r\n custom: {\r\n cookiesAllowed: false,\r\n localStorageAllowed: false,\r\n sessionStorageAllowed: false,\r\n indexedDBAllowed: false,\r\n webSQLAllowed: false,\r\n serviceWorkerCacheAllowed: false,\r\n },\r\n};\r\n","/**\r\n * @fileoverview PRO-23: Accessibility & Internationalization Types\r\n *\r\n * This module provides TypeScript types and interfaces for building\r\n * fully accessible and internationalized applications following\r\n * WCAG 2.1 AA guidelines and supporting 50+ languages.\r\n *\r\n * @module @nice2dev/ui-tools/accessibility-i18n\r\n */\r\n\r\n// =============================================================================\r\n// ACCESSIBILITY (A11Y) TYPES\r\n// =============================================================================\r\n\r\n/**\r\n * WCAG compliance levels.\r\n */\r\nexport type WCAGLevel = 'A' | 'AA' | 'AAA';\r\n\r\n/**\r\n * WCAG version.\r\n */\r\nexport type WCAGVersion = '2.0' | '2.1' | '2.2';\r\n\r\n/**\r\n * Accessibility configuration for an application.\r\n */\r\nexport interface AccessibilityConfig {\r\n /** Target WCAG level */\r\n targetLevel: WCAGLevel;\r\n /** WCAG version to follow */\r\n wcagVersion: WCAGVersion;\r\n /** Enable screen reader optimizations */\r\n screenReaderOptimizations: boolean;\r\n /** Enable full keyboard navigation */\r\n keyboardNavigation: boolean;\r\n /** Enforce minimum color contrast */\r\n enforceColorContrast: boolean;\r\n /** Minimum contrast ratio (4.5:1 for AA) */\r\n minContrastRatio: number;\r\n /** Respect prefers-reduced-motion */\r\n respectReducedMotion: boolean;\r\n /** Enable focus visible indicators */\r\n focusVisible: boolean;\r\n /** Enable high contrast mode support */\r\n highContrastSupport: boolean;\r\n /** Enable forced colors support */\r\n forcedColorsSupport: boolean;\r\n /** Run automated accessibility tests */\r\n automatedTesting: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// ARIA TYPES\r\n// =============================================================================\r\n\r\n/**\r\n * ARIA roles for semantic meaning.\r\n */\r\nexport type AriaRole =\r\n // Landmark roles\r\n | 'banner'\r\n | 'complementary'\r\n | 'contentinfo'\r\n | 'form'\r\n | 'main'\r\n | 'navigation'\r\n | 'region'\r\n | 'search'\r\n // Widget roles\r\n | 'button'\r\n | 'checkbox'\r\n | 'dialog'\r\n | 'gridcell'\r\n | 'link'\r\n | 'log'\r\n | 'marquee'\r\n | 'menuitem'\r\n | 'menuitemcheckbox'\r\n | 'menuitemradio'\r\n | 'option'\r\n | 'progressbar'\r\n | 'radio'\r\n | 'scrollbar'\r\n | 'searchbox'\r\n | 'slider'\r\n | 'spinbutton'\r\n | 'status'\r\n | 'switch'\r\n | 'tab'\r\n | 'tabpanel'\r\n | 'textbox'\r\n | 'timer'\r\n | 'tooltip'\r\n | 'treeitem'\r\n // Document structure roles\r\n | 'article'\r\n | 'cell'\r\n | 'columnheader'\r\n | 'definition'\r\n | 'directory'\r\n | 'document'\r\n | 'figure'\r\n | 'group'\r\n | 'heading'\r\n | 'img'\r\n | 'list'\r\n | 'listitem'\r\n | 'math'\r\n | 'none'\r\n | 'note'\r\n | 'presentation'\r\n | 'row'\r\n | 'rowgroup'\r\n | 'rowheader'\r\n | 'separator'\r\n | 'table'\r\n | 'term'\r\n | 'toolbar'\r\n // Live region roles\r\n | 'alert'\r\n | 'alertdialog'\r\n | 'application'\r\n | 'grid'\r\n | 'listbox'\r\n | 'menu'\r\n | 'menubar'\r\n | 'radiogroup'\r\n | 'tablist'\r\n | 'tree'\r\n | 'treegrid';\r\n\r\n/**\r\n * ARIA live region politeness.\r\n */\r\nexport type AriaLive = 'off' | 'polite' | 'assertive';\r\n\r\n/**\r\n * ARIA pressed state for toggle buttons.\r\n */\r\nexport type AriaPressed = boolean | 'mixed';\r\n\r\n/**\r\n * ARIA expanded state for collapsible elements.\r\n */\r\nexport type AriaExpanded = boolean;\r\n\r\n/**\r\n * ARIA selected state.\r\n */\r\nexport type AriaSelected = boolean;\r\n\r\n/**\r\n * ARIA checked state.\r\n */\r\nexport type AriaChecked = boolean | 'mixed';\r\n\r\n/**\r\n * ARIA label configuration.\r\n */\r\nexport interface AriaLabelConfig {\r\n /** The accessible label */\r\n label?: string;\r\n /** ID of element that labels this */\r\n labelledBy?: string;\r\n /** ID of element that describes this */\r\n describedBy?: string;\r\n /** ID of error message element */\r\n errorMessage?: string;\r\n /** Additional details for screen readers */\r\n details?: string;\r\n}\r\n\r\n/**\r\n * ARIA relationship configuration.\r\n */\r\nexport interface AriaRelationships {\r\n /** ID of controlled element */\r\n controls?: string;\r\n /** IDs of owned elements */\r\n owns?: string;\r\n /** ID of active descendant */\r\n activeDescendant?: string;\r\n /** IDs of related flow elements */\r\n flowTo?: string;\r\n /** ID of help element */\r\n help?: string;\r\n}\r\n\r\n/**\r\n * ARIA state configuration.\r\n */\r\nexport interface AriaState {\r\n /** Whether element is expanded */\r\n expanded?: AriaExpanded;\r\n /** Whether element is selected */\r\n selected?: AriaSelected;\r\n /** Whether element is pressed */\r\n pressed?: AriaPressed;\r\n /** Whether element is checked */\r\n checked?: AriaChecked;\r\n /** Whether element is disabled */\r\n disabled?: boolean;\r\n /** Whether element is hidden */\r\n hidden?: boolean;\r\n /** Whether element is invalid */\r\n invalid?: boolean | 'grammar' | 'spelling';\r\n /** Whether element is required */\r\n required?: boolean;\r\n /** Whether element is read-only */\r\n readOnly?: boolean;\r\n /** Whether element is busy */\r\n busy?: boolean;\r\n /** Current value for range widgets */\r\n valuenow?: number;\r\n /** Minimum value for range widgets */\r\n valuemin?: number;\r\n /** Maximum value for range widgets */\r\n valuemax?: number;\r\n /** Text alternative for current value */\r\n valuetext?: string;\r\n /** Current item position */\r\n posinset?: number;\r\n /** Total items in set */\r\n setsize?: number;\r\n /** Level in hierarchy */\r\n level?: number;\r\n /** Sort direction */\r\n sort?: 'ascending' | 'descending' | 'none' | 'other';\r\n /** Autocomplete behavior */\r\n autocomplete?: 'none' | 'inline' | 'list' | 'both';\r\n /** Multiselectable */\r\n multiselectable?: boolean;\r\n /** Orientation */\r\n orientation?: 'horizontal' | 'vertical';\r\n}\r\n\r\n/**\r\n * Complete accessible element configuration.\r\n */\r\nexport interface AccessibleElementConfig extends AriaLabelConfig, AriaRelationships, AriaState {\r\n /** Element role */\r\n role?: AriaRole;\r\n /** Live region configuration */\r\n live?: AriaLive;\r\n /** Atomic updates for live regions */\r\n atomic?: boolean;\r\n /** Relevant changes for live regions */\r\n relevant?: 'additions' | 'removals' | 'text' | 'all';\r\n /** Tab index for keyboard navigation */\r\n tabIndex?: number;\r\n}\r\n\r\n// =============================================================================\r\n// KEYBOARD NAVIGATION\r\n// =============================================================================\r\n\r\n/**\r\n * Keyboard shortcut definition.\r\n */\r\nexport interface KeyboardShortcut {\r\n /** Shortcut identifier */\r\n id: string;\r\n /** Key combination (e.g., \"Ctrl+S\", \"Alt+Shift+P\") */\r\n keys: string;\r\n /** Description of what the shortcut does */\r\n description: string;\r\n /** Action category */\r\n category?: string;\r\n /** Whether shortcut is global */\r\n global?: boolean;\r\n /** Whether shortcut can be customized */\r\n customizable?: boolean;\r\n /** Alternative key combination */\r\n alternative?: string;\r\n /** Platform-specific overrides */\r\n platformOverrides?: Record<string, string>;\r\n}\r\n\r\n/**\r\n * Keyboard navigation configuration.\r\n */\r\nexport interface KeyboardNavigationConfig {\r\n /** Enable arrow key navigation */\r\n arrowNavigation: boolean;\r\n /** Enable tab navigation */\r\n tabNavigation: boolean;\r\n /** Enable home/end navigation */\r\n homeEndNavigation: boolean;\r\n /** Enable page up/down navigation */\r\n pageNavigation: boolean;\r\n /** Enable type-ahead search */\r\n typeAhead: boolean;\r\n /** Type-ahead timeout in ms */\r\n typeAheadTimeout?: number;\r\n /** Wrap around at boundaries */\r\n wrapNavigation: boolean;\r\n /** Custom shortcuts */\r\n shortcuts: KeyboardShortcut[];\r\n}\r\n\r\n/**\r\n * Focus trap configuration.\r\n */\r\nexport interface FocusTrapConfig {\r\n /** Enable focus trap */\r\n enabled: boolean;\r\n /** Allow escape key to exit */\r\n allowEscape: boolean;\r\n /** Return focus to trigger on close */\r\n returnFocus: boolean;\r\n /** Initial focus target selector */\r\n initialFocus?: string;\r\n /** Final focus target selector */\r\n finalFocus?: string;\r\n /** Selectors for focusable elements */\r\n focusableSelectors?: string[];\r\n}\r\n\r\n/**\r\n * Focus management utilities.\r\n */\r\nexport interface FocusManagement {\r\n /** Currently focused element ID */\r\n currentFocus?: string;\r\n /** Focus history stack */\r\n focusHistory: string[];\r\n /** Maximum history length */\r\n maxHistoryLength: number;\r\n /** Focus trap configuration */\r\n trap?: FocusTrapConfig;\r\n}\r\n\r\n// =============================================================================\r\n// COLOR & CONTRAST\r\n// =============================================================================\r\n\r\n/**\r\n * Color contrast requirements.\r\n */\r\nexport interface ColorContrastRequirements {\r\n /** Minimum contrast for normal text */\r\n normalText: number;\r\n /** Minimum contrast for large text (14pt bold or 18pt) */\r\n largeText: number;\r\n /** Minimum contrast for UI components */\r\n uiComponents: number;\r\n /** Minimum contrast for graphical objects */\r\n graphicalObjects: number;\r\n /** Minimum contrast for focus indicators */\r\n focusIndicators: number;\r\n}\r\n\r\n/**\r\n * WCAG 2.1 AA contrast requirements.\r\n */\r\nexport const WCAG_AA_CONTRAST: ColorContrastRequirements = {\r\n normalText: 4.5,\r\n largeText: 3,\r\n uiComponents: 3,\r\n graphicalObjects: 3,\r\n focusIndicators: 3,\r\n};\r\n\r\n/**\r\n * WCAG 2.1 AAA contrast requirements.\r\n */\r\nexport const WCAG_AAA_CONTRAST: ColorContrastRequirements = {\r\n normalText: 7,\r\n largeText: 4.5,\r\n uiComponents: 3,\r\n graphicalObjects: 3,\r\n focusIndicators: 4.5,\r\n};\r\n\r\n/**\r\n * Color contrast check result.\r\n */\r\nexport interface ContrastCheckResult {\r\n /** Foreground color */\r\n foreground: string;\r\n /** Background color */\r\n background: string;\r\n /** Calculated contrast ratio */\r\n ratio: number;\r\n /** Passes AA for normal text */\r\n passesAANormal: boolean;\r\n /** Passes AA for large text */\r\n passesAALarge: boolean;\r\n /** Passes AAA for normal text */\r\n passesAAANormal: boolean;\r\n /** Passes AAA for large text */\r\n passesAAALarge: boolean;\r\n /** Suggested alternatives if failing */\r\n suggestions?: ColorSuggestion[];\r\n}\r\n\r\n/**\r\n * Color suggestion for improving contrast.\r\n */\r\nexport interface ColorSuggestion {\r\n /** Suggested color */\r\n color: string;\r\n /** Resulting contrast ratio */\r\n resultingRatio: number;\r\n /** Whether it passes target level */\r\n passesTarget: boolean;\r\n /** How different from original (0-1) */\r\n colorDifference: number;\r\n}\r\n\r\n/**\r\n * High contrast mode configuration.\r\n */\r\nexport interface HighContrastConfig {\r\n /** Detect high contrast mode automatically */\r\n autoDetect: boolean;\r\n /** Custom high contrast theme */\r\n customTheme?: HighContrastTheme;\r\n /** Respect Windows high contrast mode */\r\n respectWindowsHC: boolean;\r\n /** Enable forced-colors support */\r\n forcedColors: boolean;\r\n}\r\n\r\n/**\r\n * High contrast theme colors.\r\n */\r\nexport interface HighContrastTheme {\r\n /** Background color */\r\n background: string;\r\n /** Foreground/text color */\r\n foreground: string;\r\n /** Link color */\r\n link: string;\r\n /** Visited link color */\r\n linkVisited: string;\r\n /** Button background */\r\n buttonBackground: string;\r\n /** Button text */\r\n buttonText: string;\r\n /** Disabled text */\r\n disabledText: string;\r\n /** Highlight background */\r\n highlight: string;\r\n /** Highlight text */\r\n highlightText: string;\r\n}\r\n\r\n// =============================================================================\r\n// MOTION & ANIMATION\r\n// =============================================================================\r\n\r\n/**\r\n * Reduced motion configuration.\r\n */\r\nexport interface ReducedMotionConfig {\r\n /** Detect prefers-reduced-motion automatically */\r\n autoDetect: boolean;\r\n /** Force reduced motion regardless of system setting */\r\n forceReduced: boolean;\r\n /** Alternative for essential animations */\r\n essentialAnimationFallback: 'none' | 'fade' | 'instant';\r\n /** Maximum animation duration when reduced (ms) */\r\n maxDuration: number;\r\n}\r\n\r\n/**\r\n * Animation accessibility settings.\r\n */\r\nexport interface AnimationAccessibility {\r\n /** Whether animations are enabled */\r\n enabled: boolean;\r\n /** Maximum animation duration (ms) */\r\n maxDuration: number;\r\n /** Disable parallax effects */\r\n disableParallax: boolean;\r\n /** Disable auto-playing videos */\r\n disableAutoplayVideo: boolean;\r\n /** Disable auto-playing audio */\r\n disableAutoplayAudio: boolean;\r\n /** Pause animations on focus loss */\r\n pauseOnFocusLoss: boolean;\r\n /** Provide animation controls */\r\n showAnimationControls: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// SCREEN READER SUPPORT\r\n// =============================================================================\r\n\r\n/**\r\n * Screen reader announcement configuration.\r\n */\r\nexport interface ScreenReaderAnnouncement {\r\n /** Message to announce */\r\n message: string;\r\n /** Politeness level */\r\n politeness: AriaLive;\r\n /** Whether to clear previous announcements */\r\n clearQueue?: boolean;\r\n /** Delay before announcement (ms) */\r\n delay?: number;\r\n}\r\n\r\n/**\r\n * Live region configuration.\r\n */\r\nexport interface LiveRegionConfig {\r\n /** Region ID */\r\n id: string;\r\n /** Politeness level */\r\n politeness: AriaLive;\r\n /** Whether updates are atomic */\r\n atomic: boolean;\r\n /** What changes are relevant */\r\n relevant: 'additions' | 'removals' | 'text' | 'all';\r\n /** Role (status, log, alert, etc.) */\r\n role?: 'status' | 'log' | 'alert' | 'progressbar' | 'marquee' | 'timer';\r\n}\r\n\r\n/**\r\n * Screen reader hints configuration.\r\n */\r\nexport interface ScreenReaderHints {\r\n /** Enable form field hints */\r\n formHints: boolean;\r\n /** Enable navigation hints */\r\n navigationHints: boolean;\r\n /** Enable state change announcements */\r\n stateChangeAnnouncements: boolean;\r\n /** Enable error announcements */\r\n errorAnnouncements: boolean;\r\n /** Enable loading announcements */\r\n loadingAnnouncements: boolean;\r\n /** Announce page titles */\r\n announcePageTitles: boolean;\r\n /** Announce focus changes */\r\n announceFocusChanges: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// FORM ACCESSIBILITY\r\n// =============================================================================\r\n\r\n/**\r\n * Accessible form field configuration.\r\n */\r\nexport interface AccessibleFormField {\r\n /** Field ID */\r\n id: string;\r\n /** Field name */\r\n name: string;\r\n /** Label text */\r\n label: string;\r\n /** Label position */\r\n labelPosition: 'before' | 'after' | 'floating';\r\n /** Whether label is visible */\r\n labelVisible: boolean;\r\n /** Help text */\r\n helpText?: string;\r\n /** Error message */\r\n errorMessage?: string;\r\n /** Whether field is required */\r\n required: boolean;\r\n /** Auto-complete attribute */\r\n autocomplete?: string;\r\n /** Input mode */\r\n inputMode?: 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';\r\n /** Pattern validation */\r\n pattern?: string;\r\n /** Pattern description for screen readers */\r\n patternDescription?: string;\r\n}\r\n\r\n/**\r\n * Form error handling configuration.\r\n */\r\nexport interface FormErrorHandling {\r\n /** Show inline errors */\r\n inlineErrors: boolean;\r\n /** Show error summary */\r\n errorSummary: boolean;\r\n /** Error summary position */\r\n summaryPosition: 'top' | 'bottom';\r\n /** Focus first error on submit */\r\n focusFirstError: boolean;\r\n /** Announce errors to screen readers */\r\n announceErrors: boolean;\r\n /** Error announcement politeness */\r\n errorPoliteness: AriaLive;\r\n /** Real-time validation */\r\n realtimeValidation: boolean;\r\n /** Validation delay (ms) */\r\n validationDelay?: number;\r\n}\r\n\r\n// =============================================================================\r\n// SKIP LINKS & LANDMARKS\r\n// =============================================================================\r\n\r\n/**\r\n * Skip link configuration.\r\n */\r\nexport interface SkipLink {\r\n /** Link text */\r\n text: string;\r\n /** Target element ID */\r\n target: string;\r\n /** Whether link is visible on focus */\r\n visibleOnFocus: boolean;\r\n}\r\n\r\n/**\r\n * Page landmarks configuration.\r\n */\r\nexport interface LandmarksConfig {\r\n /** Main content landmark ID */\r\n main?: string;\r\n /** Navigation landmark ID */\r\n navigation?: string;\r\n /** Search landmark ID */\r\n search?: string;\r\n /** Banner landmark ID */\r\n banner?: string;\r\n /** Footer landmark ID */\r\n contentinfo?: string;\r\n /** Complementary/aside landmark IDs */\r\n complementary?: string[];\r\n /** Custom regions */\r\n regions?: { id: string; label: string }[];\r\n}\r\n\r\n// =============================================================================\r\n// ACCESSIBILITY TESTING\r\n// =============================================================================\r\n\r\n/**\r\n * Accessibility test result.\r\n */\r\nexport interface AccessibilityTestResult {\r\n /** Test passed */\r\n passed: boolean;\r\n /** Number of violations */\r\n violationCount: number;\r\n /** Violations found */\r\n violations: AccessibilityViolation[];\r\n /** Passes (optional, for reporting) */\r\n passes?: AccessibilityPass[];\r\n /** Incomplete checks (need manual review) */\r\n incomplete?: AccessibilityIncomplete[];\r\n /** Test timestamp */\r\n timestamp: string;\r\n /** Page/component tested */\r\n target: string;\r\n}\r\n\r\n/**\r\n * Accessibility violation.\r\n */\r\nexport interface AccessibilityViolation {\r\n /** Rule ID */\r\n ruleId: string;\r\n /** Violation description */\r\n description: string;\r\n /** Impact severity */\r\n impact: 'minor' | 'moderate' | 'serious' | 'critical';\r\n /** WCAG criteria violated */\r\n wcagCriteria: string[];\r\n /** Help URL */\r\n helpUrl: string;\r\n /** Affected elements */\r\n nodes: AccessibilityNode[];\r\n /** How to fix */\r\n fix: string;\r\n}\r\n\r\n/**\r\n * Accessibility pass (rule that passed).\r\n */\r\nexport interface AccessibilityPass {\r\n /** Rule ID */\r\n ruleId: string;\r\n /** Rule description */\r\n description: string;\r\n /** Elements that passed */\r\n nodes: AccessibilityNode[];\r\n}\r\n\r\n/**\r\n * Incomplete accessibility check.\r\n */\r\nexport interface AccessibilityIncomplete {\r\n /** Rule ID */\r\n ruleId: string;\r\n /** What needs manual review */\r\n description: string;\r\n /** Elements to review */\r\n nodes: AccessibilityNode[];\r\n}\r\n\r\n/**\r\n * Affected DOM node.\r\n */\r\nexport interface AccessibilityNode {\r\n /** Element selector */\r\n selector: string;\r\n /** Element HTML */\r\n html: string;\r\n /** Failure summary */\r\n failureSummary?: string;\r\n}\r\n\r\n// =============================================================================\r\n// INTERNATIONALIZATION (I18N) TYPES\r\n// =============================================================================\r\n\r\n/**\r\n * Locale identifier (BCP 47).\r\n */\r\nexport type LocaleCode = string; // e.g., 'en', 'en-US', 'pl-PL', 'ar-SA'\r\n\r\n/**\r\n * Text direction.\r\n */\r\nexport type TextDirection = 'ltr' | 'rtl' | 'auto';\r\n\r\n/**\r\n * I18n configuration.\r\n */\r\nexport interface I18nConfig {\r\n /** Default locale */\r\n defaultLocale: LocaleCode;\r\n /** Supported locales */\r\n supportedLocales: LocaleCode[];\r\n /** Fallback locale */\r\n fallbackLocale: LocaleCode;\r\n /** Enable RTL support */\r\n rtlSupport: boolean;\r\n /** RTL locales */\r\n rtlLocales: LocaleCode[];\r\n /** Load locale on demand */\r\n lazyLoading: boolean;\r\n /** Translation file format */\r\n format: 'json' | 'yaml' | 'po' | 'xliff';\r\n /** Missing translation handling */\r\n missingTranslation: 'warn' | 'error' | 'fallback' | 'key';\r\n /** Enable pluralization */\r\n pluralization: boolean;\r\n /** Enable gender agreement */\r\n genderAgreement: boolean;\r\n /** Date/time format configuration */\r\n dateTimeFormats: Record<LocaleCode, DateTimeFormats>;\r\n /** Number format configuration */\r\n numberFormats: Record<LocaleCode, NumberFormats>;\r\n}\r\n\r\n// =============================================================================\r\n// DATE/TIME FORMATTING\r\n// =============================================================================\r\n\r\n/**\r\n * Date/time format presets.\r\n */\r\nexport interface DateTimeFormats {\r\n /** Short date format */\r\n short: Intl.DateTimeFormatOptions;\r\n /** Medium date format */\r\n medium: Intl.DateTimeFormatOptions;\r\n /** Long date format */\r\n long: Intl.DateTimeFormatOptions;\r\n /** Full date format */\r\n full: Intl.DateTimeFormatOptions;\r\n /** Time only format */\r\n time: Intl.DateTimeFormatOptions;\r\n /** DateTime format */\r\n datetime: Intl.DateTimeFormatOptions;\r\n /** Relative time format */\r\n relative: Intl.RelativeTimeFormatOptions;\r\n}\r\n\r\n/**\r\n * Date formatting configuration.\r\n */\r\nexport interface DateFormatConfig {\r\n /** Locale for formatting */\r\n locale: LocaleCode;\r\n /** Calendar system */\r\n calendar: CalendarSystem;\r\n /** Timezone */\r\n timezone: string;\r\n /** Hour cycle (12 or 24) */\r\n hourCycle: 'h11' | 'h12' | 'h23' | 'h24';\r\n /** Week starts on */\r\n weekStartsOn: 0 | 1 | 2 | 3 | 4 | 5 | 6;\r\n}\r\n\r\n/**\r\n * Supported calendar systems.\r\n */\r\nexport type CalendarSystem =\r\n | 'gregory' // Gregorian (default)\r\n | 'buddhist' // Buddhist\r\n | 'chinese' // Chinese\r\n | 'coptic' // Coptic\r\n | 'ethiopic' // Ethiopian\r\n | 'hebrew' // Hebrew\r\n | 'indian' // Indian National\r\n | 'islamic' // Islamic (Hijri)\r\n | 'islamic-civil' // Islamic civil\r\n | 'islamic-rgsa' // Islamic (Saudi Arabia)\r\n | 'islamic-tbla' // Islamic (tabular)\r\n | 'islamic-umalqura' // Islamic (Umm al-Qura)\r\n | 'japanese' // Japanese\r\n | 'persian' // Persian (Jalali)\r\n | 'roc'; // Republic of China\r\n\r\n/**\r\n * Relative time formatting result.\r\n */\r\nexport interface RelativeTimeResult {\r\n /** Formatted string */\r\n formatted: string;\r\n /** Unit used */\r\n unit: Intl.RelativeTimeFormatUnit;\r\n /** Numeric value */\r\n value: number;\r\n /** Whether time is in past */\r\n isPast: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// NUMBER FORMATTING\r\n// =============================================================================\r\n\r\n/**\r\n * Number format presets.\r\n */\r\nexport interface NumberFormats {\r\n /** Decimal format */\r\n decimal: Intl.NumberFormatOptions;\r\n /** Currency format */\r\n currency: CurrencyFormatOptions;\r\n /** Percent format */\r\n percent: Intl.NumberFormatOptions;\r\n /** Compact format (1K, 1M) */\r\n compact: Intl.NumberFormatOptions;\r\n /** Scientific format */\r\n scientific: Intl.NumberFormatOptions;\r\n /** Unit format */\r\n unit: UnitFormatOptions;\r\n}\r\n\r\n/**\r\n * Currency format options.\r\n */\r\nexport interface CurrencyFormatOptions extends Intl.NumberFormatOptions {\r\n /** Currency code (ISO 4217) */\r\n currency: string;\r\n /** Currency display style */\r\n currencyDisplay?: 'symbol' | 'narrowSymbol' | 'code' | 'name';\r\n /** Accounting format for negative values */\r\n currencySign?: 'standard' | 'accounting';\r\n}\r\n\r\n/**\r\n * Unit format options.\r\n */\r\nexport interface UnitFormatOptions extends Intl.NumberFormatOptions {\r\n /** Unit to display */\r\n unit: string;\r\n /** Unit display style */\r\n unitDisplay?: 'short' | 'narrow' | 'long';\r\n}\r\n\r\n/**\r\n * Common currency codes.\r\n */\r\nexport type CurrencyCode =\r\n | 'USD'\r\n | 'EUR'\r\n | 'GBP'\r\n | 'JPY'\r\n | 'CNY'\r\n | 'CHF'\r\n | 'CAD'\r\n | 'AUD'\r\n | 'NZD'\r\n | 'SEK'\r\n | 'NOK'\r\n | 'DKK'\r\n | 'PLN'\r\n | 'CZK'\r\n | 'HUF'\r\n | 'RON'\r\n | 'BGN'\r\n | 'HRK'\r\n | 'RUB'\r\n | 'UAH'\r\n | 'TRY'\r\n | 'BRL'\r\n | 'MXN'\r\n | 'ARS'\r\n | 'INR'\r\n | 'KRW'\r\n | 'SGD'\r\n | 'HKD'\r\n | 'TWD'\r\n | 'THB'\r\n | 'MYR'\r\n | 'IDR'\r\n | 'PHP'\r\n | 'VND'\r\n | 'ZAR'\r\n | 'EGP'\r\n | 'SAR'\r\n | 'AED'\r\n | 'ILS'\r\n | 'NGN'\r\n | string; // Allow other codes\r\n\r\n// =============================================================================\r\n// PLURALIZATION\r\n// =============================================================================\r\n\r\n/**\r\n * Plural categories (CLDR).\r\n */\r\nexport type PluralCategory = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other';\r\n\r\n/**\r\n * Plural rule function type.\r\n */\r\nexport type PluralRuleFunction = (n: number, ord?: boolean) => PluralCategory;\r\n\r\n/**\r\n * Plural rules configuration.\r\n */\r\nexport interface PluralRules {\r\n /** Locale */\r\n locale: LocaleCode;\r\n /** Cardinal plural rules */\r\n cardinal: PluralRuleFunction;\r\n /** Ordinal plural rules */\r\n ordinal: PluralRuleFunction;\r\n /** Plural categories used by this locale */\r\n categories: PluralCategory[];\r\n /** Ordinal categories used by this locale */\r\n ordinalCategories: PluralCategory[];\r\n}\r\n\r\n/**\r\n * Pluralized message.\r\n */\r\nexport interface PluralMessage {\r\n /** Message for zero */\r\n zero?: string;\r\n /** Message for one */\r\n one?: string;\r\n /** Message for two (Arabic, Hebrew) */\r\n two?: string;\r\n /** Message for few (Slavic languages) */\r\n few?: string;\r\n /** Message for many (Slavic languages) */\r\n many?: string;\r\n /** Message for other (required) */\r\n other: string;\r\n}\r\n\r\n// =============================================================================\r\n// GENDER AGREEMENT\r\n// =============================================================================\r\n\r\n/**\r\n * Grammatical gender.\r\n */\r\nexport type GrammaticalGender =\r\n | 'masculine'\r\n | 'feminine'\r\n | 'neuter'\r\n | 'common'\r\n | 'animate'\r\n | 'inanimate';\r\n\r\n/**\r\n * Gender-aware message.\r\n */\r\nexport interface GenderedMessage {\r\n /** Message for masculine */\r\n masculine?: string;\r\n /** Message for feminine */\r\n feminine?: string;\r\n /** Message for neuter */\r\n neuter?: string;\r\n /** Message for unknown/common gender */\r\n other: string;\r\n}\r\n\r\n/**\r\n * Combined plural and gender message.\r\n */\r\nexport interface PluralGenderedMessage {\r\n /** Messages by gender, then by plural */\r\n [gender: string]: PluralMessage;\r\n}\r\n\r\n// =============================================================================\r\n// TRANSLATION MANAGEMENT\r\n// =============================================================================\r\n\r\n/**\r\n * Translation entry.\r\n */\r\nexport interface TranslationEntry {\r\n /** Translation key */\r\n key: string;\r\n /** Source text */\r\n source: string;\r\n /** Translated text */\r\n translation: string;\r\n /** Context for translators */\r\n context?: string;\r\n /** Translator notes */\r\n notes?: string;\r\n /** Whether entry is reviewed */\r\n reviewed: boolean;\r\n /** Last modified timestamp */\r\n lastModified: string;\r\n /** Last modified by */\r\n modifiedBy?: string;\r\n /** Plural forms */\r\n plurals?: PluralMessage;\r\n /** Gender forms */\r\n genders?: GenderedMessage;\r\n}\r\n\r\n/**\r\n * Translation namespace/file.\r\n */\r\nexport interface TranslationNamespace {\r\n /** Namespace name */\r\n name: string;\r\n /** Locale code */\r\n locale: LocaleCode;\r\n /** Translations in this namespace */\r\n translations: Record<string, TranslationEntry | string | PluralMessage>;\r\n /** Namespace version */\r\n version: string;\r\n /** Last updated */\r\n lastUpdated: string;\r\n}\r\n\r\n/**\r\n * Translation Management System (TMS) integration.\r\n */\r\nexport interface TMSIntegration {\r\n /** TMS provider */\r\n provider: 'crowdin' | 'lokalise' | 'phrase' | 'transifex' | 'weblate' | 'custom';\r\n /** API endpoint */\r\n apiEndpoint?: string;\r\n /** API key (should be from env) */\r\n apiKey?: string;\r\n /** Project ID */\r\n projectId: string;\r\n /** Sync direction */\r\n syncDirection: 'push' | 'pull' | 'both';\r\n /** Auto-sync on build */\r\n autoSync: boolean;\r\n}\r\n\r\n/**\r\n * Translation memory entry.\r\n */\r\nexport interface TranslationMemoryEntry {\r\n /** Source text */\r\n source: string;\r\n /** Source locale */\r\n sourceLocale: LocaleCode;\r\n /** Target text */\r\n target: string;\r\n /** Target locale */\r\n targetLocale: LocaleCode;\r\n /** Similarity score (0-100) */\r\n similarity: number;\r\n /** Context */\r\n context?: string;\r\n /** Usage count */\r\n usageCount: number;\r\n}\r\n\r\n// =============================================================================\r\n// RTL SUPPORT\r\n// =============================================================================\r\n\r\n/**\r\n * RTL layout configuration.\r\n */\r\nexport interface RTLConfig {\r\n /** Current direction */\r\n direction: TextDirection;\r\n /** Flip icons in RTL */\r\n flipIcons: boolean;\r\n /** Icons to exclude from flipping */\r\n excludeIcons: string[];\r\n /** Flip animations */\r\n flipAnimations: boolean;\r\n /** Use logical properties (start/end vs left/right) */\r\n useLogicalProperties: boolean;\r\n /** Mirror entire layout */\r\n mirrorLayout: boolean;\r\n}\r\n\r\n/**\r\n * Bidirectional text handling.\r\n */\r\nexport interface BidiConfig {\r\n /** Enable bidirectional text support */\r\n enabled: boolean;\r\n /** Default text direction */\r\n defaultDirection: TextDirection;\r\n /** Isolate mixed direction text */\r\n isolateMixed: boolean;\r\n /** Override algorithm for specific elements */\r\n overrides?: Record<string, TextDirection>;\r\n}\r\n\r\n// =============================================================================\r\n// TIMEZONE HANDLING\r\n// =============================================================================\r\n\r\n/**\r\n * Timezone configuration.\r\n */\r\nexport interface TimezoneConfig {\r\n /** User's timezone */\r\n userTimezone: string;\r\n /** Server/default timezone */\r\n serverTimezone: string;\r\n /** Display format */\r\n displayFormat: 'local' | 'utc' | 'both';\r\n /** Auto-detect timezone */\r\n autoDetect: boolean;\r\n /** Show timezone abbreviation */\r\n showAbbreviation: boolean;\r\n}\r\n\r\n/**\r\n * Timezone info.\r\n */\r\nexport interface TimezoneInfo {\r\n /** IANA timezone ID */\r\n id: string;\r\n /** Display name */\r\n displayName: string;\r\n /** UTC offset in minutes */\r\n offsetMinutes: number;\r\n /** UTC offset string (e.g., \"+02:00\") */\r\n offsetString: string;\r\n /** Abbreviation (e.g., \"CET\", \"EST\") */\r\n abbreviation: string;\r\n /** Whether DST is currently active */\r\n isDST: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// PSEUDO-LOCALIZATION\r\n// =============================================================================\r\n\r\n/**\r\n * Pseudo-localization configuration for testing.\r\n */\r\nexport interface PseudoLocalizationConfig {\r\n /** Enable pseudo-localization */\r\n enabled: boolean;\r\n /** Pseudo-locale code */\r\n pseudoLocale: string;\r\n /** Expansion factor (1.3 = 30% longer) */\r\n expansionFactor: number;\r\n /** Use accented characters */\r\n accented: boolean;\r\n /** Add brackets around strings */\r\n brackets: boolean;\r\n /** Bracket style */\r\n bracketStyle: '[{text}]' | '「{text}」' | '《{text}》';\r\n /** Simulate RTL */\r\n simulateRtl: boolean;\r\n /** Exclamation marks at start */\r\n exclamation: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// LOCALE DETECTION\r\n// =============================================================================\r\n\r\n/**\r\n * Locale detection configuration.\r\n */\r\nexport interface LocaleDetectionConfig {\r\n /** Detection order */\r\n order: LocaleDetectionSource[];\r\n /** Default if detection fails */\r\n fallback: LocaleCode;\r\n /** Cache detected locale */\r\n cache: boolean;\r\n /** Cache key (localStorage/cookie) */\r\n cacheKey: string;\r\n /** Accept partial matches (e.g., 'en' for 'en-US') */\r\n partialMatch: boolean;\r\n}\r\n\r\n/**\r\n * Sources for locale detection.\r\n */\r\nexport type LocaleDetectionSource =\r\n | 'querystring' // URL parameter (?lang=en)\r\n | 'cookie' // Cookie value\r\n | 'localStorage' // localStorage value\r\n | 'sessionStorage' // sessionStorage value\r\n | 'navigator' // navigator.language\r\n | 'header' // Accept-Language header\r\n | 'path' // URL path (/en/page)\r\n | 'subdomain' // Subdomain (en.example.com)\r\n | 'custom'; // Custom detection function\r\n\r\n// =============================================================================\r\n// REACT INTEGRATION\r\n// =============================================================================\r\n\r\n/**\r\n * useTranslation hook options.\r\n */\r\nexport interface UseTranslationOptions {\r\n /** Namespace to use */\r\n namespace?: string | string[];\r\n /** Key prefix */\r\n keyPrefix?: string;\r\n /** Fallback namespace */\r\n fallbackNS?: string;\r\n /** Use suspense for loading */\r\n useSuspense?: boolean;\r\n}\r\n\r\n/**\r\n * useTranslation hook return type.\r\n */\r\nexport interface UseTranslationResult {\r\n /** Translation function */\r\n t: TranslationFunction;\r\n /** Current locale */\r\n locale: LocaleCode;\r\n /** Available locales */\r\n locales: LocaleCode[];\r\n /** Change locale */\r\n changeLocale: (locale: LocaleCode) => Promise<void>;\r\n /** Whether translations are loading */\r\n isLoading: boolean;\r\n /** Current direction */\r\n dir: TextDirection;\r\n}\r\n\r\n/**\r\n * Translation function type.\r\n */\r\nexport type TranslationFunction = {\r\n /** Simple translation */\r\n (key: string): string;\r\n /** Translation with interpolation */\r\n (key: string, values: Record<string, unknown>): string;\r\n /** Translation with count for pluralization */\r\n (key: string, options: { count: number; [key: string]: unknown }): string;\r\n /** Translation with context */\r\n (key: string, options: { context: string; [key: string]: unknown }): string;\r\n};\r\n\r\n/**\r\n * I18n provider props.\r\n */\r\nexport interface I18nProviderProps {\r\n /** I18n configuration */\r\n config: I18nConfig;\r\n /** Initial locale */\r\n initialLocale?: LocaleCode;\r\n /** Children */\r\n children: React.ReactNode;\r\n /** On locale change callback */\r\n onLocaleChange?: (locale: LocaleCode) => void;\r\n}\r\n\r\n// =============================================================================\r\n// COMBINED ACCESSIBILITY & I18N\r\n// =============================================================================\r\n\r\n/**\r\n * Full accessibility and i18n configuration.\r\n */\r\nexport interface A11yI18nConfig {\r\n /** Accessibility configuration */\r\n accessibility: AccessibilityConfig;\r\n /** I18n configuration */\r\n i18n: I18nConfig;\r\n /** Screen reader adjustments per locale */\r\n localeScreenReaderAdjustments?: Record<LocaleCode, ScreenReaderHints>;\r\n /** Locale-specific keyboard shortcuts */\r\n localeKeyboardShortcuts?: Record<LocaleCode, KeyboardShortcut[]>;\r\n}\r\n\r\n/**\r\n * Default accessibility configuration.\r\n */\r\nexport const DEFAULT_ACCESSIBILITY_CONFIG: AccessibilityConfig = {\r\n targetLevel: 'AA',\r\n wcagVersion: '2.1',\r\n screenReaderOptimizations: true,\r\n keyboardNavigation: true,\r\n enforceColorContrast: true,\r\n minContrastRatio: 4.5,\r\n respectReducedMotion: true,\r\n focusVisible: true,\r\n highContrastSupport: true,\r\n forcedColorsSupport: true,\r\n automatedTesting: true,\r\n};\r\n\r\n/**\r\n * Common supported locales.\r\n */\r\nexport const COMMON_LOCALES: LocaleCode[] = [\r\n 'en',\r\n 'en-US',\r\n 'en-GB',\r\n 'es',\r\n 'es-ES',\r\n 'es-MX',\r\n 'fr',\r\n 'fr-FR',\r\n 'fr-CA',\r\n 'de',\r\n 'de-DE',\r\n 'it',\r\n 'it-IT',\r\n 'pt',\r\n 'pt-BR',\r\n 'pt-PT',\r\n 'ru',\r\n 'ru-RU',\r\n 'zh',\r\n 'zh-CN',\r\n 'zh-TW',\r\n 'ja',\r\n 'ja-JP',\r\n 'ko',\r\n 'ko-KR',\r\n 'ar',\r\n 'ar-SA',\r\n 'he',\r\n 'he-IL',\r\n 'hi',\r\n 'hi-IN',\r\n 'pl',\r\n 'pl-PL',\r\n 'nl',\r\n 'nl-NL',\r\n 'tr',\r\n 'tr-TR',\r\n 'sv',\r\n 'sv-SE',\r\n 'da',\r\n 'da-DK',\r\n 'no',\r\n 'nb-NO',\r\n 'fi',\r\n 'fi-FI',\r\n 'cs',\r\n 'cs-CZ',\r\n 'sk',\r\n 'sk-SK',\r\n 'hu',\r\n 'hu-HU',\r\n 'ro',\r\n 'ro-RO',\r\n 'bg',\r\n 'bg-BG',\r\n 'uk',\r\n 'uk-UA',\r\n 'el',\r\n 'el-GR',\r\n 'th',\r\n 'th-TH',\r\n 'vi',\r\n 'vi-VN',\r\n 'id',\r\n 'id-ID',\r\n 'ms',\r\n 'ms-MY',\r\n];\r\n\r\n/**\r\n * RTL locales.\r\n */\r\nexport const RTL_LOCALES: LocaleCode[] = [\r\n 'ar',\r\n 'ar-SA',\r\n 'ar-AE',\r\n 'ar-EG',\r\n 'ar-MA',\r\n 'he',\r\n 'he-IL',\r\n 'fa',\r\n 'fa-IR',\r\n 'ur',\r\n 'ur-PK',\r\n 'ps', // Pashto\r\n 'sd', // Sindhi\r\n 'yi', // Yiddish\r\n];\r\n","/**\r\n * @fileoverview PRO-28: Icons Professional Suite Types\r\n *\r\n * This module provides TypeScript types and interfaces for the comprehensive\r\n * icon system including icon management, searching, editing, and cross-framework\r\n * support.\r\n *\r\n * @module @nice2dev/ui-tools/icon-tools\r\n */\r\n\r\n// =============================================================================\r\n// CORE ICON TYPES\r\n// =============================================================================\r\n\r\n/**\r\n * Icon style variants.\r\n */\r\nexport type IconStyle =\r\n | 'solid' // Filled icons\r\n | 'outline' // Line/stroke icons\r\n | 'duotone' // Two-color icons\r\n | 'light' // Light stroke weight\r\n | 'thin' // Thinnest stroke weight\r\n | 'bold' // Bold stroke weight\r\n | 'filled' // Alias for solid\r\n | 'regular' // Default weight\r\n | 'brand'; // Brand/logo icons\r\n\r\n/**\r\n * Icon size presets.\r\n */\r\nexport type IconSize =\r\n | 'xs' // 12px\r\n | 'sm' // 16px\r\n | 'md' // 24px\r\n | 'lg' // 32px\r\n | 'xl' // 48px\r\n | '2xl' // 64px\r\n | '3xl' // 96px\r\n | '4xl'; // 128px\r\n\r\n/**\r\n * Icon size in pixels.\r\n */\r\nexport type IconSizePixels =\r\n | 12\r\n | 14\r\n | 16\r\n | 18\r\n | 20\r\n | 24\r\n | 28\r\n | 32\r\n | 36\r\n | 40\r\n | 48\r\n | 56\r\n | 64\r\n | 72\r\n | 96\r\n | 128\r\n | 192\r\n | 256\r\n | 512;\r\n\r\n/**\r\n * Icon category for organization.\r\n */\r\nexport type IconCategory =\r\n | 'action' // Action icons (edit, delete, save)\r\n | 'alert' // Alert/notification icons\r\n | 'av' // Audio/video controls\r\n | 'communication' // Email, chat, phone\r\n | 'content' // Content management\r\n | 'device' // Device/hardware\r\n | 'editor' // Text editor\r\n | 'file' // File types\r\n | 'hardware' // Hardware devices\r\n | 'image' // Image manipulation\r\n | 'maps' // Maps and navigation\r\n | 'navigation' // UI navigation\r\n | 'notification' // Notifications\r\n | 'places' // Places and buildings\r\n | 'social' // Social platforms\r\n | 'toggle' // Toggle controls\r\n | 'brand' // Brand logos\r\n | 'custom'; // Custom/user-defined\r\n\r\n/**\r\n * Domain-specific icon categories.\r\n */\r\nexport type DomainCategory =\r\n | 'business' // Business operations\r\n | 'finance' // Financial\r\n | 'healthcare' // Medical/health\r\n | 'education' // Educational\r\n | 'manufacturing' // Industrial\r\n | 'retail' // Retail/commerce\r\n | 'technology' // Tech/IT\r\n | 'gaming' // Game-related\r\n | 'science' // Scientific\r\n | 'life-management' // Personal life\r\n | 'creative' // Creative/design\r\n | 'legal' // Legal/compliance\r\n | 'hr' // Human resources\r\n | 'logistics'; // Supply chain\r\n\r\n/**\r\n * Use case for icon selection.\r\n */\r\nexport type IconUseCase =\r\n | 'toolbar' // Toolbar button\r\n | 'menu' // Menu item\r\n | 'button' // Action button\r\n | 'status' // Status indicator\r\n | 'cursor' // Mouse cursor\r\n | 'notification' // Notification badge\r\n | 'tab' // Tab icon\r\n | 'avatar' // Avatar/profile\r\n | 'decoration' // Decorative only\r\n | 'illustration' // Illustrative\r\n | 'logo' // Brand logo\r\n | 'favicon'; // Website favicon\r\n\r\n// =============================================================================\r\n// ICON METADATA\r\n// =============================================================================\r\n\r\n/**\r\n * Basic icon definition.\r\n */\r\nexport interface IconDefinition {\r\n /** Unique icon ID */\r\n id: string;\r\n /** Icon name (kebab-case) */\r\n name: string;\r\n /** Display name */\r\n displayName: string;\r\n /** SVG path data */\r\n path: string;\r\n /** Alternative paths for composite icons */\r\n paths?: string[];\r\n /** Viewbox dimensions */\r\n viewBox: string;\r\n /** Default fill rule */\r\n fillRule?: 'nonzero' | 'evenodd';\r\n /** Default stroke properties */\r\n stroke?: IconStrokeConfig;\r\n /** Icon style */\r\n style: IconStyle;\r\n /** Available sizes */\r\n sizes?: IconSizePixels[];\r\n}\r\n\r\n/**\r\n * Stroke configuration for outline icons.\r\n */\r\nexport interface IconStrokeConfig {\r\n /** Stroke width */\r\n width: number;\r\n /** Stroke line cap */\r\n lineCap: 'butt' | 'round' | 'square';\r\n /** Stroke line join */\r\n lineJoin: 'miter' | 'round' | 'bevel';\r\n /** Miter limit */\r\n miterLimit?: number;\r\n}\r\n\r\n/**\r\n * Extended icon metadata for search and organization.\r\n */\r\nexport interface IconMetadata extends IconDefinition {\r\n /** Primary category */\r\n category: IconCategory;\r\n /** Secondary categories */\r\n secondaryCategories?: IconCategory[];\r\n /** Domain tags */\r\n domains: DomainCategory[];\r\n /** Use case tags */\r\n useCases: IconUseCase[];\r\n /** Style compatibility */\r\n availableStyles: IconStyle[];\r\n /** Recommended sizes */\r\n recommendedSizes: IconSizePixels[];\r\n /** Related icon IDs */\r\n relatedIcons: string[];\r\n /** Alternative names/aliases */\r\n aliases: string[];\r\n /** Localized names */\r\n localizedNames: Record<string, string>;\r\n /** Keywords for search */\r\n keywords: string[];\r\n /** Description */\r\n description?: string;\r\n /** Version added */\r\n versionAdded: string;\r\n /** Whether icon is deprecated */\r\n deprecated?: boolean;\r\n /** Replacement icon if deprecated */\r\n replacement?: string;\r\n /** License information */\r\n license?: string;\r\n /** Author/source */\r\n author?: string;\r\n /** Unicode codepoint (if in icon font) */\r\n unicode?: string;\r\n}\r\n\r\n/**\r\n * Icon usage statistics.\r\n */\r\nexport interface IconUsageStats {\r\n /** Icon ID */\r\n iconId: string;\r\n /** Total usage count */\r\n totalUsage: number;\r\n /** Usage by project */\r\n byProject: Record<string, number>;\r\n /** Usage by component type */\r\n byComponentType: Record<string, number>;\r\n /** First used date */\r\n firstUsed: string;\r\n /** Last used date */\r\n lastUsed: string;\r\n /** Usage trend */\r\n trend: 'increasing' | 'stable' | 'decreasing';\r\n}\r\n\r\n// =============================================================================\r\n// ICON COLLECTIONS\r\n// =============================================================================\r\n\r\n/**\r\n * Icon set/collection definition.\r\n */\r\nexport interface IconSet {\r\n /** Set identifier */\r\n id: string;\r\n /** Set name */\r\n name: string;\r\n /** Set description */\r\n description: string;\r\n /** Set version */\r\n version: string;\r\n /** Total icon count */\r\n iconCount: number;\r\n /** Available styles in this set */\r\n styles: IconStyle[];\r\n /** License */\r\n license: IconLicense;\r\n /** Author/organization */\r\n author: string;\r\n /** Website URL */\r\n website?: string;\r\n /** Documentation URL */\r\n docsUrl?: string;\r\n /** Icon prefix */\r\n prefix: string;\r\n /** Default style */\r\n defaultStyle: IconStyle;\r\n /** Categories available */\r\n categories: IconCategory[];\r\n /** Icons in this set */\r\n icons: Record<string, IconDefinition>;\r\n}\r\n\r\n/**\r\n * Icon license information.\r\n */\r\nexport interface IconLicense {\r\n /** License name */\r\n name: string;\r\n /** SPDX identifier */\r\n spdx?: string;\r\n /** License URL */\r\n url?: string;\r\n /** Whether attribution is required */\r\n attributionRequired: boolean;\r\n /** Attribution text if required */\r\n attributionText?: string;\r\n /** Commercial use allowed */\r\n commercialUse: boolean;\r\n /** Modification allowed */\r\n modification: boolean;\r\n}\r\n\r\n/**\r\n * User-created icon collection.\r\n */\r\nexport interface UserIconCollection {\r\n /** Collection ID */\r\n id: string;\r\n /** Collection name */\r\n name: string;\r\n /** Description */\r\n description?: string;\r\n /** Owner user ID */\r\n ownerId: string;\r\n /** Icon IDs in collection */\r\n iconIds: string[];\r\n /** Custom icon data (user-created icons) */\r\n customIcons?: IconDefinition[];\r\n /** Created date */\r\n createdAt: string;\r\n /** Last modified date */\r\n modifiedAt: string;\r\n /** Whether collection is public */\r\n isPublic: boolean;\r\n /** Tags for organization */\r\n tags: string[];\r\n /** Cover icon ID */\r\n coverIconId?: string;\r\n}\r\n\r\n// =============================================================================\r\n// ICON SEARCH\r\n// =============================================================================\r\n\r\n/**\r\n * Icon search query.\r\n */\r\nexport interface IconSearchQuery {\r\n /** Search text */\r\n query: string;\r\n /** Filter by category */\r\n categories?: IconCategory[];\r\n /** Filter by domain */\r\n domains?: DomainCategory[];\r\n /** Filter by use case */\r\n useCases?: IconUseCase[];\r\n /** Filter by style */\r\n styles?: IconStyle[];\r\n /** Filter by size availability */\r\n sizes?: IconSizePixels[];\r\n /** Filter by icon set */\r\n sets?: string[];\r\n /** Include deprecated icons */\r\n includeDeprecated?: boolean;\r\n /** Search mode */\r\n mode?: 'exact' | 'fuzzy' | 'semantic';\r\n /** Fuzzy match threshold (0-1) */\r\n fuzzyThreshold?: number;\r\n /** Sort by */\r\n sortBy?: 'relevance' | 'name' | 'popularity' | 'recent';\r\n /** Sort direction */\r\n sortDir?: 'asc' | 'desc';\r\n /** Page number */\r\n page?: number;\r\n /** Page size */\r\n pageSize?: number;\r\n}\r\n\r\n/**\r\n * Icon search result.\r\n */\r\nexport interface IconSearchResult {\r\n /** Total matches */\r\n total: number;\r\n /** Current page */\r\n page: number;\r\n /** Page size */\r\n pageSize: number;\r\n /** Results */\r\n results: IconSearchHit[];\r\n /** Search suggestions */\r\n suggestions?: string[];\r\n /** Related searches */\r\n relatedSearches?: string[];\r\n /** Facets for filtering */\r\n facets?: IconSearchFacets;\r\n}\r\n\r\n/**\r\n * Individual search hit.\r\n */\r\nexport interface IconSearchHit {\r\n /** Icon metadata */\r\n icon: IconMetadata;\r\n /** Relevance score (0-100) */\r\n score: number;\r\n /** Matched fields */\r\n matchedFields: string[];\r\n /** Highlighted name */\r\n highlightedName?: string;\r\n /** Matched keywords */\r\n matchedKeywords?: string[];\r\n}\r\n\r\n/**\r\n * Search facets for filtering.\r\n */\r\nexport interface IconSearchFacets {\r\n /** Category counts */\r\n categories: Record<IconCategory, number>;\r\n /** Domain counts */\r\n domains: Record<DomainCategory, number>;\r\n /** Style counts */\r\n styles: Record<IconStyle, number>;\r\n /** Set counts */\r\n sets: Record<string, number>;\r\n}\r\n\r\n/**\r\n * Semantic search configuration (AI-powered).\r\n */\r\nexport interface SemanticSearchConfig {\r\n /** Enable semantic search */\r\n enabled: boolean;\r\n /** Embedding model */\r\n model: 'openai' | 'cohere' | 'local';\r\n /** Similarity threshold */\r\n threshold: number;\r\n /** Maximum results to re-rank */\r\n maxRerank: number;\r\n /** Cache embeddings */\r\n cacheEmbeddings: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// ICON EDITOR\r\n// =============================================================================\r\n\r\n/**\r\n * Icon editor configuration.\r\n */\r\nexport interface IconEditorConfig {\r\n /** Canvas size */\r\n canvasSize: number;\r\n /** Grid size */\r\n gridSize: number;\r\n /** Show grid */\r\n showGrid: boolean;\r\n /** Snap to grid */\r\n snapToGrid: boolean;\r\n /** Show guides */\r\n showGuides: boolean;\r\n /** Default stroke width */\r\n defaultStrokeWidth: number;\r\n /** Default fill color */\r\n defaultFill: string;\r\n /** Default stroke color */\r\n defaultStroke: string;\r\n /** Undo history limit */\r\n undoLimit: number;\r\n /** Auto-save interval (ms) */\r\n autoSaveInterval?: number;\r\n}\r\n\r\n/**\r\n * Icon editing operation.\r\n */\r\nexport interface IconEditOperation {\r\n /** Operation type */\r\n type: IconEditOperationType;\r\n /** Operation parameters */\r\n params: Record<string, unknown>;\r\n /** Timestamp */\r\n timestamp: string;\r\n}\r\n\r\n/**\r\n * Types of edit operations.\r\n */\r\nexport type IconEditOperationType =\r\n | 'add-path'\r\n | 'remove-path'\r\n | 'modify-path'\r\n | 'set-fill'\r\n | 'set-stroke'\r\n | 'transform'\r\n | 'flip-h'\r\n | 'flip-v'\r\n | 'rotate'\r\n | 'scale'\r\n | 'combine'\r\n | 'subtract'\r\n | 'intersect'\r\n | 'exclude'\r\n | 'simplify'\r\n | 'optimize';\r\n\r\n/**\r\n * Icon transformation.\r\n */\r\nexport interface IconTransform {\r\n /** Translation X */\r\n translateX: number;\r\n /** Translation Y */\r\n translateY: number;\r\n /** Scale X */\r\n scaleX: number;\r\n /** Scale Y */\r\n scaleY: number;\r\n /** Rotation in degrees */\r\n rotate: number;\r\n /** Rotation origin X */\r\n originX: number;\r\n /** Rotation origin Y */\r\n originY: number;\r\n /** Skew X */\r\n skewX: number;\r\n /** Skew Y */\r\n skewY: number;\r\n}\r\n\r\n/**\r\n * Color modification options.\r\n */\r\nexport interface IconColorOptions {\r\n /** Primary color */\r\n primary: string;\r\n /** Secondary color (for duotone) */\r\n secondary?: string;\r\n /** Background color */\r\n background?: string;\r\n /** Opacity */\r\n opacity: number;\r\n /** Color mode */\r\n colorMode: 'single' | 'gradient' | 'duotone';\r\n /** Gradient configuration */\r\n gradient?: IconGradient;\r\n}\r\n\r\n/**\r\n * Gradient configuration for icons.\r\n */\r\nexport interface IconGradient {\r\n /** Gradient type */\r\n type: 'linear' | 'radial';\r\n /** Gradient angle (for linear) */\r\n angle?: number;\r\n /** Gradient stops */\r\n stops: GradientStop[];\r\n /** Center X (for radial) */\r\n cx?: number;\r\n /** Center Y (for radial) */\r\n cy?: number;\r\n /** Radius (for radial) */\r\n r?: number;\r\n}\r\n\r\n/**\r\n * Gradient color stop.\r\n */\r\nexport interface GradientStop {\r\n /** Offset (0-1) */\r\n offset: number;\r\n /** Color */\r\n color: string;\r\n /** Opacity */\r\n opacity?: number;\r\n}\r\n\r\n/**\r\n * Icon combination/composition.\r\n */\r\nexport interface IconComposition {\r\n /** Base icon */\r\n base: IconDefinition;\r\n /** Overlay icon (badge) */\r\n overlay?: IconDefinition;\r\n /** Overlay position */\r\n overlayPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'center';\r\n /** Overlay scale */\r\n overlayScale?: number;\r\n /** Overlay offset */\r\n overlayOffset?: { x: number; y: number };\r\n /** Whether to create cutout for overlay */\r\n cutout?: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// ICON SET CREATOR\r\n// =============================================================================\r\n\r\n/**\r\n * Icon set creation configuration.\r\n */\r\nexport interface IconSetCreatorConfig {\r\n /** Set name */\r\n name: string;\r\n /** Set prefix */\r\n prefix: string;\r\n /** Selected icons */\r\n icons: string[];\r\n /** Custom naming rules */\r\n naming: IconNamingConfig;\r\n /** Export configuration */\r\n export: IconSetExportConfig;\r\n /** Include metadata */\r\n includeMetadata: boolean;\r\n /** Tree-shaking support */\r\n treeShakeable: boolean;\r\n}\r\n\r\n/**\r\n * Naming configuration for icon sets.\r\n */\r\nexport interface IconNamingConfig {\r\n /** Case style */\r\n caseStyle: 'camelCase' | 'PascalCase' | 'kebab-case' | 'snake_case';\r\n /** Prefix to add */\r\n prefix?: string;\r\n /** Suffix to add */\r\n suffix?: string;\r\n /** Word replacements */\r\n replacements?: Record<string, string>;\r\n /** Remove words */\r\n removeWords?: string[];\r\n}\r\n\r\n/**\r\n * Icon set export configuration.\r\n */\r\nexport interface IconSetExportConfig {\r\n /** Export formats */\r\n formats: IconExportFormat[];\r\n /** Output directory */\r\n outputDir: string;\r\n /** Generate index file */\r\n generateIndex: boolean;\r\n /** Generate TypeScript types */\r\n generateTypes: boolean;\r\n /** Generate CSS */\r\n generateCSS: boolean;\r\n /** Generate icon font */\r\n generateFont: boolean;\r\n /** Font configuration */\r\n fontConfig?: IconFontConfig;\r\n /** Sprite configuration */\r\n spriteConfig?: IconSpriteConfig;\r\n}\r\n\r\n/**\r\n * Icon export formats.\r\n */\r\nexport type IconExportFormat =\r\n | 'svg'\r\n | 'png'\r\n | 'webp'\r\n | 'ico'\r\n | 'icns'\r\n | 'pdf'\r\n | 'jsx'\r\n | 'tsx'\r\n | 'vue'\r\n | 'svelte'\r\n | 'json'\r\n | 'css'\r\n | 'scss'\r\n | 'woff2'\r\n | 'ttf';\r\n\r\n/**\r\n * Icon font generation configuration.\r\n */\r\nexport interface IconFontConfig {\r\n /** Font family name */\r\n fontName: string;\r\n /** Class prefix */\r\n classPrefix: string;\r\n /** Unicode starting point */\r\n unicodeStart: number;\r\n /** Font formats to generate */\r\n formats: ('woff2' | 'woff' | 'ttf' | 'eot' | 'svg')[];\r\n /** Normalize icon sizes */\r\n normalize: boolean;\r\n /** Center icons */\r\n centerHorizontally: boolean;\r\n centerVertically: boolean;\r\n /** Font height */\r\n fontHeight: number;\r\n /** Descent */\r\n descent: number;\r\n /** Round values */\r\n round: number;\r\n}\r\n\r\n/**\r\n * SVG sprite configuration.\r\n */\r\nexport interface IconSpriteConfig {\r\n /** Sprite filename */\r\n filename: string;\r\n /** Symbol mode (versus inline) */\r\n symbolMode: boolean;\r\n /** Include style element */\r\n includeStyle: boolean;\r\n /** Namespace prefix */\r\n symbolPrefix: string;\r\n}\r\n\r\n// =============================================================================\r\n// ICON PREVIEW\r\n// =============================================================================\r\n\r\n/**\r\n * Icon preview configuration.\r\n */\r\nexport interface IconPreviewConfig {\r\n /** Preview sizes */\r\n sizes: IconSizePixels[];\r\n /** Show in both themes */\r\n showBothThemes: boolean;\r\n /** Background options */\r\n backgrounds: PreviewBackground[];\r\n /** Show grid */\r\n showGrid: boolean;\r\n /** Grid color */\r\n gridColor: string;\r\n /** Animation preview */\r\n animationPreview: boolean;\r\n /** Compare mode */\r\n compareMode: boolean;\r\n /** Compare icons */\r\n compareIcons?: string[];\r\n}\r\n\r\n/**\r\n * Preview background options.\r\n */\r\nexport interface PreviewBackground {\r\n /** Background name */\r\n name: string;\r\n /** Background color or image */\r\n value: string;\r\n /** Whether it's a pattern */\r\n isPattern?: boolean;\r\n /** Contrast for icon color suggestion */\r\n suggestedIconColor?: string;\r\n}\r\n\r\n/**\r\n * Animation preview configuration.\r\n */\r\nexport interface IconAnimationPreview {\r\n /** Animation type */\r\n type: IconAnimationType;\r\n /** Duration in ms */\r\n duration: number;\r\n /** Easing function */\r\n easing: string;\r\n /** Iteration count */\r\n iterations: number | 'infinite';\r\n /** Direction */\r\n direction: 'normal' | 'reverse' | 'alternate' | 'alternate-reverse';\r\n /** Delay in ms */\r\n delay: number;\r\n}\r\n\r\n/**\r\n * Icon animation types.\r\n */\r\nexport type IconAnimationType =\r\n | 'spin'\r\n | 'pulse'\r\n | 'bounce'\r\n | 'shake'\r\n | 'flip'\r\n | 'beat'\r\n | 'fade'\r\n | 'beat-fade'\r\n | 'spin-pulse'\r\n | 'custom';\r\n\r\n// =============================================================================\r\n// FAVICON GENERATOR\r\n// =============================================================================\r\n\r\n/**\r\n * Favicon generation configuration.\r\n */\r\nexport interface FaviconGeneratorConfig {\r\n /** Source icon */\r\n sourceIcon: IconDefinition | string; // icon ID or definition\r\n /** App name */\r\n appName: string;\r\n /** Short name */\r\n shortName: string;\r\n /** Theme color */\r\n themeColor: string;\r\n /** Background color */\r\n backgroundColor: string;\r\n /** Display mode */\r\n display: 'standalone' | 'fullscreen' | 'minimal-ui' | 'browser';\r\n /** Orientation */\r\n orientation: 'any' | 'portrait' | 'landscape';\r\n /** Start URL */\r\n startUrl: string;\r\n /** Sizes to generate */\r\n sizes: FaviconSize[];\r\n /** Generate manifest.json */\r\n generateManifest: boolean;\r\n /** Generate browserconfig.xml (Windows) */\r\n generateBrowserConfig: boolean;\r\n /** Output configuration */\r\n output: FaviconOutputConfig;\r\n}\r\n\r\n/**\r\n * Favicon sizes to generate.\r\n */\r\nexport interface FaviconSize {\r\n /** Width */\r\n width: number;\r\n /** Height */\r\n height: number;\r\n /** Purpose */\r\n purpose: 'any' | 'maskable' | 'monochrome' | 'favicon' | 'apple-touch';\r\n /** Filename */\r\n filename?: string;\r\n /** Format */\r\n format: 'png' | 'ico' | 'svg';\r\n}\r\n\r\n/**\r\n * Standard favicon sizes.\r\n */\r\nexport const STANDARD_FAVICON_SIZES: FaviconSize[] = [\r\n { width: 16, height: 16, purpose: 'favicon', format: 'ico' },\r\n { width: 32, height: 32, purpose: 'favicon', format: 'png' },\r\n { width: 48, height: 48, purpose: 'favicon', format: 'png' },\r\n { width: 180, height: 180, purpose: 'apple-touch', format: 'png' },\r\n { width: 192, height: 192, purpose: 'any', format: 'png' },\r\n { width: 512, height: 512, purpose: 'any', format: 'png' },\r\n { width: 512, height: 512, purpose: 'maskable', format: 'png' },\r\n];\r\n\r\n/**\r\n * Favicon output configuration.\r\n */\r\nexport interface FaviconOutputConfig {\r\n /** Output directory */\r\n outputDir: string;\r\n /** Base path for URLs */\r\n basePath: string;\r\n /** Generate HTML link tags */\r\n generateHtml: boolean;\r\n /** Generate meta tags */\r\n generateMeta: boolean;\r\n}\r\n\r\n/**\r\n * Generated favicon result.\r\n */\r\nexport interface FaviconGenerationResult {\r\n /** Generated files */\r\n files: GeneratedFile[];\r\n /** HTML to include */\r\n html: string;\r\n /** manifest.json content */\r\n manifest?: Record<string, unknown>;\r\n /** browserconfig.xml content */\r\n browserConfig?: string;\r\n}\r\n\r\n/**\r\n * Generated file information.\r\n */\r\nexport interface GeneratedFile {\r\n /** Filename */\r\n filename: string;\r\n /** File path */\r\n path: string;\r\n /** File size in bytes */\r\n size: number;\r\n /** MIME type */\r\n mimeType: string;\r\n /** Dimensions if image */\r\n dimensions?: { width: number; height: number };\r\n}\r\n\r\n// =============================================================================\r\n// CROSS-FRAMEWORK SUPPORT\r\n// =============================================================================\r\n\r\n/**\r\n * Framework-specific icon component configuration.\r\n */\r\nexport interface FrameworkIconConfig {\r\n /** Component name */\r\n componentName: string;\r\n /** File extension */\r\n fileExtension: string;\r\n /** Import style */\r\n importStyle: 'named' | 'default' | 'namespace';\r\n /** Props interface name */\r\n propsInterfaceName: string;\r\n /** Supports tree-shaking */\r\n treeShakeable: boolean;\r\n /** SSR support */\r\n ssrSupport: boolean;\r\n /** TypeScript support */\r\n typeScriptSupport: boolean;\r\n}\r\n\r\n/**\r\n * React icon component props.\r\n */\r\nexport interface ReactIconProps {\r\n /** Icon size */\r\n size?: IconSize | number;\r\n /** Icon color */\r\n color?: string;\r\n /** Additional class names */\r\n className?: string;\r\n /** Inline styles */\r\n style?: React.CSSProperties;\r\n /** Title for accessibility */\r\n title?: string;\r\n /** Description for accessibility */\r\n desc?: string;\r\n /** Whether icon is decorative (aria-hidden) */\r\n decorative?: boolean;\r\n /** Animation */\r\n animation?: IconAnimationType;\r\n /** Animation duration */\r\n animationDuration?: number;\r\n /** onClick handler */\r\n onClick?: (event: React.MouseEvent) => void;\r\n}\r\n\r\n/**\r\n * Vue icon component props.\r\n */\r\nexport interface VueIconProps {\r\n /** Icon size */\r\n size?: IconSize | number;\r\n /** Icon color */\r\n color?: string;\r\n /** Additional class names */\r\n class?: string;\r\n /** Title for accessibility */\r\n title?: string;\r\n /** Animation */\r\n animation?: IconAnimationType;\r\n}\r\n\r\n/**\r\n * Angular icon component inputs.\r\n */\r\nexport interface AngularIconInputs {\r\n /** Icon name */\r\n name: string;\r\n /** Icon size */\r\n size: IconSize | number;\r\n /** Icon color */\r\n color: string;\r\n /** Title for accessibility */\r\n title: string;\r\n /** Animation */\r\n animation: IconAnimationType;\r\n}\r\n\r\n/**\r\n * Web Component (Lit) icon properties.\r\n */\r\nexport interface WebComponentIconProps {\r\n /** Icon name */\r\n name: string;\r\n /** Icon size */\r\n size: IconSize | number;\r\n /** Icon color */\r\n color: string;\r\n /** Title for accessibility */\r\n title: string;\r\n}\r\n\r\n/**\r\n * Blazor icon parameters.\r\n */\r\nexport interface BlazorIconParameters {\r\n /** Icon name */\r\n Name: string;\r\n /** Icon size */\r\n Size: IconSize | number;\r\n /** Icon color */\r\n Color: string;\r\n /** CSS class */\r\n CssClass: string;\r\n /** Title for accessibility */\r\n Title: string;\r\n}\r\n\r\n/**\r\n * Flutter IconData equivalent.\r\n */\r\nexport interface FlutterIconData {\r\n /** Codepoint */\r\n codePoint: number;\r\n /** Font family */\r\n fontFamily: string;\r\n /** Font package */\r\n fontPackage: string;\r\n /** Match text direction */\r\n matchTextDirection: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// DESIGN TOOL INTEGRATION\r\n// =============================================================================\r\n\r\n/**\r\n * Figma plugin configuration.\r\n */\r\nexport interface FigmaPluginConfig {\r\n /** Plugin ID */\r\n pluginId: string;\r\n /** Sync configuration */\r\n sync: FigmaSyncConfig;\r\n /** Insert options */\r\n insertOptions: FigmaInsertOptions;\r\n}\r\n\r\n/**\r\n * Figma sync configuration.\r\n */\r\nexport interface FigmaSyncConfig {\r\n /** Auto-sync enabled */\r\n autoSync: boolean;\r\n /** Sync interval in minutes */\r\n syncInterval: number;\r\n /** Which collections to sync */\r\n collections: string[];\r\n /** Sync direction */\r\n direction: 'push' | 'pull' | 'both';\r\n}\r\n\r\n/**\r\n * Figma insert options.\r\n */\r\nexport interface FigmaInsertOptions {\r\n /** Insert as component */\r\n asComponent: boolean;\r\n /** Auto-layout */\r\n autoLayout: boolean;\r\n /** Default size */\r\n defaultSize: number;\r\n /** Maintain aspect ratio */\r\n maintainAspectRatio: boolean;\r\n}\r\n\r\n/**\r\n * Sketch plugin configuration.\r\n */\r\nexport interface SketchPluginConfig {\r\n /** Plugin identifier */\r\n identifier: string;\r\n /** Library configuration */\r\n library: SketchLibraryConfig;\r\n}\r\n\r\n/**\r\n * Sketch library configuration.\r\n */\r\nexport interface SketchLibraryConfig {\r\n /** Library name */\r\n name: string;\r\n /** Library path */\r\n path: string;\r\n /** Auto-update */\r\n autoUpdate: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// ICON ANALYTICS\r\n// =============================================================================\r\n\r\n/**\r\n * Icon analytics configuration.\r\n */\r\nexport interface IconAnalyticsConfig {\r\n /** Enable analytics */\r\n enabled: boolean;\r\n /** Track usage */\r\n trackUsage: boolean;\r\n /** Track searches */\r\n trackSearches: boolean;\r\n /** Retention days */\r\n retentionDays: number;\r\n /** Anonymize data */\r\n anonymize: boolean;\r\n}\r\n\r\n/**\r\n * Icon analytics dashboard data.\r\n */\r\nexport interface IconAnalyticsDashboard {\r\n /** Time period */\r\n period: { start: string; end: string };\r\n /** Total icons used */\r\n totalIconsUsed: number;\r\n /** Unique icons used */\r\n uniqueIconsUsed: number;\r\n /** Most used icons */\r\n mostUsed: IconUsageStats[];\r\n /** Least used icons */\r\n leastUsed: IconUsageStats[];\r\n /** Unused icons */\r\n unusedIcons: string[];\r\n /** Search analytics */\r\n searchAnalytics: SearchAnalytics;\r\n /** Missing icon requests */\r\n missingIconRequests: MissingIconRequest[];\r\n}\r\n\r\n/**\r\n * Search analytics data.\r\n */\r\nexport interface SearchAnalytics {\r\n /** Total searches */\r\n totalSearches: number;\r\n /** Unique queries */\r\n uniqueQueries: number;\r\n /** Top queries */\r\n topQueries: { query: string; count: number }[];\r\n /** Zero-result queries */\r\n zeroResultQueries: { query: string; count: number }[];\r\n /** Average results per search */\r\n avgResultsPerSearch: number;\r\n /** Click-through rate */\r\n clickThroughRate: number;\r\n}\r\n\r\n/**\r\n * Missing icon request.\r\n */\r\nexport interface MissingIconRequest {\r\n /** Requested icon name/description */\r\n request: string;\r\n /** Number of times requested */\r\n count: number;\r\n /** First requested date */\r\n firstRequested: string;\r\n /** Users who requested */\r\n userCount: number;\r\n /** Suggested alternatives */\r\n suggestedAlternatives?: string[];\r\n}\r\n\r\n// =============================================================================\r\n// CURSOR ICONS\r\n// =============================================================================\r\n\r\n/**\r\n * Cursor icon definition.\r\n */\r\nexport interface CursorIconDefinition extends IconDefinition {\r\n /** Cursor type */\r\n cursorType: CursorType;\r\n /** Hotspot X coordinate */\r\n hotspotX: number;\r\n /** Hotspot Y coordinate */\r\n hotspotY: number;\r\n /** Animation frames (for animated cursors) */\r\n frames?: CursorFrame[];\r\n /** Frame rate for animation */\r\n frameRate?: number;\r\n}\r\n\r\n/**\r\n * Standard cursor types.\r\n */\r\nexport type CursorType =\r\n | 'pointer'\r\n | 'crosshair'\r\n | 'move'\r\n | 'resize-n'\r\n | 'resize-s'\r\n | 'resize-e'\r\n | 'resize-w'\r\n | 'resize-ne'\r\n | 'resize-nw'\r\n | 'resize-se'\r\n | 'resize-sw'\r\n | 'resize-ns'\r\n | 'resize-ew'\r\n | 'resize-nesw'\r\n | 'resize-nwse'\r\n | 'text'\r\n | 'cell'\r\n | 'grab'\r\n | 'grabbing'\r\n | 'zoom-in'\r\n | 'zoom-out'\r\n | 'rotate'\r\n | 'draw'\r\n | 'brush'\r\n | 'eraser'\r\n | 'eyedropper'\r\n | 'bucket'\r\n | 'pen'\r\n | 'line'\r\n | 'rectangle'\r\n | 'ellipse'\r\n | 'wait'\r\n | 'progress'\r\n | 'not-allowed'\r\n | 'help'\r\n | 'context-menu'\r\n | 'custom';\r\n\r\n/**\r\n * Cursor animation frame.\r\n */\r\nexport interface CursorFrame {\r\n /** Frame icon/image */\r\n icon: IconDefinition;\r\n /** Frame duration in ms */\r\n duration: number;\r\n}\r\n\r\n// =============================================================================\r\n// HIGH-DPI / DESKTOP ICONS\r\n// =============================================================================\r\n\r\n/**\r\n * Desktop/high-DPI icon configuration.\r\n */\r\nexport interface DesktopIconConfig {\r\n /** Base icon */\r\n baseIcon: IconDefinition;\r\n /** Sizes to generate */\r\n sizes: IconSizePixels[];\r\n /** High-DPI scales */\r\n scales: (1 | 1.5 | 2 | 3 | 4)[];\r\n /** Platform-specific exports */\r\n platforms: DesktopIconPlatform[];\r\n}\r\n\r\n/**\r\n * Desktop platform targets.\r\n */\r\nexport interface DesktopIconPlatform {\r\n /** Platform name */\r\n platform: 'windows' | 'macos' | 'linux';\r\n /** Format */\r\n format: 'ico' | 'icns' | 'png';\r\n /** Sizes for this platform */\r\n sizes: IconSizePixels[];\r\n /** Output filename */\r\n filename: string;\r\n}\r\n\r\n/**\r\n * Windows ICO file generation.\r\n */\r\nexport interface WindowsIcoConfig {\r\n /** Sizes to include */\r\n sizes: (16 | 32 | 48 | 64 | 128 | 256)[];\r\n /** Include 256-color versions */\r\n include256Color: boolean;\r\n /** Compression */\r\n compress: boolean;\r\n}\r\n\r\n/**\r\n * macOS ICNS file generation.\r\n */\r\nexport interface MacOSIcnsConfig {\r\n /** Sizes to include */\r\n sizes: (16 | 32 | 64 | 128 | 256 | 512 | 1024)[];\r\n /** Include @2x versions */\r\n includeRetina: boolean;\r\n}\r\n\r\n// =============================================================================\r\n// THEMATIC ICON PACKAGES\r\n// =============================================================================\r\n\r\n/**\r\n * Thematic icon package definition.\r\n */\r\nexport interface ThematicIconPackage {\r\n /** Package name */\r\n name: string;\r\n /** npm package name */\r\n npmName: string;\r\n /** Description */\r\n description: string;\r\n /** Total icon count */\r\n iconCount: number;\r\n /** Categories included */\r\n categories: string[];\r\n /** Domains covered */\r\n domains: DomainCategory[];\r\n /** Dependencies on other packages */\r\n dependencies: string[];\r\n /** Version */\r\n version: string;\r\n}\r\n\r\n/**\r\n * Available thematic packages.\r\n */\r\nexport const THEMATIC_PACKAGES: ThematicIconPackage[] = [\r\n {\r\n name: 'Business Icons',\r\n npmName: '@nice2dev/icons-business',\r\n description: 'All ERP-related icons for business applications',\r\n iconCount: 500,\r\n categories: ['accounting', 'hr', 'crm', 'production', 'warehouse', 'sales', 'purchasing'],\r\n domains: ['business', 'finance', 'hr', 'logistics'],\r\n dependencies: [],\r\n version: '1.0.0',\r\n },\r\n {\r\n name: 'Education Icons',\r\n npmName: '@nice2dev/icons-education',\r\n description: 'Educational, scientific, and mathematical icons',\r\n iconCount: 300,\r\n categories: ['subjects', 'learning', 'school', 'science', 'math'],\r\n domains: ['education', 'science'],\r\n dependencies: [],\r\n version: '1.0.0',\r\n },\r\n {\r\n name: 'Tech Icons',\r\n npmName: '@nice2dev/icons-tech',\r\n description: 'Development tools, infrastructure, cloud, and containers',\r\n iconCount: 400,\r\n categories: ['devtools', 'infrastructure', 'cloud', 'containers', 'networking'],\r\n domains: ['technology'],\r\n dependencies: [],\r\n version: '1.0.0',\r\n },\r\n {\r\n name: 'Media Icons',\r\n npmName: '@nice2dev/icons-media',\r\n description: 'Audio, video, graphics, 3D, and streaming icons',\r\n iconCount: 350,\r\n categories: ['audio', 'video', 'graphics', '3d', 'streaming'],\r\n domains: ['creative'],\r\n dependencies: [],\r\n version: '1.0.0',\r\n },\r\n {\r\n name: 'Social Icons',\r\n npmName: '@nice2dev/icons-social',\r\n description: 'Social platforms, reactions, and messaging icons',\r\n iconCount: 200,\r\n categories: ['platforms', 'reactions', 'messaging'],\r\n domains: [],\r\n dependencies: [],\r\n version: '1.0.0',\r\n },\r\n {\r\n name: 'Game Icons',\r\n npmName: '@nice2dev/icons-game',\r\n description: 'Characters, items, UI elements, and game actions',\r\n iconCount: 400,\r\n categories: ['characters', 'items', 'ui', 'actions'],\r\n domains: ['gaming'],\r\n dependencies: [],\r\n version: '1.0.0',\r\n },\r\n {\r\n name: 'Life Management Icons',\r\n npmName: '@nice2dev/icons-life',\r\n description: 'Personal finance, health, productivity, and home icons',\r\n iconCount: 300,\r\n categories: ['finance', 'health', 'productivity', 'home', 'family'],\r\n domains: ['life-management'],\r\n dependencies: [],\r\n version: '1.0.0',\r\n },\r\n {\r\n name: 'All Icons',\r\n npmName: '@nice2dev/icons-all',\r\n description: 'Meta-package containing all icon packs',\r\n iconCount: 2500,\r\n categories: [],\r\n domains: [],\r\n dependencies: [\r\n '@nice2dev/icons-business',\r\n '@nice2dev/icons-education',\r\n '@nice2dev/icons-tech',\r\n '@nice2dev/icons-media',\r\n '@nice2dev/icons-social',\r\n '@nice2dev/icons-game',\r\n '@nice2dev/icons-life',\r\n ],\r\n version: '1.0.0',\r\n },\r\n];\r\n"],"names":["OPENAPI_LINT_RULES","formatBytes","bytes","decimals","k","dm","sizes","i","formatSpeed","bytesPerSecond","unit","value","formatDuration","seconds","hours","minutes","secs","calculateETA","remainingBytes","speedBytesPerSecond","parseDownloadUrl","url","parseMagnetLink","parsed","filename","extension","_a","protocol","getFileType","magnetUrl","params","infoHash","displayName","trackers","exactLength","keywords","types","type","extensions","generateDownloadId","validateChecksum","data","checksum","algorithm","hashBuffer","b","createDownloadSegments","totalSize","segmentCount","segmentSize","segments","start","end","DownloadManager","config","event","callback","listeners","error","options","id","download","urls","deleteFile","items","sum","d","totalDownloaded","status","category","abortController","controller","priority","direction","index","updates","limit","max","downloads","downloaded","total","totalSpeed","signal","response","contentLength","reader","_b","chunks","lastUpdate","bytesInInterval","done","now","elapsed","speed","offset","chunk","blob","a","auth","samples","queued","priorityOrder","downloadManagerInstance","getDownloadManager","disposeDownloadManager","useDownloadManager","autoRefresh","refreshInterval","manager","useMemo","queue","setQueue","useState","stats","setStats","useEffect","handleQueueChange","unsubscribers","interval","unsub","activeDownloads","addDownload","useCallback","opts","addDownloads","generateInfoHash","chars","hash","generatePeerId","clientId","randomPart","parseMagnetUri","magnetUri","xt","createMagnetUri","torrent","tracker","calculatePieces","pieceSize","createPieceStatus","pieceCount","formatPeerCount","connected","calculateTorrentHealth","seeders","leechers","ratio","createFileSelection","files","f","filterFilesByExtension","ext","getVideoFiles","getAudioFiles","getLargestFile","largest","file","TorrentClient","magnetInfo","v","deleteData","fileIndex","wanted","enabled","torrents","totalDownload","totalUpload","downloadSpeedSum","uploadSpeedSum","totalPeers","t","baseSpeed","downloadSpeed","increment","uploadSpeed","createTorrent","name","comment","isPrivate","webSeeds","magnetLink","torrentFile","torrentClientInstance","getTorrentClient","disposeTorrentClient","useTorrentClient","client","setTorrents","statistics","setStatistics","handleUpdate","activeTorrents","uri","del","idx","w","en","lim","DEFAULT_TRACELESS_POLICY","DEFAULT_FULL_POLICY","MODE_CAPABILITIES","WCAG_AA_CONTRAST","WCAG_AAA_CONTRAST","DEFAULT_ACCESSIBILITY_CONFIG","COMMON_LOCALES","RTL_LOCALES","STANDARD_FAVICON_SIZES","THEMATIC_PACKAGES"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8CA42DaA,IAA4D;AAAA,EACvE,yBAAyB;AAAA,IACvB,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA,EAAA;AAAA,EAEX,yBAAyB;AAAA,IACvB,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA,EAAA;AAAA,EAEX,gBAAgB;AAAA,IACd,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA,EAAA;AAAA,EAEX,oBAAoB;AAAA,IAClB,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA,EAAA;AAAA,EAEX,eAAe;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA,EAAA;AAEb;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC92DO,SAASC,GAAYC,GAAeC,IAAW,GAAW;AAC/D,MAAID,MAAU;AACZ,WAAO;AAET,QAAME,IAAI,MACJC,IAAKF,IAAW,IAAI,IAAIA,GACxBG,IAAQ,CAAC,KAAK,MAAM,MAAM,MAAM,MAAM,IAAI,GAC1CC,IAAI,KAAK,MAAM,KAAK,IAAIL,CAAK,IAAI,KAAK,IAAIE,CAAC,CAAC;AAClD,SAAO,YAAYF,IAAQ,KAAK,IAAIE,GAAGG,CAAC,GAAG,QAAQF,CAAE,CAAC,IAAI,MAAMC,EAAMC,CAAC;AACzE;AAKO,SAASC,EAAYC,GAAuC;AAEjE,MAAIC,IAAqC,OACrCC,IAAQF;AAEZ,SAAIA,KAAkB,OAAI,OAAI,QAC5BC,IAAO,QACPC,IAAQF,KAAkB,OAAI,OAAI,SACzBA,KAAkB,OAAI,QAC/BC,IAAO,QACPC,IAAQF,KAAkB,OAAI,SACrBA,KAAkB,SAC3BC,IAAO,QACPC,IAAQF,IAAiB,OAGpB;AAAA,IACL,gBAAAA;AAAA,IACA,cAAcE,EAAM,QAAQ,CAAC;AAAA,IAC7B,aAAaD;AAAA,EAAA;AAEjB;AAKO,SAASE,GAAeC,GAAyB;AACtD,MAAI,CAAC,SAASA,CAAO,KAAKA,IAAU;AAClC,WAAO;AAGT,QAAMC,IAAQ,KAAK,MAAMD,IAAU,IAAI,GACjCE,IAAU,KAAK,MAAOF,IAAU,OAAQ,EAAE,GAC1CG,IAAO,KAAK,MAAMH,IAAU,EAAE;AAEpC,SAAIC,IAAQ,IACH,GAAGA,CAAK,KAAKC,CAAO,MAClBA,IAAU,IACZ,GAAGA,CAAO,KAAKC,CAAI,MAErB,GAAGA,CAAI;AAChB;AAKO,SAASC,EACdC,GACAC,GACoB;AACpB,MAAI,EAAAA,KAAuB;AAG3B,WAAO,KAAK,KAAKD,IAAiBC,CAAmB;AACvD;AAKO,SAASC,EAAiBC,GAA6B;;AAE5D,MAAIA,EAAI,WAAW,SAAS;AAC1B,WAAOC,EAAgBD,CAAG;AAG5B,MAAI;AACF,UAAME,IAAS,IAAI,IAAIF,CAAG,GAEpBG,IADW,mBAAmBD,EAAO,QAAQ,EACzB,MAAM,GAAG,EAAE,SAAS,YACxCE,IAAYD,EAAS,SAAS,GAAG,KAAIE,IAAAF,EAAS,MAAM,GAAG,EAAE,IAAA,MAApB,gBAAAE,EAA2B,gBAAgB;AAEtF,QAAIC,IAA6B;AACjC,WAAIJ,EAAO,aAAa,UACtBI,IAAW,SACFJ,EAAO,aAAa,SAC7BI,IAAW,QACFJ,EAAO,aAAa,YAC7BI,IAAW,SAGN;AAAA,MACL,KAAAN;AAAA,MACA,UAAAM;AAAA,MACA,MAAMJ,EAAO;AAAA,MACb,UAAAC;AAAA,MACA,WAAAC;AAAA,MACA,UAAUA,IAAYG,EAAYH,CAAS,IAAI;AAAA,MAC/C,WAAWE,MAAa,WAAWA,MAAa;AAAA;AAAA,MAChD,cAAc,CAAC,CAACJ,EAAO;AAAA,MACvB,UAAU;AAAA,MACV,YAAY;AAAA,IAAA;AAAA,EAEhB,QAAQ;AACN,WAAO;AAAA,MACL,KAAAF;AAAA,MACA,UAAU;AAAA,MACV,MAAM;AAAA,MACN,UAAU;AAAA,MACV,WAAW;AAAA,MACX,UAAU;AAAA,MACV,YAAY;AAAA,IAAA;AAAA,EAEhB;AACF;AAKO,SAASC,EAAgBO,GAAmC;;AACjE,QAAMC,IAAS,IAAI,gBAAgBD,EAAU,QAAQ,YAAY,EAAE,CAAC,GAE9DE,KADKD,EAAO,IAAI,IAAI,KAAK,IACX,QAAQ,aAAa,EAAE,GACrCE,IAAcF,EAAO,IAAI,IAAI,KAAK,mBAClCG,IAAWH,EAAO,OAAO,IAAI,GAC7BI,IAAcJ,EAAO,IAAI,IAAI,IAAI,SAASA,EAAO,IAAI,IAAI,GAAI,EAAE,IAAI,QACnEK,MAAWT,IAAAI,EAAO,IAAI,IAAI,MAAf,gBAAAJ,EAAkB,MAAM,SAAQ,CAAA;AAUjD,SAAO;AAAA,IACL,KAAKG;AAAA,IACL,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAUG;AAAA,IACV,MAAME;AAAA,IACN,WAAW;AAAA,IACX,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,YAjBiC;AAAA,MACjC,UAAAH;AAAA,MACA,aAAAC;AAAA,MACA,UAAAC;AAAA,MACA,aAAAC;AAAA,MACA,UAAAC;AAAA,IAAA;AAAA,EAYA;AAEJ;AAKO,SAASP,EAAYH,GAA2B;AACrD,QAAMW,IAAkC;AAAA,IACtC,OAAO,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,QAAQ,OAAO,QAAQ,OAAO,KAAK;AAAA,IACrF,OAAO,CAAC,OAAO,QAAQ,OAAO,OAAO,OAAO,OAAO,OAAO,QAAQ,MAAM;AAAA,IACxE,OAAO,CAAC,OAAO,QAAQ,OAAO,OAAO,OAAO,OAAO,QAAQ,OAAO,QAAQ,KAAK;AAAA,IAC/E,UAAU,CAAC,OAAO,OAAO,QAAQ,OAAO,QAAQ,OAAO,QAAQ,OAAO,OAAO,KAAK;AAAA,IAClF,SAAS,CAAC,OAAO,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,KAAK;AAAA,IAC7D,YAAY,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAAA,IAC5D,MAAM,CAAC,MAAM,MAAM,MAAM,QAAQ,OAAO,KAAK,MAAM,MAAM,MAAM,MAAM,KAAK;AAAA,EAAA;AAG5E,aAAW,CAACC,GAAMC,CAAU,KAAK,OAAO,QAAQF,CAAK;AACnD,QAAIE,EAAW,SAASb,EAAU,YAAA,CAAa;AAC7C,aAAOY;AAGX,SAAO;AACT;AAKO,SAASE,IAA6B;AAC3C,SAAO,MAAM,KAAK,IAAA,EAAM,SAAS,EAAE,CAAC,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,UAAU,GAAG,CAAC,CAAC;AACpF;AAKA,eAAsBC,EACpBC,GACAC,GACkB;AAClB,MAAI,OAAO,SAAW,OAAe,CAAC,OAAO;AAC3C,mBAAQ,KAAK,sDAAsD,GAC5D;AAST,QAAMC,IANuC;AAAA,IAC3C,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,EAAA,EAGuBD,EAAS,SAAS;AACjD,MAAI,CAACC;AACH,mBAAQ,KAAK,mCAAmCD,EAAS,SAAS,EAAE,GAC7D;AAGT,QAAME,IAAa,MAAM,OAAO,OAAO,OAAOD,GAAWF,CAAI;AAI7D,SAHkB,MAAM,KAAK,IAAI,WAAWG,CAAU,CAAC,EAC7B,IAAI,CAACC,MAAMA,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE,EAE9D,YAAA,MAAkBH,EAAS,MAAM,YAAA;AAClD;AAkBO,SAASI,GAAuBC,GAAmBC,GAAyC;AACjG,MAAID,KAAa,KAAKC,KAAgB;AACpC,WAAO,CAAA;AAGT,QAAMC,IAAc,KAAK,KAAKF,IAAYC,CAAY,GAChDE,IAA8B,CAAA;AAEpC,WAAS3C,IAAI,GAAGA,IAAIyC,GAAczC,KAAK;AACrC,UAAM4C,IAAQ5C,IAAI0C,GACZG,IAAM,KAAK,IAAID,IAAQF,IAAc,GAAGF,IAAY,CAAC;AAE3D,IAAAG,EAAS,KAAK;AAAA,MACZ,OAAO3C;AAAA,MACP,OAAA4C;AAAA,MACA,KAAAC;AAAA,MACA,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,SAAS;AAAA,IAAA,CACV;AAAA,EACH;AAEA,SAAOF;AACT;AA6BO,MAAMG,EAAgB;AAAA,EAS3B,YAAYC,IAAyC,IAAI;AAPzD,SAAQ,gCAA2C,IAAA,GACnD,KAAQ,sCAAmC,IAAA,GAC3C,KAAQ,uCAAqD,IAAA,GAC7D,KAAQ,mCAA0C,IAAA,GAClD,KAAQ,qCAAyE,IAAA,GACjF,KAAQ,iBAAwD,MAG9D,KAAK,SAAS;AAAA,MACZ,qBAAqBA,EAAO,uBAAuB;AAAA,MACnD,wBAAwBA,EAAO,0BAA0B;AAAA,MACzD,gBAAgBA,EAAO;AAAA,MACvB,eAAeA,EAAO,iBAAiB;AAAA,MACvC,YAAYA,EAAO,cAAc;AAAA,MACjC,WAAWA,EAAO,aAAa;AAAA,MAC/B,iBAAiBA,EAAO,mBAAmB;AAAA,MAC3C,YAAYA,EAAO,cAAc,CAAA;AAAA,MACjC,iBAAiBA,EAAO,mBAAmB,CAAA;AAAA,IAAC;AAAA,EAEhD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,GAAGC,GAA0BC,GAA6C;AACxE,WAAK,KAAK,eAAe,IAAID,CAAK,KAChC,KAAK,eAAe,IAAIA,GAAO,oBAAI,KAAK,GAE1C,KAAK,eAAe,IAAIA,CAAK,EAAG,IAAIC,CAAQ,GACrC,MAAA;;AAAM,cAAA9B,IAAA,KAAK,eAAe,IAAI6B,CAAK,MAA7B,gBAAA7B,EAAgC,OAAO8B;AAAA;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAKQ,KAAKD,GAA4B;AACvC,UAAME,IAAY,KAAK,eAAe,IAAIF,EAAM,IAAI;AACpD,QAAIE;AACF,iBAAWD,KAAYC;AACrB,YAAI;AACF,UAAAD,EAASD,CAAK;AAAA,QAChB,SAASG,GAAO;AACd,kBAAQ,MAAM,kCAAkCA,CAAK;AAAA,QACvD;AAAA,EAGN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,YACErC,GACAsC,IAQK,IACS;AACd,UAAMpC,IAASH,EAAiBC,CAAG,GAC7BuC,IAAKrB,EAAA,GAELsB,IAAyB;AAAA,MAC7B,IAAAD;AAAA,MACA,KAAAvC;AAAA,MACA,UAAUsC,EAAQ,YAAYpC,EAAO;AAAA,MACrC,MAAMoC,EAAQ,QAAQ,KAAK,OAAO;AAAA,MAClC,QAAQ;AAAA,MACR,UAAUA,EAAQ,YAAY;AAAA,MAC9B,MAAMpC,EAAO;AAAA,MACb,iBAAiB;AAAA,MACjB,UAAU;AAAA,MACV,OAAOf,EAAY,CAAC;AAAA,MACpB,+BAAe,KAAA;AAAA,MACf,YAAY;AAAA,MACZ,UAAUmD,EAAQ,YAAY,KAAK,eAAepC,EAAO,SAAS;AAAA,MAClE,QAAQ;AAAA,QACN,MAAMA,EAAO,WAAW,WAAW;AAAA,QACnC,UAAUA,EAAO;AAAA,QACjB,MAAMA,EAAO;AAAA,MAAA;AAAA,MAEf,UAAUoC,EAAQ;AAAA,IAAA;AAGpB,gBAAK,UAAU,IAAIC,GAAIC,CAAQ,GAC/B,KAAK,KAAK,EAAE,MAAM,SAAS,UAAAA,GAAU,GACrC,KAAK,iBAAA,IAIFF,EAAQ,aAAa,KAAK,OAAO,cAClC,KAAK,gBAAgB,OAAO,KAAK,OAAO,0BAExC,KAAK,cAAcC,CAAE,GAGhBC;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,aACEC,GACAH,IAKK,IACW;AAChB,WAAOG,EAAK,IAAI,CAACzC,MAAQ,KAAK,YAAYA,GAAKsC,CAAO,CAAC;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA,EAKA,eAAeC,GAAYG,IAAa,IAAgB;AAEtD,WADiB,KAAK,UAAU,IAAIH,CAAE,KAMtC,KAAK,eAAeA,CAAE,GAEtB,KAAK,UAAU,OAAOA,CAAE,GACxB,KAAK,iBAAA,GAGDG,KACF,QAAQ,KAAK,sDAAsD,GAG9D,MAdE;AAAA,EAeX;AAAA;AAAA;AAAA;AAAA,EAKA,YAAYH,GAAsC;AAChD,WAAO,KAAK,UAAU,IAAIA,CAAE;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkC;AAChC,WAAO,MAAM,KAAK,KAAK,UAAU,QAAQ;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,WAA0B;AACxB,UAAMI,IAAQ,KAAK,gBAAA,GACbjB,IAAYiB,EAAM,OAAO,CAACC,GAAKC,MAAMD,KAAOC,EAAE,QAAQ,IAAI,CAAC,GAC3DC,IAAkBH,EAAM,OAAO,CAACC,GAAKC,MAAMD,IAAMC,EAAE,iBAAiB,CAAC;AAE3E,WAAO;AAAA,MACL,OAAAF;AAAA,MACA,WAAAjB;AAAA,MACA,eAAeA,IAAY,IAAKoB,IAAkBpB,IAAa,MAAM;AAAA,MACrE,iBAAiB,KAAK,gBAAgB;AAAA,MACtC,iBAAiBiB,EAAM,OAAO,CAACE,MAAMA,EAAE,WAAW,QAAQ,EAAE;AAAA,MAC5D,oBAAoBF,EAAM,OAAO,CAACE,MAAMA,EAAE,WAAW,WAAW,EAAE;AAAA,IAAA;AAAA,EAEtE;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAqBE,GAAwC;AAC3D,WAAO,KAAK,kBAAkB,OAAO,CAACF,MAAMA,EAAE,WAAWE,CAAM;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA,EAKA,uBAAuBC,GAAkC;AACvD,WAAO,KAAK,kBAAkB,OAAO,CAACH,MAAMA,EAAE,aAAaG,CAAQ;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cAAcT,GAA2B;AAC7C,UAAMC,IAAW,KAAK,UAAU,IAAID,CAAE;AAKtC,QAJI,CAACC,KAIDA,EAAS,WAAW;AACtB;AAEF,QAAI,KAAK,gBAAgB,QAAQ,KAAK,OAAO,wBAAwB;AACnE,MAAAA,EAAS,SAAS;AAClB;AAAA,IACF;AAEA,IAAAA,EAAS,SAAS,eAClBA,EAAS,kCAAkB,KAAA,GAC3B,KAAK,gBAAgB,IAAID,CAAE;AAE3B,UAAMU,IAAkB,IAAI,gBAAA;AAC5B,SAAK,iBAAiB,IAAIV,GAAIU,CAAe,GAC7C,KAAK,aAAa,IAAIV,GAAI,CAAA,CAAE,GAE5B,KAAK,KAAK,EAAE,MAAM,WAAW,UAAAC,GAAU;AAEvC,QAAI;AACF,YAAM,KAAK,gBAAgBA,GAAUS,EAAgB,MAAM,GAE3DT,EAAS,SAAS,aAClBA,EAAS,oCAAoB,KAAA,GAC7BA,EAAS,WAAW,KACpB,KAAK,KAAK,EAAE,MAAM,aAAa,UAAAA,GAAU;AAAA,IAC3C,SAASH,GAAO;AACd,UAAIY,EAAgB,OAAO;AAEzB;AAGF,MAAAT,EAAS,eAAeH,aAAiB,QAAQA,EAAM,UAAU,mBAG7DG,EAAS,aAAa,KAAK,OAAO,iBACpCA,EAAS,cACTA,EAAS,SAAS,UAClB,WAAW,MAAM,KAAK,cAAcD,CAAE,GAAG,KAAK,OAAO,UAAU,MAE/DC,EAAS,SAAS,UAClB,KAAK,KAAK;AAAA,QACR,MAAM;AAAA,QACN,UAAAA;AAAA,QACA,OAAOH,aAAiB,QAAQA,IAAQ,IAAI,MAAM,OAAOA,CAAK,CAAC;AAAA,MAAA,CAChE;AAAA,IAEL,UAAA;AACE,WAAK,gBAAgB,OAAOE,CAAE,GAC9B,KAAK,iBAAiB,OAAOA,CAAE,GAC/B,KAAK,aAAa,OAAOA,CAAE,GAC3B,KAAK,iBAAA,GAGL,KAAK,aAAA;AAAA,IACP;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAAcA,GAAkB;AAC9B,UAAMC,IAAW,KAAK,UAAU,IAAID,CAAE;AACtC,QAAI,CAACC,KAAYA,EAAS,WAAW;AACnC;AAGF,UAAMU,IAAa,KAAK,iBAAiB,IAAIX,CAAE;AAC/C,IAAIW,KACFA,EAAW,MAAA,GAGbV,EAAS,SAAS,UAClB,KAAK,gBAAgB,OAAOD,CAAE,GAC9B,KAAK,KAAK,EAAE,MAAM,UAAU,UAAAC,GAAU,GACtC,KAAK,iBAAA,GAGL,KAAK,aAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKA,eAAeD,GAAkB;AAC/B,UAAMC,IAAW,KAAK,UAAU,IAAID,CAAE;AACtC,IAAI,CAACC,KAAYA,EAAS,WAAW,aAIrCA,EAAS,SAAS,UAClB,KAAK,KAAK,EAAE,MAAM,WAAW,UAAAA,GAAU,GACvC,KAAK,cAAcD,CAAE;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,eAAeA,GAAkB;AAC/B,UAAMC,IAAW,KAAK,UAAU,IAAID,CAAE;AACtC,QAAI,CAACC;AACH;AAGF,UAAMU,IAAa,KAAK,iBAAiB,IAAIX,CAAE;AAC/C,IAAIW,KACFA,EAAW,MAAA,GAGbV,EAAS,SAAS,aAClB,KAAK,gBAAgB,OAAOD,CAAE,GAC9B,KAAK,KAAK,EAAE,MAAM,aAAa,UAAAC,GAAU,GACzC,KAAK,iBAAA,GAEL,KAAK,aAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKA,WAAiB;AACf,eAAWD,KAAM,KAAK;AACpB,WAAK,cAAcA,CAAE;AAAA,EAEzB;AAAA;AAAA;AAAA;AAAA,EAKA,YAAkB;AAChB,eAAWC,KAAY,KAAK,UAAU,OAAA;AACpC,MAAIA,EAAS,WAAW,YACtB,KAAK,eAAeA,EAAS,EAAE;AAAA,EAGrC;AAAA;AAAA;AAAA;AAAA,EAKA,YAAkB;AAChB,eAAWD,KAAM,KAAK,UAAU,KAAA;AAC9B,WAAK,eAAeA,CAAE;AAAA,EAE1B;AAAA;AAAA;AAAA;AAAA,EAKA,YAAYA,GAAYY,GAAkC;AACxD,UAAMX,IAAW,KAAK,UAAU,IAAID,CAAE;AACtC,IAAIC,MACFA,EAAS,WAAWW,GACpB,KAAK,iBAAA;AAAA,EAET;AAAA;AAAA;AAAA;AAAA,EAKA,YAAYZ,GAAYa,GAAmD;AACzE,UAAMT,IAAQ,KAAK,kBAAkB,OAAO,CAACE,MAAMA,EAAE,WAAW,QAAQ,GAClEQ,IAAQV,EAAM,UAAU,CAACE,MAAMA,EAAE,OAAON,CAAE;AAChD,QAAIc,MAAU,IAKd;AAAA,cAAQD,GAAA;AAAA,QACN,KAAK;AACH,UAAAT,EAAMU,CAAK,EAAE,WAAW;AACxB;AAAA,QACF,KAAK;AACH,UAAIV,EAAMU,CAAK,EAAE,aAAa,WAC5BV,EAAMU,CAAK,EAAE,WAAW,SACfV,EAAMU,CAAK,EAAE,aAAa,UACnCV,EAAMU,CAAK,EAAE,WAAW;AAE1B;AAAA,QACF,KAAK;AACH,UAAIV,EAAMU,CAAK,EAAE,aAAa,WAC5BV,EAAMU,CAAK,EAAE,WAAW,QACfV,EAAMU,CAAK,EAAE,aAAa,WACnCV,EAAMU,CAAK,EAAE,WAAW;AAE1B;AAAA,QACF,KAAK;AACH,UAAAV,EAAMU,CAAK,EAAE,WAAW;AACxB;AAAA,MAAA;AAGJ,WAAK,iBAAA;AAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,YAAmC;AACjC,WAAO,EAAE,GAAG,KAAK,OAAA;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,aAAaC,GAA+C;AAC1D,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAGA,EAAA;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkBC,GAAyC;AACzD,SAAK,OAAO,iBAAiBA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,0BAA0BC,GAAmB;AAC3C,SAAK,OAAO,yBAAyBA,GACrC,KAAK,aAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKA,YAAYR,GAAkC;AAC5C,SAAK,OAAO,aAAa,CAAC,GAAI,KAAK,OAAO,cAAc,CAAA,GAAKA,CAAQ;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,WAA0B;AACxB,UAAMS,IAAY,KAAK,gBAAA,GACjBC,IAAaD,EAAU,OAAO,CAACb,GAAKC,MAAMD,IAAMC,EAAE,iBAAiB,CAAC,GACpEc,IAAQF,EAAU,OAAO,CAACb,GAAKC,MAAMD,KAAOC,EAAE,QAAQ,IAAI,CAAC;AAGjE,QAAIe,IAAa;AACjB,eAAWrB,KAAM,KAAK,iBAAiB;AACrC,YAAMC,IAAW,KAAK,UAAU,IAAID,CAAE;AACtC,MAAIC,MACFoB,KAAcpB,EAAS,MAAM;AAAA,IAEjC;AAEA,WAAO;AAAA,MACL,YAAAkB;AAAA,MACA,UAAU;AAAA,MACV,WAAWC,IAAQD;AAAA,MACnB,OAAAC;AAAA,MACA,UAAUA,IAAQ,IAAKD,IAAaC,IAAS,MAAM;AAAA,MACnD,eAAexE,EAAYyE,CAAU;AAAA,MACrC,aAAazE,EAAY,CAAC;AAAA,MAC1B,KAAKyE,IAAa,IAAIhE,EAAa+D,IAAQD,GAAYE,CAAU,IAAI;AAAA,IAAA;AAAA,EAEzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,gBAAgBpB,GAAwBqB,GAAoC;;AACxF,UAAMC,IAAW,MAAM,MAAMtB,EAAS,KAAK;AAAA,MACzC,QAAAqB;AAAA,MACA,UAASxD,IAAAmC,EAAS,WAAT,QAAAnC,EAAiB,OAAO,KAAK,iBAAiBmC,EAAS,OAAO,IAAI,IAAI;AAAA,IAAA,CAChF;AAED,QAAI,CAACsB,EAAS;AACZ,YAAM,IAAI,MAAM,QAAQA,EAAS,MAAM,KAAKA,EAAS,UAAU,EAAE;AAGnE,UAAMC,IAAgBD,EAAS,QAAQ,IAAI,gBAAgB;AAC3D,IAAIC,MACFvB,EAAS,OAAO,SAASuB,GAAe,EAAE;AAG5C,UAAMC,KAASC,IAAAH,EAAS,SAAT,gBAAAG,EAAe;AAC9B,QAAI,CAACD;AACH,YAAM,IAAI,MAAM,+BAA+B;AAGjD,UAAME,IAAuB,CAAA;AAC7B,QAAIC,IAAa,KAAK,IAAA,GAClBC,IAAkB;AAEtB,eAAa;AACX,YAAM,EAAE,MAAAC,GAAM,OAAA/E,EAAA,IAAU,MAAM0E,EAAO,KAAA;AAErC,UAAIK;AACF;AAGF,MAAAH,EAAO,KAAK5E,CAAK,GACjBkD,EAAS,mBAAmBlD,EAAM,QAClC8E,KAAmB9E,EAAM,QAGrBkD,EAAS,SACXA,EAAS,WAAYA,EAAS,kBAAkBA,EAAS,OAAQ;AAInE,YAAM8B,IAAM,KAAK,IAAA,GACXC,IAAUD,IAAMH;AACtB,UAAII,KAAW,KAAK;AAClB,cAAMC,IAASJ,IAAkBG,IAAW;AAC5C,aAAK,YAAY/B,EAAS,IAAIgC,CAAK,GACnChC,EAAS,QAAQrD,EAAYqF,CAAK,GAClChC,EAAS,MAAMA,EAAS,OACpB5C,EAAa4C,EAAS,OAAOA,EAAS,iBAAiBgC,CAAK,IAC5D,QAEJ,KAAK,KAAK,EAAE,MAAM,YAAY,UAAAhC,GAAU,GAExC2B,IAAaG,GACbF,IAAkB;AAAA,MACpB;AAAA,IACF;AAGA,UAAMhD,IAAO,IAAI,WAAWoB,EAAS,eAAe;AACpD,QAAIiC,IAAS;AACb,eAAWC,KAASR;AAClB,MAAA9C,EAAK,IAAIsD,GAAOD,CAAM,GACtBA,KAAUC,EAAM;AAGlB,QAAIlC,EAAS,UAAU;AAErB,UAAI,CADU,MAAMrB,EAAiBC,EAAK,QAAQoB,EAAS,QAAQ;AAEjE,cAAM,IAAI,MAAM,4BAA4B;AAE9C,MAAAA,EAAS,SAAS,WAAW;AAAA,IAC/B;AAIA,SAAK,uBAAuBA,GAAUpB,CAAI;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAAuBoB,GAAwBpB,GAAwB;AAE7E,QAAI,OAAO,SAAW,OAAe,OAAO,WAAa,KAAa;AACpE,YAAMuD,IAAO,IAAI,KAAK,CAAC,IAAI,WAAWvD,CAAI,CAAC,CAAC,GACtCpB,IAAM,IAAI,gBAAgB2E,CAAI,GAC9BC,IAAI,SAAS,cAAc,GAAG;AACpC,MAAAA,EAAE,OAAO5E,GACT4E,EAAE,WAAWpC,EAAS,UACtB,SAAS,KAAK,YAAYoC,CAAC,GAC3BA,EAAE,MAAA,GACF,SAAS,KAAK,YAAYA,CAAC,GAC3B,IAAI,gBAAgB5E,CAAG;AAAA,IACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAiB6E,GAAsD;AAC7E,QAAI,CAACA;AACH,aAAO,CAAA;AAGT,YAAQA,EAAK,MAAA;AAAA,MACX,KAAK;AAEH,eAAO,EAAE,eAAe,SADJ,KAAK,GAAGA,EAAK,QAAQ,IAAIA,EAAK,QAAQ,EAAE,CAChB,GAAA;AAAA,MAE9C,KAAK;AACH,eAAO,EAAE,eAAe,UAAUA,EAAK,KAAK,GAAA;AAAA,MAC9C,KAAK;AACH,eAAO,EAAE,aAAaA,EAAK,UAAU,GAAA;AAAA,MACvC;AACE,eAAO,CAAA;AAAA,IAAC;AAAA,EAEd;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAYtC,GAAYiC,GAAqB;AACnD,UAAMM,IAAU,KAAK,aAAa,IAAIvC,CAAE,KAAK,CAAA;AAC7C,IAAAuC,EAAQ,KAAKN,CAAK,GAGdM,EAAQ,SAAS,MACnBA,EAAQ,MAAA,GAGV,KAAK,aAAa,IAAIvC,GAAIuC,CAAO;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAqB;AAC3B,QAAI,KAAK,gBAAgB,QAAQ,KAAK,OAAO;AAC3C;AAIF,UAAMC,IAAS,KAAK,qBAAqB,QAAQ,EAAE,KAAK,CAACH,GAAGpD,MAAM;AAChE,YAAMwD,IAAgB,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,EAAA;AAC9D,aAAOA,EAAcJ,EAAE,QAAQ,IAAII,EAAcxD,EAAE,QAAQ;AAAA,IAC7D,CAAC;AAED,eAAWgB,KAAYuC,GAAQ;AAC7B,UAAI,KAAK,gBAAgB,QAAQ,KAAK,OAAO;AAC3C;AAEF,WAAK,cAAcvC,EAAS,EAAE;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAepC,GAAwC;;AAC7D,QAAI,GAACA,KAAa,CAAC,KAAK,OAAO;AAI/B,iBAAW4C,KAAY,KAAK,OAAO;AACjC,aAAI3C,IAAA2C,EAAS,cAAT,QAAA3C,EAAoB,SAASD,EAAU,YAAA;AACzC,iBAAO4C,EAAS;AAAA;AAAA,EAItB;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAyB;AAC/B,SAAK,KAAK,EAAE,MAAM,iBAAiB,OAAO,KAAK,SAAA,GAAY;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AACd,SAAK,UAAA,GACD,KAAK,kBACP,cAAc,KAAK,cAAc,GAEnC,KAAK,eAAe,MAAA,GACpB,KAAK,UAAU,MAAA;AAAA,EACjB;AACF;AAMA,IAAIiC,IAAkD;AAK/C,SAASC,EAAmBjD,GAA0D;AAC3F,SAAKgD,MACHA,IAA0B,IAAIjD,EAAgBC,CAAM,IAE/CgD;AACT;AAKO,SAASE,KAA+B;AAC7C,EAAAF,KAAA,QAAAA,EAAyB,WACzBA,IAA0B;AAC5B;AAsDO,SAASG,GACd9C,IAAqC,IACX;AAC1B,QAAM,EAAE,QAAAL,GAAQ,aAAAoD,IAAc,IAAM,iBAAAC,IAAkB,QAAShD,GAEzDiD,IAAUC,EAAQ,MAAMN,EAAmBjD,CAAM,GAAG,CAACA,CAAM,CAAC,GAE5D,CAACwD,GAAOC,CAAQ,IAAIC,EAAwBJ,EAAQ,UAAU,GAC9D,CAACK,GAAOC,CAAQ,IAAIF,EAAwBJ,EAAQ,UAAU;AAEpE,EAAAO,EAAU,MAAM;AACd,UAAMC,IAAoB,MAAM;AAC9B,MAAAL,EAASH,EAAQ,UAAU,GAC3BM,EAASN,EAAQ,UAAU;AAAA,IAC7B,GAEMS,IAAgB;AAAA,MACpBT,EAAQ,GAAG,SAASQ,CAAiB;AAAA,MACrCR,EAAQ,GAAG,WAAWQ,CAAiB;AAAA,MACvCR,EAAQ,GAAG,YAAYQ,CAAiB;AAAA,MACxCR,EAAQ,GAAG,UAAUQ,CAAiB;AAAA,MACtCR,EAAQ,GAAG,WAAWQ,CAAiB;AAAA,MACvCR,EAAQ,GAAG,aAAaQ,CAAiB;AAAA,MACzCR,EAAQ,GAAG,UAAUQ,CAAiB;AAAA,MACtCR,EAAQ,GAAG,aAAaQ,CAAiB;AAAA,MACzCR,EAAQ,GAAG,iBAAiBQ,CAAiB;AAAA,IAAA;AAI/C,QAAIE;AACJ,WAAIZ,MACFY,IAAW,YAAY,MAAM;AAC3B,MAAIV,EAAQ,WAAW,kBAAkB,KACvCQ,EAAA;AAAA,IAEJ,GAAGT,CAAe,IAGb,MAAM;AACX,MAAAU,EAAc,QAAQ,CAACE,MAAUA,EAAA,CAAO,GACpCD,KACF,cAAcA,CAAQ;AAAA,IAE1B;AAAA,EACF,GAAG,CAACV,GAASF,GAAaC,CAAe,CAAC;AAE1C,QAAMa,IAAkBX;AAAA,IACtB,MAAMC,EAAM,MAAM,OAAO,CAAC5C,MAAMA,EAAE,WAAW,aAAa;AAAA,IAC1D,CAAC4C,CAAK;AAAA,EAAA,GAGFW,IAAcC;AAAA,IAClB,CAACrG,GAAasG,MACZf,EAAQ,YAAYvF,GAAKsG,CAAI;AAAA,IAC/B,CAACf,CAAO;AAAA,EAAA,GAGJgB,IAAeF;AAAA,IACnB,CAAC5D,GAAgB6D,MACff,EAAQ,aAAa9C,GAAM6D,CAAI;AAAA,IACjC,CAACf,CAAO;AAAA,EAAA;AAGV,SAAO;AAAA,IACL,OAAAE;AAAA,IACA,OAAAG;AAAA,IACA,iBAAAO;AAAA,IACA,aAAAC;AAAA,IACA,cAAAG;AAAA,IACA,eAAeF,EAAY,CAAC9D,MAAOgD,EAAQ,cAAchD,CAAE,GAAG,CAACgD,CAAO,CAAC;AAAA,IACvE,eAAec,EAAY,CAAC9D,MAAOgD,EAAQ,cAAchD,CAAE,GAAG,CAACgD,CAAO,CAAC;AAAA,IACvE,gBAAgBc,EAAY,CAAC9D,MAAOgD,EAAQ,eAAehD,CAAE,GAAG,CAACgD,CAAO,CAAC;AAAA,IACzE,gBAAgBc,EAAY,CAAC9D,MAAOgD,EAAQ,eAAehD,CAAE,GAAG,CAACgD,CAAO,CAAC;AAAA,IACzE,gBAAgBc;AAAA,MACd,CAAC9D,GAAIG,MAAe6C,EAAQ,eAAehD,GAAIG,CAAU;AAAA,MACzD,CAAC6C,CAAO;AAAA,IAAA;AAAA,IAEV,UAAUc,EAAY,MAAMd,EAAQ,YAAY,CAACA,CAAO,CAAC;AAAA,IACzD,WAAWc,EAAY,MAAMd,EAAQ,aAAa,CAACA,CAAO,CAAC;AAAA,IAC3D,mBAAmBc,EAAY,CAAC9C,MAAUgC,EAAQ,kBAAkBhC,CAAK,GAAG,CAACgC,CAAO,CAAC;AAAA,IACrF,aAAac,EAAY,CAAC9D,GAAIY,MAAaoC,EAAQ,YAAYhD,GAAIY,CAAQ,GAAG,CAACoC,CAAO,CAAC;AAAA,EAAA;AAE3F;ACzlCO,SAASiB,IAA2B;AACzC,QAAMC,IAAQ;AACd,MAAIC,IAAO;AACX,WAASxH,IAAI,GAAGA,IAAI,IAAIA;AACtB,IAAAwH,KAAQD,EAAM,KAAK,MAAM,KAAK,WAAWA,EAAM,MAAM,CAAC;AAExD,SAAOC;AACT;AAKO,SAASC,IAAyB;AACvC,QAAMC,IAAW,YACXC,IAAa,MAAM;AAAA,IAAK,EAAE,QAAQ,GAAA;AAAA,IAAM,MAC5C,KAAK,MAAM,KAAK,OAAA,IAAW,GAAG,EAC3B,SAAS,EAAE,EACX,SAAS,GAAG,GAAG;AAAA,EAAA,EAClB,KAAK,EAAE;AACT,SAAOD,IAAWC;AACpB;AAKO,SAASC,EAAeC,GAA0C;;AACvE,MAAI,CAACA,EAAU,WAAW,UAAU;AAClC,WAAO;AAGT,QAAMtG,IAAS,IAAI,gBAAgBsG,EAAU,QAAQ,YAAY,EAAE,CAAC,GAE9DC,IAAKvG,EAAO,IAAI,IAAI;AAC1B,MAAI,CAACuG;AACH,WAAO;AAGT,QAAMtG,IAAWsG,EAAG,QAAQ,aAAa,EAAE,GACrCrG,IAAcF,EAAO,IAAI,IAAI,KAAK,QAClCG,IAAWH,EAAO,OAAO,IAAI,GAC7BI,IAAcJ,EAAO,IAAI,IAAI,IAAI,SAASA,EAAO,IAAI,IAAI,GAAI,EAAE,IAAI,QACnEK,MAAWT,IAAAI,EAAO,IAAI,IAAI,MAAf,gBAAAJ,EAAkB,MAAM,SAAQ;AAEjD,SAAO;AAAA,IACL,UAAAK;AAAA,IACA,aAAAC;AAAA,IACA,UAAUC,EAAS,SAAS,IAAIA,IAAW;AAAA,IAC3C,aAAAC;AAAA,IACA,UAAAC;AAAA,EAAA;AAEJ;AAKO,SAASmG,EAAgBC,GAKrB;AACT,QAAMzG,IAAS,IAAI,gBAAA;AAQnB,MAPAA,EAAO,IAAI,MAAM,YAAYyG,EAAQ,QAAQ,EAAE,GAC/CzG,EAAO,IAAI,MAAMyG,EAAQ,IAAI,GAEzBA,EAAQ,QACVzG,EAAO,IAAI,MAAMyG,EAAQ,KAAK,UAAU,GAGtCA,EAAQ;AACV,eAAWC,KAAWD,EAAQ;AAC5B,MAAAzG,EAAO,OAAO,MAAM0G,CAAO;AAI/B,SAAO,WAAW1G,EAAO,SAAA,CAAU;AACrC;AAKO,SAAS2G,EAAgB1F,GAAmB2F,IAAoB,QAAgB;AACrF,SAAO,KAAK,KAAK3F,IAAY2F,CAAS;AACxC;AAKO,SAASC,EAAkBC,GAAmC;AACnE,SAAO,MAAM,KAAK,EAAE,QAAQA,EAAA,GAAc,MAAM,SAAwB;AAC1E;AAKO,SAASC,GAAgBC,GAAmB9D,GAAuB;AACxE,SAAO,GAAG8D,CAAS,IAAI9D,CAAK;AAC9B;AAKO,SAAS+D,GACdC,GACAC,GACiD;AACjD,MAAID,MAAY;AACd,WAAO;AAET,QAAME,IAAQF,KAAWC,IAAW;AACpC,SAAIC,KAAS,KAAKF,KAAW,KACpB,cAELE,KAAS,KAAKF,KAAW,IACpB,SAELA,KAAW,IACN,SAEF;AACT;AASO,SAASG,GAAoBC,GAA4C;AAC9E,SAAO,IAAI,IAAIA,EAAM,IAAI,CAACC,MAAM,CAACA,EAAE,OAAOA,EAAE,MAAM,CAAC,CAAC;AACtD;AAKO,SAASC,EAAuBF,GAAsB9G,GAAqC;AAChG,SAAO8G,EAAM,OAAO,CAACC,MAAM;;AACzB,UAAME,KAAM7H,IAAA2H,EAAE,KAAK,MAAM,GAAG,EAAE,IAAA,MAAlB,gBAAA3H,EAAyB;AACrC,WAAO6H,KAAOjH,EAAW,SAASiH,CAAG;AAAA,EACvC,CAAC;AACH;AAKO,SAASC,GAAcJ,GAAqC;AAEjE,SAAOE,EAAuBF,GADN,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,QAAQ,OAAO,QAAQ,KAAK,CAC3C;AACtD;AAKO,SAASK,GAAcL,GAAqC;AAEjE,SAAOE,EAAuBF,GADN,CAAC,OAAO,QAAQ,OAAO,OAAO,OAAO,OAAO,OAAO,MAAM,CAC7B;AACtD;AAKO,SAASM,GAAeN,GAA+C;AAC5E,SAAOA,EAAM;AAAA,IACX,CAACO,GAASC,MAAUA,EAAK,SAAQD,KAAA,gBAAAA,EAAS,SAAQ,KAAKC,IAAOD;AAAA,IAC9D;AAAA,EAAA;AAEJ;AAmDO,MAAME,EAAc;AAAA,EAOzB,YAAYvG,IAAuC,IAAI;AALvD,SAAQ,+BAAkD,IAAA,GAC1D,KAAQ,qCAAuE,IAAA,GAE/E,KAAQ,sCAAmE,IAAA,GAGzE,KAAK,SAAS0E,EAAA,GACd,KAAK,SAAS;AAAA,MACZ,cAAc1E,EAAO,gBAAgB;AAAA,MACrC,UAAUA,EAAO;AAAA,MACjB,mBAAmBA,EAAO,qBAAqB;AAAA,MAC/C,0BAA0BA,EAAO,4BAA4B;AAAA,MAC7D,0BAA0BA,EAAO,4BAA4B;AAAA,MAC7D,sBAAsBA,EAAO,wBAAwB;AAAA,MACrD,gBAAgBA,EAAO,kBAAkB,EAAE,SAAS,IAAO,MAAM,OAAA;AAAA,MACjE,YAAYA,EAAO,cAAc;AAAA,MACjC,YAAYA,EAAO,cAAc;AAAA,MACjC,YAAYA,EAAO,cAAc;AAAA,MACjC,aAAaA,EAAO,eAAe;AAAA,MACnC,eAAeA,EAAO,iBAAiB;AAAA,MACvC,gBAAgBA,EAAO,kBAAkB;AAAA,MACzC,aAAaA,EAAO,eAAe;AAAA,MACnC,eAAeA,EAAO,iBAAiB;AAAA,MACvC,eAAeA,EAAO;AAAA,IAAA,GAGpB,KAAK,OAAO,cACd,KAAK,QAAA,GAEH,KAAK,OAAO,cACd,KAAK,QAAA;AAAA,EAET;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,GAAGC,GAAyBC,GAA4C;AACtE,WAAK,KAAK,eAAe,IAAID,CAAK,KAChC,KAAK,eAAe,IAAIA,GAAO,oBAAI,KAAK,GAE1C,KAAK,eAAe,IAAIA,CAAK,EAAG,IAAIC,CAAQ,GACrC,MAAA;;AAAM,cAAA9B,IAAA,KAAK,eAAe,IAAI6B,CAAK,MAA7B,gBAAA7B,EAAgC,OAAO8B;AAAA;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAKQ,KAAKD,GAA2B;AACtC,UAAME,IAAY,KAAK,eAAe,IAAIF,EAAM,IAAI;AACpD,QAAIE;AACF,iBAAWD,KAAYC;AACrB,YAAI;AACF,UAAAD,EAASD,CAAK;AAAA,QAChB,SAASG,GAAO;AACd,kBAAQ,MAAM,iCAAiCA,CAAK;AAAA,QACtD;AAAA,EAGN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,UACE0E,GACAzE,IAMK,IACW;AAChB,UAAMmG,IAAa3B,EAAeC,CAAS;AAC3C,QAAI,CAAC0B;AACH,qBAAQ,MAAM,oBAAoB,GAC3B;AAIT,QAAI,KAAK,SAAS,IAAIA,EAAW,QAAQ;AACvC,aAAO,KAAK,SAAS,IAAIA,EAAW,QAAQ;AAG9C,UAAMvB,IAAU,KAAK,cAAc;AAAA,MACjC,UAAUuB,EAAW;AAAA,MACrB,MAAMA,EAAW,eAAe;AAAA,MAChC,MAAMA,EAAW;AAAA,MACjB,UAAUA,EAAW;AAAA,MACrB,WAAA1B;AAAA,MACA,GAAGzE;AAAA,IAAA,CACJ;AAED,gBAAK,SAAS,IAAI4E,EAAQ,UAAUA,CAAO,GAC3C,KAAK,KAAK,EAAE,MAAM,SAAS,SAAAA,GAAS,GAEhC5E,EAAQ,cAAc,MACxB,KAAK,aAAa4E,EAAQ,QAAQ,GAG7BA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,eACE9F,GACAkB,IAMK,IACW;AAGhB,UAAM5B,IAAW8F,EAAA,GAEXU,IAAU,KAAK,cAAc;AAAA,MACjC,UAAAxG;AAAA,MACA,MAAM;AAAA,MACN,GAAG4B;AAAA,IAAA,CACJ;AAED,gBAAK,SAAS,IAAI4E,EAAQ,UAAUA,CAAO,GAC3C,KAAK,KAAK,EAAE,MAAM,SAAS,SAAAA,GAAS,GAEhC5E,EAAQ,cAAc,MACxB,KAAK,aAAa4E,EAAQ,QAAQ,GAG7BA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAczG,GAUG;AACvB,UAAM8G,IAAa9G,EAAO,OAAO2G,EAAgB3G,EAAO,IAAI,IAAI,GAE1DG,KAA8BH,EAAO,YAAY,KAAK,sBACzD,OAAO,CAACiI,GAAGxJ,GAAG,MAAM,EAAE,QAAQwJ,CAAC,MAAMxJ,CAAC,EACtC,IAAI,CAACc,GAAKqD,OAAW;AAAA,MACpB,KAAArD;AAAA,MACA,MAAM,KAAK,MAAMqD,IAAQ,CAAC;AAAA,MAC1B,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,UAAU;AAAA,IAAA,EACV;AAEJ,WAAO;AAAA,MACL,IAAI,WAAW,KAAK,MAAM,SAAS,EAAE,CAAC,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,UAAU,GAAG,CAAC,CAAC;AAAA,MACpF,UAAU5C,EAAO;AAAA,MACjB,MAAMA,EAAO;AAAA,MACb,QAAQ;AAAA,MACR,UAAUA,EAAO,YAAY;AAAA;AAAA,MAG7B,MAAMA,EAAO,QAAQ;AAAA,MACrB,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,UAAU;AAAA,MACV,OAAO;AAAA;AAAA,MAGP,eAAetB,EAAY,CAAC;AAAA,MAC5B,aAAaA,EAAY,CAAC;AAAA;AAAA,MAG1B,OAAO;AAAA,MACP,OAAO;AAAA;AAAA,MAGP,UAAAyB;AAAA;AAAA,MAGA,OAAO,CAAA;AAAA,MACP,QAAQ0G,EAAkBC,CAAU;AAAA;AAAA,MAGpC,UAAU9G,EAAO,QAAQ,KAAK,OAAO;AAAA,MACrC,WAAW;AAAA;AAAA,MAGX,WAAWA,EAAO;AAAA,MAClB,+BAAe,KAAA;AAAA,MACf,oBAAoBA,EAAO,sBAAsB;AAAA,MACjD,eAAeA,EAAO,iBAAiB,CAAA;AAAA,IAAC;AAAA,EAE5C;AAAA;AAAA;AAAA;AAAA,EAKA,cAAcC,GAAkBiI,IAAa,IAAgB;AAC3D,UAAMzB,IAAU,KAAK,SAAS,IAAIxG,CAAQ;AAC1C,WAAKwG,KAIL,KAAK,YAAYxG,CAAQ,GACzB,KAAK,SAAS,OAAOA,CAAQ,GAE7B,KAAK,KAAK,EAAE,MAAM,WAAW,SAAAwG,GAAS,GAElCyB,KACF,QAAQ,KAAK,sDAAsD,GAG9D,MAZE;AAAA,EAaX;AAAA;AAAA;AAAA;AAAA,EAKA,WAAWjI,GAAuC;AAChD,WAAO,KAAK,SAAS,IAAIA,CAAQ;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,iBAA4B;AAC1B,WAAO,MAAM,KAAK,KAAK,SAAS,QAAQ;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoBqC,GAAkC;AACpD,WAAO,KAAK,iBAAiB,OAAO,CAAC,MAAM,EAAE,WAAWA,CAAM;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,aAAarC,GAAwB;AACnC,UAAMwG,IAAU,KAAK,SAAS,IAAIxG,CAAQ;AAC1C,IAAKwG,MAIDA,EAAQ,WAAW,iBAAiBA,EAAQ,WAAW,cAKvDA,EAAQ,MAAM,WAAW,KAAKA,EAAQ,aACxCA,EAAQ,SAAS,YACjB,KAAK,cAAcA,CAAO,MAE1BA,EAAQ,SAAS,eACjBA,EAAQ,kCAAkB,KAAA,IAG5B,KAAK,KAAK,EAAE,MAAM,WAAW,SAAAA,GAAS,GACtC,KAAK,wBAAwBxG,CAAQ;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,aAAaA,GAAwB;AACnC,UAAMwG,IAAU,KAAK,SAAS,IAAIxG,CAAQ;AAC1C,QAAI,CAACwG;AACH;AAGF,UAAMjB,IAAW,KAAK,gBAAgB,IAAIvF,CAAQ;AAClD,IAAIuF,MACF,cAAcA,CAAQ,GACtB,KAAK,gBAAgB,OAAOvF,CAAQ,IAGtCwG,EAAQ,SAAS,UACjBA,EAAQ,gBAAgB/H,EAAY,CAAC,GACrC+H,EAAQ,cAAc/H,EAAY,CAAC,GAEnC,KAAK,KAAK,EAAE,MAAM,UAAU,SAAA+H,GAAS;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,cAAcxG,GAAwB;AACpC,UAAMwG,IAAU,KAAK,SAAS,IAAIxG,CAAQ;AAC1C,IAAI,CAACwG,KAAWA,EAAQ,WAAW,aAInCA,EAAQ,SAASA,EAAQ,YAAY,MAAM,YAAY,eACvD,KAAK,KAAK,EAAE,MAAM,WAAW,SAAAA,GAAS,GACtC,KAAK,wBAAwBxG,CAAQ;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,YAAYA,GAAwB;AAClC,UAAMwG,IAAU,KAAK,SAAS,IAAIxG,CAAQ;AAC1C,QAAI,CAACwG;AACH;AAGF,UAAMjB,IAAW,KAAK,gBAAgB,IAAIvF,CAAQ;AAClD,IAAIuF,MACF,cAAcA,CAAQ,GACtB,KAAK,gBAAgB,OAAOvF,CAAQ,IAGtCwG,EAAQ,SAAS,WACjBA,EAAQ,gBAAgB/H,EAAY,CAAC,GACrC+H,EAAQ,cAAc/H,EAAY,CAAC;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,eAAeuB,GAAwB;AACrC,UAAMwG,IAAU,KAAK,SAAS,IAAIxG,CAAQ;AAC1C,IAAKwG,MAILA,EAAQ,SAAS,YAEjB,WAAW,MAAM;AACf,MAAIA,EAAQ,WAAW,eACrBA,EAAQ,SAASA,EAAQ,YAAY,MAAM,YAAY;AAAA,IAE3D,GAAG,GAAI;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmBxG,GAAwB;AACzC,UAAMwG,IAAU,KAAK,SAAS,IAAIxG,CAAQ;AAC1C,QAAKwG;AAIL,iBAAWC,KAAWD,EAAQ;AAC5B,QAAAC,EAAQ,SAAS,YAEjB;AAAA,UACE,MAAM;AACJ,YAAAA,EAAQ,SAAS,WACjBA,EAAQ,mCAAmB,KAAA,GAC3BA,EAAQ,QAAQ,KAAK,MAAM,KAAK,OAAA,IAAW,GAAG,GAC9CA,EAAQ,WAAW,KAAK,MAAM,KAAK,OAAA,IAAW,EAAE,GAChD,KAAK,KAAK,EAAE,MAAM,kBAAkB,SAAAD,GAAS,SAAAC,GAAS;AAAA,UACxD;AAAA,UACA,MAAO,KAAK,WAAW;AAAA,QAAA;AAAA,EAG7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,iBAAiBzG,GAAkBkI,GAAmBC,GAAuB;AAC3E,UAAM3B,IAAU,KAAK,SAAS,IAAIxG,CAAQ;AAC1C,QAAI,CAACwG;AACH;AAGF,UAAMqB,IAAOrB,EAAQ,MAAM,KAAK,CAACc,MAAMA,EAAE,UAAUY,CAAS;AAC5D,IAAIL,MACFA,EAAK,SAASM,GACdN,EAAK,WAAWM,IAAS,WAAW,QAEhC3B,EAAQ,kBACN2B,KAAU,CAAC3B,EAAQ,cAAc,SAAS0B,CAAS,IACrD1B,EAAQ,cAAc,KAAK0B,CAAS,IAC1BC,MACV3B,EAAQ,gBAAgBA,EAAQ,cAAc,OAAO,CAAChI,MAAcA,MAAM0J,CAAS;AAAA,EAI3F;AAAA;AAAA;AAAA;AAAA,EAKA,gBACElI,GACAkI,GACAzF,GACM;AACN,UAAM+D,IAAU,KAAK,SAAS,IAAIxG,CAAQ;AAC1C,QAAI,CAACwG;AACH;AAGF,UAAMqB,IAAOrB,EAAQ,MAAM,KAAK,CAACc,MAAMA,EAAE,UAAUY,CAAS;AAC5D,IAAIL,MACFA,EAAK,WAAWpF,GAChBoF,EAAK,SAASpF,MAAa;AAAA,EAE/B;AAAA;AAAA;AAAA;AAAA,EAKA,eAAezC,GAAwB;AACrC,UAAMwG,IAAU,KAAK,SAAS,IAAIxG,CAAQ;AAC1C,QAAKwG,GAIL;AAAA,iBAAWqB,KAAQrB,EAAQ;AACzB,QAAAqB,EAAK,SAAS,IACdA,EAAK,WAAW;AAElB,MAAIrB,EAAQ,kBAAkB,WAC5BA,EAAQ,gBAAgBA,EAAQ,MAAM,IAAI,CAACc,MAAMA,EAAE,KAAK;AAAA;AAAA,EAE5D;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiBtH,GAAwB;AACvC,UAAMwG,IAAU,KAAK,SAAS,IAAIxG,CAAQ;AAC1C,QAAKwG,GAIL;AAAA,iBAAWqB,KAAQrB,EAAQ;AACzB,QAAAqB,EAAK,SAAS,IACdA,EAAK,WAAW;AAElB,MAAIrB,EAAQ,kBAAkB,WAC5BA,EAAQ,gBAAgB,CAAA;AAAA;AAAA,EAE5B;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsBxG,GAAkBoI,GAAwB;AAC9D,UAAM5B,IAAU,KAAK,SAAS,IAAIxG,CAAQ;AAC1C,IAAIwG,MACFA,EAAQ,qBAAqB4B;AAAA,EAEjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,YAAiC;AAC/B,WAAO,EAAE,GAAG,KAAK,OAAA;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,aAAaxF,GAA6C;AACxD,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAGA,EAAA;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiBlE,GAA0C;AACzD,IAAIA,MAAmB,SACrB,KAAK,OAAO,iBAAiB;AAAA,MAC3B,GAAG,KAAK,OAAO;AAAA,MACf,UAAUA;AAAA,MACV,SAAS;AAAA,IAAA,IAGX,KAAK,OAAO,iBAAiB;AAAA,MAC3B,GAAG,KAAK,OAAO;AAAA,MACf,UAAU;AAAA,IAAA;AAAA,EAGhB;AAAA;AAAA;AAAA;AAAA,EAKA,eAAeA,GAA0C;AACvD,IAAIA,MAAmB,SACrB,KAAK,OAAO,iBAAiB;AAAA,MAC3B,GAAG,KAAK,OAAO;AAAA,MACf,QAAQA;AAAA,MACR,SAAS;AAAA,IAAA,IAGX,KAAK,OAAO,iBAAiB;AAAA,MAC3B,GAAG,KAAK,OAAO;AAAA,MACf,QAAQ;AAAA,IAAA;AAAA,EAGd;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc0J,GAAwB;AACpC,SAAK,OAAO,aAAaA,GACrBA,KACF,KAAK,QAAA;AAAA,EAET;AAAA;AAAA;AAAA;AAAA,EAKA,cAAcA,GAAwB;AACpC,SAAK,OAAO,aAAaA,GACrBA,KACF,KAAK,QAAA;AAAA,EAET;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,gBAAuC;AACrC,UAAMC,IAAW,KAAK,eAAA;AAEtB,QAAIC,IAAgB,GAChBC,IAAc,GACdC,IAAmB,GACnBC,IAAiB,GACjBC,IAAa;AAEjB,eAAWC,KAAKN;AACd,MAAAC,KAAiBK,EAAE,iBACnBJ,KAAeI,EAAE,eACjBH,KAAoBG,EAAE,cAAc,gBACpCF,KAAkBE,EAAE,YAAY,gBAChCD,KAAcC,EAAE;AAGlB,WAAO;AAAA,MACL,eAAeN,EAAS,OAAO,CAACM,MAAMA,EAAE,WAAW,SAAS,EAAE;AAAA,MAC9D,iBAAiBN,EAAS,OAAO,CAACM,MAAMA,EAAE,WAAW,aAAa,EAAE;AAAA,MACpE,iBAAiBL;AAAA,MACjB,eAAeC;AAAA,MACf,eAAe9J,EAAY+J,CAAgB;AAAA,MAC3C,aAAa/J,EAAYgK,CAAc;AAAA,MACvC,aAAaH,IAAgB,IAAIC,IAAcD,IAAgB;AAAA,MAC/D,UAAU,KAAK,OAAO,aAAa,KAAK,MAAM,KAAK,OAAA,IAAW,MAAM,GAAG,IAAI;AAAA,MAC3E,YAAAI;AAAA,MACA,iBAAiB;AAAA;AAAA,IAAA;AAAA,EAErB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,qBAA+B;AACrC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA,EAKQ,UAAgB;AACtB,YAAQ,IAAI,iBAAiB;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKQ,UAAgB;AACtB,YAAQ,IAAI,iBAAiB;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAclC,GAAqC;AAEzD;AAAA,MACE,MAAM;AACJ,QAAIA,EAAQ,WAAW,eAKvBA,EAAQ,QAAQ;AAAA,UACd;AAAA,YACE,OAAO;AAAA,YACP,MAAM,GAAGA,EAAQ,IAAI;AAAA,YACrB,MAAM,GAAGA,EAAQ,IAAI,IAAIA,EAAQ,IAAI;AAAA,YACrC,MAAM,KAAK,MAAM,KAAK,OAAA,IAAW,GAAU,IAAI;AAAA;AAAA,YAC/C,UAAU;AAAA,YACV,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,QAAQ;AAAA,UAAA;AAAA,UAEV;AAAA,YACE,OAAO;AAAA,YACP,MAAM;AAAA,YACN,MAAM,GAAGA,EAAQ,IAAI;AAAA,YACrB,MAAM,KAAK,MAAM,KAAK,OAAA,IAAW,GAAQ,IAAI;AAAA;AAAA,YAC7C,UAAU;AAAA,YACV,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,QAAQ;AAAA,UAAA;AAAA,UAEV;AAAA,YACE,OAAO;AAAA,YACP,MAAM;AAAA,YACN,MAAM,GAAGA,EAAQ,IAAI;AAAA,YACrB,MAAM;AAAA,YACN,UAAU;AAAA,YACV,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,QAAQ;AAAA,UAAA;AAAA,QACV,GAGFA,EAAQ,OAAOA,EAAQ,MAAM,OAAO,CAACtE,GAAKoF,MAAMpF,IAAMoF,EAAE,MAAM,CAAC,GAC/Dd,EAAQ,gBAAgBA,EAAQ,MAAM,IAAI,CAACc,MAAMA,EAAE,KAAK,GACxDd,EAAQ,SAASI,EAAkBF,EAAgBF,EAAQ,IAAI,CAAC,GAChEA,EAAQ,SAAS,eAEjB,KAAK,KAAK,EAAE,MAAM,YAAY,SAAAA,GAAS,GACvC,KAAK,KAAK,EAAE,MAAM,WAAW,SAAAA,GAAS;AAAA,MACxC;AAAA,MACA,MAAO,KAAK,WAAW;AAAA,IAAA;AAAA,EAE3B;AAAA;AAAA;AAAA;AAAA,EAKQ,wBAAwBxG,GAAwB;AACtD,IAAI,KAAK,gBAAgB,IAAIA,CAAQ,KACnC,cAAc,KAAK,gBAAgB,IAAIA,CAAQ,CAAE;AAGnD,UAAMuF,IAAW,YAAY,MAAM;AACjC,YAAMiB,IAAU,KAAK,SAAS,IAAIxG,CAAQ;AAC1C,UAAI,CAACwG,GAAS;AACZ,sBAAcjB,CAAQ;AACtB;AAAA,MACF;AAEA,UAAI,EAAAiB,EAAQ,WAAW,iBAAiBA,EAAQ,WAAW,YAK3D;AAAA,YAAIA,EAAQ,WAAW,iBAAiBA,EAAQ,OAAO,GAAG;AACxD,gBAAMoC,IAAY,MAAU,KAAK,OAAA,IAAW,KACtCC,IAAgB,KAAK,OAAO,eAAe,WAC7C,KAAK,IAAID,GAAW,KAAK,OAAO,eAAe,QAAQ,IACvDA,GAEEE,IAAYD,KAAiB,IAAI,KAAK,WAAW;AACvD,UAAArC,EAAQ,kBAAkB,KAAK,IAAIA,EAAQ,kBAAkBsC,GAAWtC,EAAQ,IAAI,GACpFA,EAAQ,WAAYA,EAAQ,kBAAkBA,EAAQ,OAAQ,KAC9DA,EAAQ,gBAAgB/H,EAAYoK,CAAa,GACjDrC,EAAQ,cAAc/H,EAAYoK,IAAgB,MAAM,KAAK,QAAQ;AAGrE,qBAAWhB,KAAQrB,EAAQ;AACzB,YAAIqB,EAAK,WACPA,EAAK,aAAa,KAAK;AAAA,cACrBA,EAAK,aAAaiB,KAAajB,EAAK,OAAOrB,EAAQ;AAAA,cACnDqB,EAAK;AAAA,YAAA,GAEPA,EAAK,WAAYA,EAAK,aAAaA,EAAK,OAAQ;AAKpD,UAAArB,EAAQ,QAAQ,KAAK,MAAM,KAAK,OAAA,IAAW,EAAE,IAAI,GACjDA,EAAQ,QAAQ,KAAK,MAAMA,EAAQ,QAAQ,GAAG,GAG9CA,EAAQ,MAAMtH,EAAasH,EAAQ,OAAOA,EAAQ,iBAAiBqC,CAAa,GAEhF,KAAK,KAAK,EAAE,MAAM,YAAY,SAAArC,GAAS,GAGnCA,EAAQ,YAAY,QACtBA,EAAQ,SAAS,WACjBA,EAAQ,oCAAoB,KAAA,GAC5BA,EAAQ,WAAW,KACnBA,EAAQ,kBAAkBA,EAAQ,MAClC,KAAK,KAAK,EAAE,MAAM,aAAa,SAAAA,GAAS,GACxC,KAAK,KAAK,EAAE,MAAM,WAAW,SAAAA,GAAS;AAAA,QAE1C;AAGA,YAAIA,EAAQ,WAAW,WAAW;AAChC,gBAAMuC,IAAc,MAAS,KAAK,OAAA,IAAW;AAC7C,UAAAvC,EAAQ,iBAAiBuC,GACzBvC,EAAQ,cAAc/H,EAAYsK,CAAW,GAC7CvC,EAAQ,gBAAgB/H,EAAY,CAAC,GACrC+H,EAAQ,QAAQA,EAAQ,OAAO,IAAIA,EAAQ,gBAAgBA,EAAQ,OAAO,GAE1EA,EAAQ,QAAQ,KAAK,MAAM,KAAK,OAAA,IAAW,EAAE,IAAI,GACjDA,EAAQ,QAAQ;AAAA,QAClB;AAAA;AAAA,IACF,GAAG,GAAI;AAEP,SAAK,gBAAgB,IAAIxG,GAAUuF,CAAQ;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AACd,eAAWA,KAAY,KAAK,gBAAgB,OAAA;AAC1C,oBAAcA,CAAQ;AAExB,SAAK,gBAAgB,MAAA,GACrB,KAAK,SAAS,MAAA,GACd,KAAK,eAAe,MAAA;AAAA,EACtB;AACF;AAuBA,eAAsByD,EAAcpH,GAAwD;AAC1F,QAAM;AAAA,IACJ,MAAAqH;AAAA,IACA,OAAA5B;AAAA,IACA,UAAAnH,IAAW,CAAA;AAAA,IACX,SAAAgJ;AAAA,IACA,WAAAC,IAAY;AAAA,IACZ,WAAAxC,IAAY;AAAA,IACZ,UAAAyC,IAAW,CAAA;AAAA,EAAC,IACVxH,GAGEZ,IAAYqG,EAAM,OAAO,CAACnF,GAAKoF,MAAMpF,IAAMoF,EAAE,MAAM,CAAC,GAGpDtH,IAAW8F,EAAA,GACXe,IAAaH,EAAgB1F,GAAW2F,CAAS,GAGjD0C,IAAa9C,EAAgB,EAAE,UAAAvG,GAAU,MAAAiJ,GAAM,UAAA/I,GAAU,MAAMc,GAAW,GAK1EsI,IADU,IAAI,YAAA,EACQ;AAAA,IAC1B,KAAK,UAAU;AAAA,MACb,UAAUpJ,EAAS,CAAC,KAAK;AAAA,MACzB,MAAM;AAAA,QACJ,MAAA+I;AAAA,QACA,gBAAgBtC;AAAA,QAChB,QAAQ3F;AAAA,QACR,SAASmI,IAAY,IAAI;AAAA,MAAA;AAAA,MAE3B,SAAAD;AAAA,MACA,YAAYE;AAAA,IAAA,CACb;AAAA,EAAA;AAGH,SAAO;AAAA,IACL,UAAApJ;AAAA,IACA,YAAAqJ;AAAA,IACA,aAAAC;AAAA,IACA,MAAMtI;AAAA,IACN,YAAA6F;AAAA,IACA,WAAAF;AAAA,EAAA;AAEJ;AAMA,IAAI4C,IAA8C;AAK3C,SAASC,EAAiBjI,GAAsD;AACrF,SAAKgI,MACHA,IAAwB,IAAIzB,EAAcvG,CAAM,IAE3CgI;AACT;AAKO,SAASE,KAA6B;AAC3C,EAAAF,KAAA,QAAAA,EAAuB,WACvBA,IAAwB;AAC1B;AAqDO,SAASG,GAAiB9H,IAAmC,IAA4B;AAC9F,QAAM,EAAE,QAAAL,GAAQ,aAAAoD,IAAc,IAAM,iBAAAC,IAAkB,QAAShD,GAEzD+H,IAAS7E,EAAQ,MAAM0E,EAAiBjI,CAAM,GAAG,CAACA,CAAM,CAAC,GAEzD,CAAC8G,GAAUuB,CAAW,IAAI3E,EAAoB0E,EAAO,gBAAgB,GACrE,CAACE,GAAYC,CAAa,IAAI7E,EAAgC0E,EAAO,eAAe;AAE1F,EAAAvE,EAAU,MAAM;AACd,UAAM2E,IAAe,MAAM;AACzB,MAAAH,EAAY,CAAC,GAAGD,EAAO,eAAA,CAAgB,CAAC,GACxCG,EAAcH,EAAO,eAAe;AAAA,IACtC,GAEMrE,IAAgB;AAAA,MACpBqE,EAAO,GAAG,SAASI,CAAY;AAAA,MAC/BJ,EAAO,GAAG,YAAYI,CAAY;AAAA,MAClCJ,EAAO,GAAG,WAAWI,CAAY;AAAA,MACjCJ,EAAO,GAAG,YAAYI,CAAY;AAAA,MAClCJ,EAAO,GAAG,UAAUI,CAAY;AAAA,MAChCJ,EAAO,GAAG,WAAWI,CAAY;AAAA,MACjCJ,EAAO,GAAG,aAAaI,CAAY;AAAA,MACnCJ,EAAO,GAAG,WAAWI,CAAY;AAAA,MACjCJ,EAAO,GAAG,UAAUI,CAAY;AAAA,MAChCJ,EAAO,GAAG,WAAWI,CAAY;AAAA,IAAA;AAInC,QAAIxE;AACJ,WAAIZ,MACFY,IAAW,YAAY,MAAM;AAC3B,OACEoE,EAAO,gBAAgB,kBAAkB,KACzCA,EAAO,cAAA,EAAgB,gBAAgB,MAEvCI,EAAA;AAAA,IAEJ,GAAGnF,CAAe,IAGb,MAAM;AACX,MAAAU,EAAc,QAAQ,CAACE,MAAUA,EAAA,CAAO,GACpCD,KACF,cAAcA,CAAQ;AAAA,IAE1B;AAAA,EACF,GAAG,CAACoE,GAAQhF,GAAaC,CAAe,CAAC;AAEzC,QAAMoF,IAAiBlF;AAAA,IACrB,MAAMuD,EAAS,OAAO,CAACM,MAAMA,EAAE,WAAW,iBAAiBA,EAAE,WAAW,SAAS;AAAA,IACjF,CAACN,CAAQ;AAAA,EAAA;AAGX,SAAO;AAAA,IACL,UAAAA;AAAA,IACA,YAAAwB;AAAA,IACA,gBAAAG;AAAA,IACA,WAAWrE,EAAY,CAACsE,GAAKrE,MAAS+D,EAAO,UAAUM,GAAKrE,CAAI,GAAG,CAAC+D,CAAM,CAAC;AAAA,IAC3E,gBAAgBhE,EAAY,CAACjF,GAAMkF,MAAS+D,EAAO,eAAejJ,GAAMkF,CAAI,GAAG,CAAC+D,CAAM,CAAC;AAAA,IACvF,eAAehE,EAAY,CAACK,GAAMkE,MAAQP,EAAO,cAAc3D,GAAMkE,CAAG,GAAG,CAACP,CAAM,CAAC;AAAA,IACnF,cAAchE,EAAY,CAACK,MAAS2D,EAAO,aAAa3D,CAAI,GAAG,CAAC2D,CAAM,CAAC;AAAA,IACvE,cAAchE,EAAY,CAACK,MAAS2D,EAAO,aAAa3D,CAAI,GAAG,CAAC2D,CAAM,CAAC;AAAA,IACvE,eAAehE,EAAY,CAACK,MAAS2D,EAAO,cAAc3D,CAAI,GAAG,CAAC2D,CAAM,CAAC;AAAA,IACzE,aAAahE,EAAY,CAACK,MAAS2D,EAAO,YAAY3D,CAAI,GAAG,CAAC2D,CAAM,CAAC;AAAA,IACrE,kBAAkBhE;AAAA,MAChB,CAACK,GAAMmE,GAAKC,MAAMT,EAAO,iBAAiB3D,GAAMmE,GAAKC,CAAC;AAAA,MACtD,CAACT,CAAM;AAAA,IAAA;AAAA,IAET,uBAAuBhE;AAAA,MACrB,CAACK,GAAMqE,MAAOV,EAAO,sBAAsB3D,GAAMqE,CAAE;AAAA,MACnD,CAACV,CAAM;AAAA,IAAA;AAAA,IAET,kBAAkBhE,EAAY,CAAC2E,MAAQX,EAAO,iBAAiBW,CAAG,GAAG,CAACX,CAAM,CAAC;AAAA,IAC7E,gBAAgBhE,EAAY,CAAC2E,MAAQX,EAAO,eAAeW,CAAG,GAAG,CAACX,CAAM,CAAC;AAAA,IACzE,eAAAX;AAAA,EAAA;AAEJ;AC9WO,MAAMuB,IAA6C;AAAA,EACxD,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,2BAA2B;AAAA,EAC3B,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,aAAY,oBAAI,KAAA,GAAO,YAAA;AACzB,GAKaC,IAAwC;AAAA,EACnD,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,2BAA2B;AAAA,EAC3B,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,aAAY,oBAAI,KAAA,GAAO,YAAA;AACzB,GAKaC,IAAgE;AAAA,EAC3E,WAAW;AAAA,IACT,gBAAgB;AAAA,IAChB,qBAAqB;AAAA,IACrB,uBAAuB;AAAA,IACvB,kBAAkB;AAAA,IAClB,eAAe;AAAA,IACf,2BAA2B;AAAA,EAAA;AAAA,EAE7B,WAAW;AAAA,IACT,gBAAgB;AAAA,IAChB,qBAAqB;AAAA,IACrB,uBAAuB;AAAA,IACvB,kBAAkB;AAAA,IAClB,eAAe;AAAA,IACf,2BAA2B;AAAA,EAAA;AAAA,EAE7B,SAAS;AAAA,IACP,gBAAgB;AAAA;AAAA,IAChB,qBAAqB;AAAA,IACrB,uBAAuB;AAAA,IACvB,kBAAkB;AAAA,IAClB,eAAe;AAAA,IACf,2BAA2B;AAAA,EAAA;AAAA,EAE7B,UAAU;AAAA,IACR,gBAAgB;AAAA,IAChB,qBAAqB;AAAA,IACrB,uBAAuB;AAAA,IACvB,kBAAkB;AAAA,IAClB,eAAe;AAAA,IACf,2BAA2B;AAAA,EAAA;AAAA,EAE7B,MAAM;AAAA,IACJ,gBAAgB;AAAA,IAChB,qBAAqB;AAAA,IACrB,uBAAuB;AAAA,IACvB,kBAAkB;AAAA,IAClB,eAAe;AAAA,IACf,2BAA2B;AAAA,EAAA;AAAA,EAE7B,QAAQ;AAAA,IACN,gBAAgB;AAAA,IAChB,qBAAqB;AAAA,IACrB,uBAAuB;AAAA,IACvB,kBAAkB;AAAA,IAClB,eAAe;AAAA,IACf,2BAA2B;AAAA,EAAA;AAE/B;;;;;8CC3lBaC,IAA8C;AAAA,EACzD,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,iBAAiB;AACnB,GAKaC,IAA+C;AAAA,EAC1D,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,iBAAiB;AACnB,GAw6BaC,IAAoD;AAAA,EAC/D,aAAa;AAAA,EACb,aAAa;AAAA,EACb,2BAA2B;AAAA,EAC3B,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB,cAAc;AAAA,EACd,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,kBAAkB;AACpB,GAKaC,IAA+B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKaC,IAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AACF;;;;;;;8CCplBaC,IAAwC;AAAA,EACnD,EAAE,OAAO,IAAI,QAAQ,IAAI,SAAS,WAAW,QAAQ,MAAA;AAAA,EACrD,EAAE,OAAO,IAAI,QAAQ,IAAI,SAAS,WAAW,QAAQ,MAAA;AAAA,EACrD,EAAE,OAAO,IAAI,QAAQ,IAAI,SAAS,WAAW,QAAQ,MAAA;AAAA,EACrD,EAAE,OAAO,KAAK,QAAQ,KAAK,SAAS,eAAe,QAAQ,MAAA;AAAA,EAC3D,EAAE,OAAO,KAAK,QAAQ,KAAK,SAAS,OAAO,QAAQ,MAAA;AAAA,EACnD,EAAE,OAAO,KAAK,QAAQ,KAAK,SAAS,OAAO,QAAQ,MAAA;AAAA,EACnD,EAAE,OAAO,KAAK,QAAQ,KAAK,SAAS,YAAY,QAAQ,MAAA;AAC1D,GAqdaC,IAA2C;AAAA,EACtD;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,IACb,WAAW;AAAA,IACX,YAAY,CAAC,cAAc,MAAM,OAAO,cAAc,aAAa,SAAS,YAAY;AAAA,IACxF,SAAS,CAAC,YAAY,WAAW,MAAM,WAAW;AAAA,IAClD,cAAc,CAAA;AAAA,IACd,SAAS;AAAA,EAAA;AAAA,EAEX;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,IACb,WAAW;AAAA,IACX,YAAY,CAAC,YAAY,YAAY,UAAU,WAAW,MAAM;AAAA,IAChE,SAAS,CAAC,aAAa,SAAS;AAAA,IAChC,cAAc,CAAA;AAAA,IACd,SAAS;AAAA,EAAA;AAAA,EAEX;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,IACb,WAAW;AAAA,IACX,YAAY,CAAC,YAAY,kBAAkB,SAAS,cAAc,YAAY;AAAA,IAC9E,SAAS,CAAC,YAAY;AAAA,IACtB,cAAc,CAAA;AAAA,IACd,SAAS;AAAA,EAAA;AAAA,EAEX;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,IACb,WAAW;AAAA,IACX,YAAY,CAAC,SAAS,SAAS,YAAY,MAAM,WAAW;AAAA,IAC5D,SAAS,CAAC,UAAU;AAAA,IACpB,cAAc,CAAA;AAAA,IACd,SAAS;AAAA,EAAA;AAAA,EAEX;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,IACb,WAAW;AAAA,IACX,YAAY,CAAC,aAAa,aAAa,WAAW;AAAA,IAClD,SAAS,CAAA;AAAA,IACT,cAAc,CAAA;AAAA,IACd,SAAS;AAAA,EAAA;AAAA,EAEX;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,IACb,WAAW;AAAA,IACX,YAAY,CAAC,cAAc,SAAS,MAAM,SAAS;AAAA,IACnD,SAAS,CAAC,QAAQ;AAAA,IAClB,cAAc,CAAA;AAAA,IACd,SAAS;AAAA,EAAA;AAAA,EAEX;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,IACb,WAAW;AAAA,IACX,YAAY,CAAC,WAAW,UAAU,gBAAgB,QAAQ,QAAQ;AAAA,IAClE,SAAS,CAAC,iBAAiB;AAAA,IAC3B,cAAc,CAAA;AAAA,IACd,SAAS;AAAA,EAAA;AAAA,EAEX;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,IACb,WAAW;AAAA,IACX,YAAY,CAAA;AAAA,IACZ,SAAS,CAAA;AAAA,IACT,cAAc;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,IAEF,SAAS;AAAA,EAAA;AAEb;;;;;;;"}
|