Some ignored filles was missing
This commit is contained in:
parent
7db22245e2
commit
fd5ab6bc0d
268 changed files with 31970 additions and 4 deletions
97
wwwroot/js/storage/IndexedDBService.d.ts
vendored
Normal file
97
wwwroot/js/storage/IndexedDBService.d.ts
vendored
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
import { ICalendarEvent } from '../types/CalendarTypes';
|
||||
/**
|
||||
* Operation for the sync queue
|
||||
*/
|
||||
export interface IQueueOperation {
|
||||
id: string;
|
||||
type: 'create' | 'update' | 'delete';
|
||||
eventId: string;
|
||||
data: Partial<ICalendarEvent> | ICalendarEvent;
|
||||
timestamp: number;
|
||||
retryCount: number;
|
||||
}
|
||||
/**
|
||||
* IndexedDB Service for Calendar App
|
||||
* Handles local storage of events and sync queue
|
||||
*/
|
||||
export declare class IndexedDBService {
|
||||
private static readonly DB_NAME;
|
||||
private static readonly DB_VERSION;
|
||||
private static readonly EVENTS_STORE;
|
||||
private static readonly QUEUE_STORE;
|
||||
private static readonly SYNC_STATE_STORE;
|
||||
private db;
|
||||
private initialized;
|
||||
/**
|
||||
* Initialize and open the database
|
||||
*/
|
||||
initialize(): Promise<void>;
|
||||
/**
|
||||
* Check if database is initialized
|
||||
*/
|
||||
isInitialized(): boolean;
|
||||
/**
|
||||
* Ensure database is initialized
|
||||
*/
|
||||
private ensureDB;
|
||||
/**
|
||||
* Get a single event by ID
|
||||
*/
|
||||
getEvent(id: string): Promise<ICalendarEvent | null>;
|
||||
/**
|
||||
* Get all events
|
||||
*/
|
||||
getAllEvents(): Promise<ICalendarEvent[]>;
|
||||
/**
|
||||
* Save an event (create or update)
|
||||
*/
|
||||
saveEvent(event: ICalendarEvent): Promise<void>;
|
||||
/**
|
||||
* Delete an event
|
||||
*/
|
||||
deleteEvent(id: string): Promise<void>;
|
||||
/**
|
||||
* Add operation to queue
|
||||
*/
|
||||
addToQueue(operation: Omit<IQueueOperation, 'id'>): Promise<void>;
|
||||
/**
|
||||
* Get all queue operations (sorted by timestamp)
|
||||
*/
|
||||
getQueue(): Promise<IQueueOperation[]>;
|
||||
/**
|
||||
* Remove operation from queue
|
||||
*/
|
||||
removeFromQueue(id: string): Promise<void>;
|
||||
/**
|
||||
* Clear entire queue
|
||||
*/
|
||||
clearQueue(): Promise<void>;
|
||||
/**
|
||||
* Save sync state value
|
||||
*/
|
||||
setSyncState(key: string, value: any): Promise<void>;
|
||||
/**
|
||||
* Get sync state value
|
||||
*/
|
||||
getSyncState(key: string): Promise<any | null>;
|
||||
/**
|
||||
* Serialize event for IndexedDB storage (convert Dates to ISO strings)
|
||||
*/
|
||||
private serializeEvent;
|
||||
/**
|
||||
* Deserialize event from IndexedDB (convert ISO strings to Dates)
|
||||
*/
|
||||
private deserializeEvent;
|
||||
/**
|
||||
* Close database connection
|
||||
*/
|
||||
close(): void;
|
||||
/**
|
||||
* Delete entire database (for testing/reset)
|
||||
*/
|
||||
static deleteDatabase(): Promise<void>;
|
||||
/**
|
||||
* Seed IndexedDB with mock data if empty
|
||||
*/
|
||||
seedIfEmpty(mockDataUrl?: string): Promise<void>;
|
||||
}
|
||||
340
wwwroot/js/storage/IndexedDBService.js
Normal file
340
wwwroot/js/storage/IndexedDBService.js
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
/**
|
||||
* IndexedDB Service for Calendar App
|
||||
* Handles local storage of events and sync queue
|
||||
*/
|
||||
export class IndexedDBService {
|
||||
constructor() {
|
||||
this.db = null;
|
||||
this.initialized = false;
|
||||
}
|
||||
/**
|
||||
* Initialize and open the database
|
||||
*/
|
||||
async initialize() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = indexedDB.open(IndexedDBService.DB_NAME, IndexedDBService.DB_VERSION);
|
||||
request.onerror = () => {
|
||||
reject(new Error(`Failed to open IndexedDB: ${request.error}`));
|
||||
};
|
||||
request.onsuccess = () => {
|
||||
this.db = request.result;
|
||||
this.initialized = true;
|
||||
resolve();
|
||||
};
|
||||
request.onupgradeneeded = (event) => {
|
||||
const db = event.target.result;
|
||||
// Create events store
|
||||
if (!db.objectStoreNames.contains(IndexedDBService.EVENTS_STORE)) {
|
||||
const eventsStore = db.createObjectStore(IndexedDBService.EVENTS_STORE, { keyPath: 'id' });
|
||||
eventsStore.createIndex('start', 'start', { unique: false });
|
||||
eventsStore.createIndex('end', 'end', { unique: false });
|
||||
eventsStore.createIndex('syncStatus', 'syncStatus', { unique: false });
|
||||
}
|
||||
// Create operation queue store
|
||||
if (!db.objectStoreNames.contains(IndexedDBService.QUEUE_STORE)) {
|
||||
const queueStore = db.createObjectStore(IndexedDBService.QUEUE_STORE, { keyPath: 'id' });
|
||||
queueStore.createIndex('timestamp', 'timestamp', { unique: false });
|
||||
}
|
||||
// Create sync state store
|
||||
if (!db.objectStoreNames.contains(IndexedDBService.SYNC_STATE_STORE)) {
|
||||
db.createObjectStore(IndexedDBService.SYNC_STATE_STORE, { keyPath: 'key' });
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Check if database is initialized
|
||||
*/
|
||||
isInitialized() {
|
||||
return this.initialized;
|
||||
}
|
||||
/**
|
||||
* Ensure database is initialized
|
||||
*/
|
||||
ensureDB() {
|
||||
if (!this.db) {
|
||||
throw new Error('IndexedDB not initialized. Call initialize() first.');
|
||||
}
|
||||
return this.db;
|
||||
}
|
||||
// ========================================
|
||||
// Event CRUD Operations
|
||||
// ========================================
|
||||
/**
|
||||
* Get a single event by ID
|
||||
*/
|
||||
async getEvent(id) {
|
||||
const db = this.ensureDB();
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([IndexedDBService.EVENTS_STORE], 'readonly');
|
||||
const store = transaction.objectStore(IndexedDBService.EVENTS_STORE);
|
||||
const request = store.get(id);
|
||||
request.onsuccess = () => {
|
||||
const event = request.result;
|
||||
resolve(event ? this.deserializeEvent(event) : null);
|
||||
};
|
||||
request.onerror = () => {
|
||||
reject(new Error(`Failed to get event ${id}: ${request.error}`));
|
||||
};
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Get all events
|
||||
*/
|
||||
async getAllEvents() {
|
||||
const db = this.ensureDB();
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([IndexedDBService.EVENTS_STORE], 'readonly');
|
||||
const store = transaction.objectStore(IndexedDBService.EVENTS_STORE);
|
||||
const request = store.getAll();
|
||||
request.onsuccess = () => {
|
||||
const events = request.result;
|
||||
resolve(events.map(e => this.deserializeEvent(e)));
|
||||
};
|
||||
request.onerror = () => {
|
||||
reject(new Error(`Failed to get all events: ${request.error}`));
|
||||
};
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Save an event (create or update)
|
||||
*/
|
||||
async saveEvent(event) {
|
||||
const db = this.ensureDB();
|
||||
const serialized = this.serializeEvent(event);
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([IndexedDBService.EVENTS_STORE], 'readwrite');
|
||||
const store = transaction.objectStore(IndexedDBService.EVENTS_STORE);
|
||||
const request = store.put(serialized);
|
||||
request.onsuccess = () => {
|
||||
resolve();
|
||||
};
|
||||
request.onerror = () => {
|
||||
reject(new Error(`Failed to save event ${event.id}: ${request.error}`));
|
||||
};
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Delete an event
|
||||
*/
|
||||
async deleteEvent(id) {
|
||||
const db = this.ensureDB();
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([IndexedDBService.EVENTS_STORE], 'readwrite');
|
||||
const store = transaction.objectStore(IndexedDBService.EVENTS_STORE);
|
||||
const request = store.delete(id);
|
||||
request.onsuccess = () => {
|
||||
resolve();
|
||||
};
|
||||
request.onerror = () => {
|
||||
reject(new Error(`Failed to delete event ${id}: ${request.error}`));
|
||||
};
|
||||
});
|
||||
}
|
||||
// ========================================
|
||||
// Queue Operations
|
||||
// ========================================
|
||||
/**
|
||||
* Add operation to queue
|
||||
*/
|
||||
async addToQueue(operation) {
|
||||
const db = this.ensureDB();
|
||||
const queueItem = {
|
||||
...operation,
|
||||
id: `${operation.type}-${operation.eventId}-${Date.now()}`
|
||||
};
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([IndexedDBService.QUEUE_STORE], 'readwrite');
|
||||
const store = transaction.objectStore(IndexedDBService.QUEUE_STORE);
|
||||
const request = store.put(queueItem);
|
||||
request.onsuccess = () => {
|
||||
resolve();
|
||||
};
|
||||
request.onerror = () => {
|
||||
reject(new Error(`Failed to add to queue: ${request.error}`));
|
||||
};
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Get all queue operations (sorted by timestamp)
|
||||
*/
|
||||
async getQueue() {
|
||||
const db = this.ensureDB();
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([IndexedDBService.QUEUE_STORE], 'readonly');
|
||||
const store = transaction.objectStore(IndexedDBService.QUEUE_STORE);
|
||||
const index = store.index('timestamp');
|
||||
const request = index.getAll();
|
||||
request.onsuccess = () => {
|
||||
resolve(request.result);
|
||||
};
|
||||
request.onerror = () => {
|
||||
reject(new Error(`Failed to get queue: ${request.error}`));
|
||||
};
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Remove operation from queue
|
||||
*/
|
||||
async removeFromQueue(id) {
|
||||
const db = this.ensureDB();
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([IndexedDBService.QUEUE_STORE], 'readwrite');
|
||||
const store = transaction.objectStore(IndexedDBService.QUEUE_STORE);
|
||||
const request = store.delete(id);
|
||||
request.onsuccess = () => {
|
||||
resolve();
|
||||
};
|
||||
request.onerror = () => {
|
||||
reject(new Error(`Failed to remove from queue: ${request.error}`));
|
||||
};
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Clear entire queue
|
||||
*/
|
||||
async clearQueue() {
|
||||
const db = this.ensureDB();
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([IndexedDBService.QUEUE_STORE], 'readwrite');
|
||||
const store = transaction.objectStore(IndexedDBService.QUEUE_STORE);
|
||||
const request = store.clear();
|
||||
request.onsuccess = () => {
|
||||
resolve();
|
||||
};
|
||||
request.onerror = () => {
|
||||
reject(new Error(`Failed to clear queue: ${request.error}`));
|
||||
};
|
||||
});
|
||||
}
|
||||
// ========================================
|
||||
// Sync State Operations
|
||||
// ========================================
|
||||
/**
|
||||
* Save sync state value
|
||||
*/
|
||||
async setSyncState(key, value) {
|
||||
const db = this.ensureDB();
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([IndexedDBService.SYNC_STATE_STORE], 'readwrite');
|
||||
const store = transaction.objectStore(IndexedDBService.SYNC_STATE_STORE);
|
||||
const request = store.put({ key, value });
|
||||
request.onsuccess = () => {
|
||||
resolve();
|
||||
};
|
||||
request.onerror = () => {
|
||||
reject(new Error(`Failed to set sync state ${key}: ${request.error}`));
|
||||
};
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Get sync state value
|
||||
*/
|
||||
async getSyncState(key) {
|
||||
const db = this.ensureDB();
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = db.transaction([IndexedDBService.SYNC_STATE_STORE], 'readonly');
|
||||
const store = transaction.objectStore(IndexedDBService.SYNC_STATE_STORE);
|
||||
const request = store.get(key);
|
||||
request.onsuccess = () => {
|
||||
const result = request.result;
|
||||
resolve(result ? result.value : null);
|
||||
};
|
||||
request.onerror = () => {
|
||||
reject(new Error(`Failed to get sync state ${key}: ${request.error}`));
|
||||
};
|
||||
});
|
||||
}
|
||||
// ========================================
|
||||
// Serialization Helpers
|
||||
// ========================================
|
||||
/**
|
||||
* Serialize event for IndexedDB storage (convert Dates to ISO strings)
|
||||
*/
|
||||
serializeEvent(event) {
|
||||
return {
|
||||
...event,
|
||||
start: event.start instanceof Date ? event.start.toISOString() : event.start,
|
||||
end: event.end instanceof Date ? event.end.toISOString() : event.end
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Deserialize event from IndexedDB (convert ISO strings to Dates)
|
||||
*/
|
||||
deserializeEvent(event) {
|
||||
return {
|
||||
...event,
|
||||
start: typeof event.start === 'string' ? new Date(event.start) : event.start,
|
||||
end: typeof event.end === 'string' ? new Date(event.end) : event.end
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Close database connection
|
||||
*/
|
||||
close() {
|
||||
if (this.db) {
|
||||
this.db.close();
|
||||
this.db = null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Delete entire database (for testing/reset)
|
||||
*/
|
||||
static async deleteDatabase() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = indexedDB.deleteDatabase(IndexedDBService.DB_NAME);
|
||||
request.onsuccess = () => {
|
||||
resolve();
|
||||
};
|
||||
request.onerror = () => {
|
||||
reject(new Error(`Failed to delete database: ${request.error}`));
|
||||
};
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Seed IndexedDB with mock data if empty
|
||||
*/
|
||||
async seedIfEmpty(mockDataUrl = 'data/mock-events.json') {
|
||||
try {
|
||||
const existingEvents = await this.getAllEvents();
|
||||
if (existingEvents.length > 0) {
|
||||
console.log(`IndexedDB already has ${existingEvents.length} events - skipping seed`);
|
||||
return;
|
||||
}
|
||||
console.log('IndexedDB is empty - seeding with mock data');
|
||||
// Check if online to fetch mock data
|
||||
if (!navigator.onLine) {
|
||||
console.warn('Offline and IndexedDB empty - starting with no events');
|
||||
return;
|
||||
}
|
||||
// Fetch mock events
|
||||
const response = await fetch(mockDataUrl);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch mock events: ${response.statusText}`);
|
||||
}
|
||||
const mockEvents = await response.json();
|
||||
// Convert and save to IndexedDB
|
||||
for (const event of mockEvents) {
|
||||
const calendarEvent = {
|
||||
...event,
|
||||
start: new Date(event.start),
|
||||
end: new Date(event.end),
|
||||
allDay: event.allDay || false,
|
||||
syncStatus: 'synced'
|
||||
};
|
||||
await this.saveEvent(calendarEvent);
|
||||
}
|
||||
console.log(`Seeded IndexedDB with ${mockEvents.length} mock events`);
|
||||
}
|
||||
catch (error) {
|
||||
console.error('Failed to seed IndexedDB:', error);
|
||||
// Don't throw - allow app to start with empty calendar
|
||||
}
|
||||
}
|
||||
}
|
||||
IndexedDBService.DB_NAME = 'CalendarDB';
|
||||
IndexedDBService.DB_VERSION = 1;
|
||||
IndexedDBService.EVENTS_STORE = 'events';
|
||||
IndexedDBService.QUEUE_STORE = 'operationQueue';
|
||||
IndexedDBService.SYNC_STATE_STORE = 'syncState';
|
||||
//# sourceMappingURL=IndexedDBService.js.map
|
||||
1
wwwroot/js/storage/IndexedDBService.js.map
Normal file
1
wwwroot/js/storage/IndexedDBService.js.map
Normal file
File diff suppressed because one or more lines are too long
55
wwwroot/js/storage/OperationQueue.d.ts
vendored
Normal file
55
wwwroot/js/storage/OperationQueue.d.ts
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import { IndexedDBService, IQueueOperation } from './IndexedDBService';
|
||||
/**
|
||||
* Operation Queue Manager
|
||||
* Handles FIFO queue of pending sync operations
|
||||
*/
|
||||
export declare class OperationQueue {
|
||||
private indexedDB;
|
||||
constructor(indexedDB: IndexedDBService);
|
||||
/**
|
||||
* Add operation to the end of the queue
|
||||
*/
|
||||
enqueue(operation: Omit<IQueueOperation, 'id'>): Promise<void>;
|
||||
/**
|
||||
* Get the first operation from the queue (without removing it)
|
||||
* Returns null if queue is empty
|
||||
*/
|
||||
peek(): Promise<IQueueOperation | null>;
|
||||
/**
|
||||
* Get all operations in the queue (sorted by timestamp FIFO)
|
||||
*/
|
||||
getAll(): Promise<IQueueOperation[]>;
|
||||
/**
|
||||
* Remove a specific operation from the queue
|
||||
*/
|
||||
remove(operationId: string): Promise<void>;
|
||||
/**
|
||||
* Remove the first operation from the queue and return it
|
||||
* Returns null if queue is empty
|
||||
*/
|
||||
dequeue(): Promise<IQueueOperation | null>;
|
||||
/**
|
||||
* Clear all operations from the queue
|
||||
*/
|
||||
clear(): Promise<void>;
|
||||
/**
|
||||
* Get the number of operations in the queue
|
||||
*/
|
||||
size(): Promise<number>;
|
||||
/**
|
||||
* Check if queue is empty
|
||||
*/
|
||||
isEmpty(): Promise<boolean>;
|
||||
/**
|
||||
* Get operations for a specific event ID
|
||||
*/
|
||||
getOperationsForEvent(eventId: string): Promise<IQueueOperation[]>;
|
||||
/**
|
||||
* Remove all operations for a specific event ID
|
||||
*/
|
||||
removeOperationsForEvent(eventId: string): Promise<void>;
|
||||
/**
|
||||
* Update retry count for an operation
|
||||
*/
|
||||
incrementRetryCount(operationId: string): Promise<void>;
|
||||
}
|
||||
96
wwwroot/js/storage/OperationQueue.js
Normal file
96
wwwroot/js/storage/OperationQueue.js
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* Operation Queue Manager
|
||||
* Handles FIFO queue of pending sync operations
|
||||
*/
|
||||
export class OperationQueue {
|
||||
constructor(indexedDB) {
|
||||
this.indexedDB = indexedDB;
|
||||
}
|
||||
/**
|
||||
* Add operation to the end of the queue
|
||||
*/
|
||||
async enqueue(operation) {
|
||||
await this.indexedDB.addToQueue(operation);
|
||||
}
|
||||
/**
|
||||
* Get the first operation from the queue (without removing it)
|
||||
* Returns null if queue is empty
|
||||
*/
|
||||
async peek() {
|
||||
const queue = await this.indexedDB.getQueue();
|
||||
return queue.length > 0 ? queue[0] : null;
|
||||
}
|
||||
/**
|
||||
* Get all operations in the queue (sorted by timestamp FIFO)
|
||||
*/
|
||||
async getAll() {
|
||||
return await this.indexedDB.getQueue();
|
||||
}
|
||||
/**
|
||||
* Remove a specific operation from the queue
|
||||
*/
|
||||
async remove(operationId) {
|
||||
await this.indexedDB.removeFromQueue(operationId);
|
||||
}
|
||||
/**
|
||||
* Remove the first operation from the queue and return it
|
||||
* Returns null if queue is empty
|
||||
*/
|
||||
async dequeue() {
|
||||
const operation = await this.peek();
|
||||
if (operation) {
|
||||
await this.remove(operation.id);
|
||||
}
|
||||
return operation;
|
||||
}
|
||||
/**
|
||||
* Clear all operations from the queue
|
||||
*/
|
||||
async clear() {
|
||||
await this.indexedDB.clearQueue();
|
||||
}
|
||||
/**
|
||||
* Get the number of operations in the queue
|
||||
*/
|
||||
async size() {
|
||||
const queue = await this.getAll();
|
||||
return queue.length;
|
||||
}
|
||||
/**
|
||||
* Check if queue is empty
|
||||
*/
|
||||
async isEmpty() {
|
||||
const size = await this.size();
|
||||
return size === 0;
|
||||
}
|
||||
/**
|
||||
* Get operations for a specific event ID
|
||||
*/
|
||||
async getOperationsForEvent(eventId) {
|
||||
const queue = await this.getAll();
|
||||
return queue.filter(op => op.eventId === eventId);
|
||||
}
|
||||
/**
|
||||
* Remove all operations for a specific event ID
|
||||
*/
|
||||
async removeOperationsForEvent(eventId) {
|
||||
const operations = await this.getOperationsForEvent(eventId);
|
||||
for (const op of operations) {
|
||||
await this.remove(op.id);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Update retry count for an operation
|
||||
*/
|
||||
async incrementRetryCount(operationId) {
|
||||
const queue = await this.getAll();
|
||||
const operation = queue.find(op => op.id === operationId);
|
||||
if (operation) {
|
||||
operation.retryCount++;
|
||||
// Re-add to queue with updated retry count
|
||||
await this.remove(operationId);
|
||||
await this.enqueue(operation);
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=OperationQueue.js.map
|
||||
1
wwwroot/js/storage/OperationQueue.js.map
Normal file
1
wwwroot/js/storage/OperationQueue.js.map
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"OperationQueue.js","sourceRoot":"","sources":["../../../src/storage/OperationQueue.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,cAAc;IAGzB,YAAY,SAA2B;QACrC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,SAAsC;QAClD,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM;QACV,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,WAAmB;QAC9B,MAAM,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;IACpD,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAO;QACX,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACpC,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC,MAAM,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,OAAO,IAAI,KAAK,CAAC,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,qBAAqB,CAAC,OAAe;QACzC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,wBAAwB,CAAC,OAAe;QAC5C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC7D,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,mBAAmB,CAAC,WAAmB;QAC3C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC;QAE1D,IAAI,SAAS,EAAE,CAAC;YACd,SAAS,CAAC,UAAU,EAAE,CAAC;YACvB,2CAA2C;YAC3C,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAC/B,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;CACF"}
|
||||
Loading…
Add table
Add a link
Reference in a new issue