8.1 原生API概述

8.1.1 Sciter原生API简介

Sciter提供了丰富的原生API,允许开发者在TIScript中直接调用系统级功能,这使得Sciter应用能够:

  • 文件系统操作:读写文件、目录遍历、文件监控
  • 网络通信:HTTP请求、WebSocket连接、TCP/UDP通信
  • 系统集成:系统通知、托盘图标、剪贴板操作
  • 硬件访问:摄像头、麦克风、传感器数据
  • 进程管理:启动外部程序、进程间通信
  • 数据库连接:SQLite、ODBC数据库操作

8.1.2 API分类

// Sciter原生API命名空间
namespace SciterAPI {
    // 文件系统API
    var FileSystem = {
        // 文件操作
        readFile: function(path, encoding) { /* ... */ },
        writeFile: function(path, content, encoding) { /* ... */ },
        deleteFile: function(path) { /* ... */ },
        copyFile: function(src, dest) { /* ... */ },
        moveFile: function(src, dest) { /* ... */ },
        
        // 目录操作
        createDirectory: function(path) { /* ... */ },
        removeDirectory: function(path) { /* ... */ },
        listDirectory: function(path) { /* ... */ },
        
        // 文件信息
        getFileInfo: function(path) { /* ... */ },
        exists: function(path) { /* ... */ },
        isFile: function(path) { /* ... */ },
        isDirectory: function(path) { /* ... */ }
    };
    
    // 网络API
    var Network = {
        // HTTP请求
        httpGet: function(url, options) { /* ... */ },
        httpPost: function(url, data, options) { /* ... */ },
        httpRequest: function(method, url, options) { /* ... */ },
        
        // WebSocket
        createWebSocket: function(url, protocols) { /* ... */ },
        
        // 下载
        downloadFile: function(url, localPath, options) { /* ... */ }
    };
    
    // 系统API
    var System = {
        // 系统信息
        getSystemInfo: function() { /* ... */ },
        getEnvironmentVariable: function(name) { /* ... */ },
        setEnvironmentVariable: function(name, value) { /* ... */ },
        
        // 进程管理
        executeProcess: function(command, args, options) { /* ... */ },
        killProcess: function(pid) { /* ... */ },
        
        // 系统通知
        showNotification: function(title, message, options) { /* ... */ },
        
        // 剪贴板
        getClipboardText: function() { /* ... */ },
        setClipboardText: function(text) { /* ... */ }
    };
    
    // 数据库API
    var Database = {
        // SQLite
        openSQLite: function(path) { /* ... */ },
        
        // ODBC
        openODBC: function(connectionString) { /* ... */ }
    };
}

8.3.2 WebSocket通信

// WebSocket客户端管理器
class WebSocketClient {
    function this(url, protocols = []) {
        this.url = url;
        this.protocols = protocols;
        this.ws = null;
        this.reconnectAttempts = 0;
        this.maxReconnectAttempts = 5;
        this.reconnectInterval = 1000;
        this.heartbeatInterval = 30000;
        this.heartbeatTimer = null;
        this.messageQueue = [];
        this.eventHandlers = {
            open: [],
            message: [],
            close: [],
            error: [],
            reconnect: []
        };
    }
    
    // 连接WebSocket
    function connect() {
        return new Promise(function(resolve, reject) {
            try {
                this.ws = new WebSocket(this.url, this.protocols);
                
                this.ws.onopen = function(event) {
                    stdout.println('WebSocket连接已建立');
                    this.reconnectAttempts = 0;
                    
                    // 发送队列中的消息
                    this.flushMessageQueue();
                    
                    // 启动心跳
                    this.startHeartbeat();
                    
                    // 触发事件
                    this.emit('open', event);
                    
                    resolve(event);
                }.bind(this);
                
                this.ws.onmessage = function(event) {
                    var message = this.parseMessage(event.data);
                    this.emit('message', message);
                }.bind(this);
                
                this.ws.onclose = function(event) {
                    stdout.println('WebSocket连接已关闭:', event.code, event.reason);
                    
                    this.stopHeartbeat();
                    this.emit('close', event);
                    
                    // 自动重连
                    if (!event.wasClean && this.reconnectAttempts < this.maxReconnectAttempts) {
                        this.scheduleReconnect();
                    }
                }.bind(this);
                
                this.ws.onerror = function(event) {
                    stdout.println('WebSocket错误:', event);
                    this.emit('error', event);
                    reject(event);
                }.bind(this);
            } catch (error) {
                reject(error);
            }
        }.bind(this));
    }
    
    // 发送消息
    function send(data, type = 'text') {
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
            var message = this.formatMessage(data, type);
            this.ws.send(message);
            return true;
        } else {
            // 连接未建立,加入队列
            this.messageQueue.push({ data: data, type: type });
            return false;
        }
    }
    
    // 发送JSON消息
    function sendJSON(data) {
        return this.send(JSON.stringify(data), 'json');
    }
    
    // 发送二进制消息
    function sendBinary(data) {
        return this.send(data, 'binary');
    }
    
    // 关闭连接
    function close(code = 1000, reason = '') {
        if (this.ws) {
            this.stopHeartbeat();
            this.ws.close(code, reason);
        }
    }
    
    // 添加事件监听器
    function on(event, handler) {
        if (this.eventHandlers[event]) {
            this.eventHandlers[event].push(handler);
        }
    }
    
    // 移除事件监听器
    function off(event, handler) {
        if (this.eventHandlers[event]) {
            var index = this.eventHandlers[event].indexOf(handler);
            if (index !== -1) {
                this.eventHandlers[event].splice(index, 1);
            }
        }
    }
    
    // 触发事件
    function emit(event, data) {
        if (this.eventHandlers[event]) {
            for (var handler of this.eventHandlers[event]) {
                try {
                    handler(data);
                } catch (error) {
                    stdout.println('WebSocket事件处理错误:', error.message);
                }
            }
        }
    }
    
    // 解析消息
    function parseMessage(data) {
        try {
            // 尝试解析为JSON
            var parsed = JSON.parse(data);
            return {
                type: 'json',
                data: parsed,
                raw: data
            };
        } catch (e) {
            // 普通文本消息
            return {
                type: 'text',
                data: data,
                raw: data
            };
        }
    }
    
    // 格式化消息
    function formatMessage(data, type) {
        switch (type) {
            case 'json':
                return JSON.stringify(data);
            case 'binary':
                return data;
            default:
                return String(data);
        }
    }
    
    // 清空消息队列
    function flushMessageQueue() {
        while (this.messageQueue.length > 0) {
            var message = this.messageQueue.shift();
            this.send(message.data, message.type);
        }
    }
    
    // 启动心跳
    function startHeartbeat() {
        this.stopHeartbeat();
        
        this.heartbeatTimer = setInterval(function() {
            if (this.ws && this.ws.readyState === WebSocket.OPEN) {
                this.send('ping', 'heartbeat');
            }
        }.bind(this), this.heartbeatInterval);
    }
    
    // 停止心跳
    function stopHeartbeat() {
        if (this.heartbeatTimer) {
            clearInterval(this.heartbeatTimer);
            this.heartbeatTimer = null;
        }
    }
    
    // 安排重连
    function scheduleReconnect() {
        this.reconnectAttempts++;
        
        var delay = this.reconnectInterval * Math.pow(2, this.reconnectAttempts - 1);
        
        stdout.println(`WebSocket重连尝试 ${this.reconnectAttempts}/${this.maxReconnectAttempts},${delay}ms后重连`);
        
        setTimeout(function() {
            this.emit('reconnect', {
                attempt: this.reconnectAttempts,
                maxAttempts: this.maxReconnectAttempts
            });
            
            this.connect().catch(function(error) {
                stdout.println('重连失败:', error);
            });
        }.bind(this), delay);
    }
    
    // 获取连接状态
    function getState() {
        if (!this.ws) {
            return 'DISCONNECTED';
        }
        
        switch (this.ws.readyState) {
            case WebSocket.CONNECTING:
                return 'CONNECTING';
            case WebSocket.OPEN:
                return 'OPEN';
            case WebSocket.CLOSING:
                return 'CLOSING';
            case WebSocket.CLOSED:
                return 'CLOSED';
            default:
                return 'UNKNOWN';
        }
    }
    
    // 获取连接信息
    function getInfo() {
        return {
            url: this.url,
            protocols: this.protocols,
            state: this.getState(),
            reconnectAttempts: this.reconnectAttempts,
            queuedMessages: this.messageQueue.length
        };
    }
}

// WebSocket服务器(用于测试)
class WebSocketServer {
    function this(port = 8080) {
        this.port = port;
        this.server = null;
        this.clients = new Set();
        this.messageHandlers = new Map();
    }
    
    // 启动服务器
    function start() {
        return new Promise(function(resolve, reject) {
            try {
                // 使用Sciter的WebSocket服务器API
                this.server = System.net.createWebSocketServer({
                    port: this.port,
                    onConnection: this.handleConnection.bind(this),
                    onError: function(error) {
                        stdout.println('WebSocket服务器错误:', error);
                        reject(error);
                    }
                });
                
                stdout.println('WebSocket服务器启动,端口:', this.port);
                resolve();
            } catch (error) {
                reject(error);
            }
        }.bind(this));
    }
    
    // 处理新连接
    function handleConnection(client) {
        stdout.println('新的WebSocket连接');
        
        this.clients.add(client);
        
        client.on('message', function(data) {
            this.handleMessage(client, data);
        }.bind(this));
        
        client.on('close', function() {
            stdout.println('WebSocket连接关闭');
            this.clients.delete(client);
        }.bind(this));
        
        client.on('error', function(error) {
            stdout.println('WebSocket客户端错误:', error);
            this.clients.delete(client);
        }.bind(this));
    }
    
    // 处理消息
    function handleMessage(client, data) {
        try {
            var message = JSON.parse(data);
            var handler = this.messageHandlers.get(message.type);
            
            if (handler) {
                handler(client, message.data);
            } else {
                // 默认回显消息
                client.send(JSON.stringify({
                    type: 'echo',
                    data: message
                }));
            }
        } catch (error) {
            stdout.println('消息处理错误:', error.message);
        }
    }
    
    // 注册消息处理器
    function onMessage(type, handler) {
        this.messageHandlers.set(type, handler);
    }
    
    // 广播消息
    function broadcast(data) {
        var message = JSON.stringify(data);
        
        for (var client of this.clients) {
            try {
                client.send(message);
            } catch (error) {
                stdout.println('广播消息失败:', error.message);
                this.clients.delete(client);
            }
        }
    }
    
    // 停止服务器
    function stop() {
        if (this.server) {
            this.server.close();
            this.server = null;
        }
        
        // 关闭所有客户端连接
        for (var client of this.clients) {
            client.close();
        }
        
        this.clients.clear();
    }
}

// 使用示例
function webSocketExample() {
    // 创建WebSocket客户端
    var client = new WebSocketClient('ws://localhost:8080');
    
    // 添加事件监听器
    client.on('open', function(event) {
        stdout.println('连接已建立');
        
        // 发送测试消息
        client.sendJSON({
            type: 'greeting',
            message: 'Hello, WebSocket!'
        });
    });
    
    client.on('message', function(message) {
        stdout.println('收到消息:', message.type, message.data);
    });
    
    client.on('close', function(event) {
        stdout.println('连接已关闭:', event.code, event.reason);
    });
    
    client.on('error', function(error) {
        stdout.println('连接错误:', error);
    });
    
    client.on('reconnect', function(info) {
        stdout.println('正在重连:', info.attempt, '/', info.maxAttempts);
    });
    
    // 连接到服务器
    client.connect()
        .then(function() {
            stdout.println('WebSocket客户端连接成功');
        })
        .catch(function(error) {
            stdout.println('WebSocket客户端连接失败:', error);
        });
    
    // 定期发送消息
    setInterval(function() {
        if (client.getState() === 'OPEN') {
            client.sendJSON({
                type: 'ping',
                timestamp: Date.now()
            });
        }
    }, 5000);
    
    // 10秒后关闭连接
    setTimeout(function() {
        client.close();
    }, 10000);
}

8.4 系统通知和托盘

8.4.1 系统通知

// 系统通知管理器
class NotificationManager {
    function this() {
        this.notifications = new Map();
        this.notificationId = 0;
        this.defaultOptions = {
            icon: null,
            timeout: 5000,
            persistent: false,
            actions: [],
            sound: true
        };
    }
    
    // 显示通知
    function show(title, message, options = {}) {
        try {
            var config = Object.assign({}, this.defaultOptions, options);
            var notificationId = ++this.notificationId;
            
            // 创建通知对象
            var notification = {
                id: notificationId,
                title: title,
                message: message,
                options: config,
                timestamp: new Date(),
                dismissed: false
            };
            
            // 使用Sciter的系统通知API
            var systemNotification = System.notification.show({
                title: title,
                body: message,
                icon: config.icon,
                timeout: config.persistent ? 0 : config.timeout,
                actions: config.actions,
                sound: config.sound,
                onClick: function() {
                    this.handleNotificationClick(notification);
                }.bind(this),
                onClose: function() {
                    this.handleNotificationClose(notification);
                }.bind(this),
                onAction: function(actionId) {
                    this.handleNotificationAction(notification, actionId);
                }.bind(this)
            });
            
            notification.systemNotification = systemNotification;
            this.notifications.set(notificationId, notification);
            
            // 自动清理非持久通知
            if (!config.persistent && config.timeout > 0) {
                setTimeout(function() {
                    this.dismiss(notificationId);
                }.bind(this), config.timeout);
            }
            
            return {
                success: true,
                notificationId: notificationId,
                notification: notification
            };
        } catch (error) {
            return {
                success: false,
                error: error.message
            };
        }
    }
    
    // 处理通知点击
    function handleNotificationClick(notification) {
        stdout.println('通知被点击:', notification.title);
        
        if (notification.options.onClick) {
            notification.options.onClick(notification);
        }
        
        // 默认行为:关闭通知
        this.dismiss(notification.id);
    }
    
    // 处理通知关闭
    function handleNotificationClose(notification) {
        stdout.println('通知被关闭:', notification.title);
        
        if (notification.options.onClose) {
            notification.options.onClose(notification);
        }
        
        this.notifications.delete(notification.id);
    }
    
    // 处理通知动作
    function handleNotificationAction(notification, actionId) {
        stdout.println('通知动作被触发:', notification.title, actionId);
        
        var action = notification.options.actions.find(a => a.id === actionId);
        if (action && action.handler) {
            action.handler(notification, actionId);
        }
    }
    
    // 关闭通知
    function dismiss(notificationId) {
        var notification = this.notifications.get(notificationId);
        if (notification && !notification.dismissed) {
            notification.dismissed = true;
            
            if (notification.systemNotification) {
                notification.systemNotification.close();
            }
            
            this.notifications.delete(notificationId);
            
            return {
                success: true,
                notificationId: notificationId
            };
        }
        
        return {
            success: false,
            error: '通知不存在或已关闭',
            notificationId: notificationId
        };
    }
    
    // 关闭所有通知
    function dismissAll() {
        var dismissed = [];
        
        for (var [id, notification] of this.notifications) {
            var result = this.dismiss(id);
            dismissed.push(result);
        }
        
        return {
            success: true,
            dismissed: dismissed
        };
    }
    
    // 获取活动通知列表
    function getActiveNotifications() {
        var active = [];
        
        for (var [id, notification] of this.notifications) {
            if (!notification.dismissed) {
                active.push({
                    id: notification.id,
                    title: notification.title,
                    message: notification.message,
                    timestamp: notification.timestamp
                });
            }
        }
        
        return {
            success: true,
            notifications: active,
            count: active.length
        };
    }
    
    // 检查通知权限
    function checkPermission() {
        try {
            var permission = System.notification.permission;
            
            return {
                success: true,
                permission: permission, // granted, denied, default
                supported: System.notification.supported
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                supported: false
            };
        }
    }
    
    // 请求通知权限
    function requestPermission() {
        return new Promise(function(resolve, reject) {
            try {
                System.notification.requestPermission(function(permission) {
                    resolve({
                        success: true,
                        permission: permission
                    });
                });
            } catch (error) {
                reject({
                    success: false,
                    error: error.message
                });
            }
        });
    }
    
    // 预定义通知类型
    function showInfo(title, message, options = {}) {
        return this.show(title, message, Object.assign({
            icon: 'info',
            sound: false
        }, options));
    }
    
    function showWarning(title, message, options = {}) {
        return this.show(title, message, Object.assign({
            icon: 'warning',
            sound: true,
            timeout: 8000
        }, options));
    }
    
    function showError(title, message, options = {}) {
        return this.show(title, message, Object.assign({
            icon: 'error',
            sound: true,
            persistent: true,
            actions: [
                {
                    id: 'dismiss',
                    title: '关闭',
                    handler: function(notification) {
                        // 自动关闭
                    }
                }
            ]
        }, options));
    }
    
    function showSuccess(title, message, options = {}) {
        return this.show(title, message, Object.assign({
            icon: 'success',
            sound: false,
            timeout: 3000
        }, options));
    }
}

// 使用示例
function notificationExample() {
    var notificationManager = new NotificationManager();
    
    // 检查通知权限
    var permissionResult = notificationManager.checkPermission();
    stdout.println('通知权限状态:', JSON.stringify(permissionResult, null, 2));
    
    if (permissionResult.permission !== 'granted') {
        // 请求通知权限
        notificationManager.requestPermission()
            .then(function(result) {
                stdout.println('权限请求结果:', JSON.stringify(result, null, 2));
                
                if (result.permission === 'granted') {
                    showTestNotifications();
                }
            })
            .catch(function(error) {
                stdout.println('权限请求失败:', error);
            });
    } else {
        showTestNotifications();
    }
    
    function showTestNotifications() {
        // 显示信息通知
        notificationManager.showInfo('信息', '这是一条信息通知');
        
        // 显示警告通知
        setTimeout(function() {
            notificationManager.showWarning('警告', '这是一条警告通知');
        }, 2000);
        
        // 显示错误通知
        setTimeout(function() {
            notificationManager.showError('错误', '这是一条错误通知', {
                onClick: function(notification) {
                    stdout.println('错误通知被点击');
                }
            });
        }, 4000);
        
        // 显示成功通知
        setTimeout(function() {
            notificationManager.showSuccess('成功', '操作完成');
        }, 6000);
        
        // 显示带动作的通知
        setTimeout(function() {
            notificationManager.show('任务完成', '文件下载已完成', {
                persistent: true,
                actions: [
                    {
                        id: 'open',
                        title: '打开文件',
                        handler: function(notification) {
                            stdout.println('打开文件');
                        }
                    },
                    {
                        id: 'folder',
                        title: '打开文件夹',
                        handler: function(notification) {
                            stdout.println('打开文件夹');
                        }
                    }
                ]
            });
        }, 8000);
    }
    
    // 10秒后关闭所有通知
    setTimeout(function() {
        var result = notificationManager.dismissAll();
        stdout.println('关闭所有通知:', JSON.stringify(result, null, 2));
    }, 10000);
}

8.4.2 系统托盘

// 系统托盘管理器
class TrayManager {
    function this() {
        this.tray = null;
        this.menu = null;
        this.isVisible = false;
        this.blinkTimer = null;
        this.contextMenu = [];
    }
    
    // 创建托盘图标
    function create(options = {}) {
        try {
            var {
                icon = 'app-icon.png',
                tooltip = 'Sciter Application',
                visible = true
            } = options;
            
            // 使用Sciter的系统托盘API
            this.tray = System.tray.create({
                icon: icon,
                tooltip: tooltip,
                visible: visible,
                onClick: this.handleClick.bind(this),
                onDoubleClick: this.handleDoubleClick.bind(this),
                onRightClick: this.handleRightClick.bind(this)
            });
            
            this.isVisible = visible;
            
            return {
                success: true,
                tray: this.tray
            };
        } catch (error) {
            return {
                success: false,
                error: error.message
            };
        }
    }
    
    // 处理单击事件
    function handleClick(event) {
        stdout.println('托盘图标被单击');
        
        // 默认行为:显示/隐藏主窗口
        var mainWindow = view.windowState;
        if (mainWindow === 'minimized' || mainWindow === 'hidden') {
            view.windowState = 'normal';
            view.focus();
        } else {
            view.windowState = 'minimized';
        }
    }
    
    // 处理双击事件
    function handleDoubleClick(event) {
        stdout.println('托盘图标被双击');
        
        // 默认行为:恢复并激活主窗口
        view.windowState = 'normal';
        view.focus();
    }
    
    // 处理右键点击事件
    function handleRightClick(event) {
        stdout.println('托盘图标被右键点击');
        
        if (this.contextMenu.length > 0) {
            this.showContextMenu();
        }
    }
    
    // 设置图标
    function setIcon(iconPath) {
        if (this.tray) {
            try {
                this.tray.setIcon(iconPath);
                return { success: true };
            } catch (error) {
                return {
                    success: false,
                    error: error.message
                };
            }
        }
        
        return {
            success: false,
            error: '托盘未创建'
        };
    }
    
    // 设置提示文本
    function setTooltip(tooltip) {
        if (this.tray) {
            try {
                this.tray.setTooltip(tooltip);
                return { success: true };
            } catch (error) {
                return {
                    success: false,
                    error: error.message
                };
            }
        }
        
        return {
            success: false,
            error: '托盘未创建'
        };
    }
    
    // 显示托盘图标
    function show() {
        if (this.tray) {
            this.tray.setVisible(true);
            this.isVisible = true;
            return { success: true };
        }
        
        return {
            success: false,
            error: '托盘未创建'
        };
    }
    
    // 隐藏托盘图标
    function hide() {
        if (this.tray) {
            this.tray.setVisible(false);
            this.isVisible = false;
            return { success: true };
        }
        
        return {
            success: false,
            error: '托盘未创建'
        };
    }
    
    // 闪烁托盘图标
    function blink(duration = 3000, interval = 500) {
        if (!this.tray) {
            return {
                success: false,
                error: '托盘未创建'
            };
        }
        
        this.stopBlink();
        
        var originalIcon = this.tray.getIcon();
        var blinkIcon = 'blink-icon.png'; // 闪烁时的图标
        var isOriginal = true;
        
        this.blinkTimer = setInterval(function() {
            if (isOriginal) {
                this.tray.setIcon(blinkIcon);
            } else {
                this.tray.setIcon(originalIcon);
            }
            isOriginal = !isOriginal;
        }.bind(this), interval);
        
        // 指定时间后停止闪烁
        setTimeout(function() {
            this.stopBlink();
            this.tray.setIcon(originalIcon);
        }.bind(this), duration);
        
        return { success: true };
    }
    
    // 停止闪烁
    function stopBlink() {
        if (this.blinkTimer) {
            clearInterval(this.blinkTimer);
            this.blinkTimer = null;
        }
    }
    
    // 设置上下文菜单
    function setContextMenu(menuItems) {
        this.contextMenu = menuItems;
        
        if (this.tray) {
            this.menu = this.buildMenu(menuItems);
            return { success: true };
        }
        
        return {
            success: false,
            error: '托盘未创建'
        };
    }
    
    // 构建菜单
    function buildMenu(items) {
        var menu = [];
        
        for (var item of items) {
            if (item.type === 'separator') {
                menu.push({ type: 'separator' });
            } else {
                menu.push({
                    id: item.id,
                    text: item.text,
                    enabled: item.enabled !== false,
                    checked: item.checked || false,
                    icon: item.icon,
                    submenu: item.submenu ? this.buildMenu(item.submenu) : null,
                    onClick: item.onClick
                });
            }
        }
        
        return menu;
    }
    
    // 显示上下文菜单
    function showContextMenu() {
        if (this.tray && this.menu) {
            this.tray.showContextMenu(this.menu);
        }
    }
    
    // 显示气泡提示
    function showBalloon(title, message, options = {}) {
        if (!this.tray) {
            return {
                success: false,
                error: '托盘未创建'
            };
        }
        
        var {
            icon = 'info', // info, warning, error
            timeout = 5000,
            onClick = null
        } = options;
        
        try {
            this.tray.showBalloon({
                title: title,
                text: message,
                icon: icon,
                timeout: timeout,
                onClick: onClick
            });
            
            return { success: true };
        } catch (error) {
            return {
                success: false,
                error: error.message
            };
        }
    }
    
    // 销毁托盘图标
    function destroy() {
        this.stopBlink();
        
        if (this.tray) {
            this.tray.destroy();
            this.tray = null;
            this.menu = null;
            this.isVisible = false;
            
            return { success: true };
        }
        
        return {
            success: false,
            error: '托盘未创建'
        };
    }
    
    // 获取托盘状态
    function getStatus() {
        return {
            created: this.tray !== null,
            visible: this.isVisible,
            blinking: this.blinkTimer !== null,
            hasContextMenu: this.contextMenu.length > 0
        };
    }
}

// 使用示例
function trayExample() {
    var trayManager = new TrayManager();
    
    // 创建托盘图标
    var createResult = trayManager.create({
        icon: 'assets/app-icon.png',
        tooltip: 'Sciter应用程序',
        visible: true
    });
    
    if (createResult.success) {
        stdout.println('托盘图标创建成功');
        
        // 设置上下文菜单
        trayManager.setContextMenu([
            {
                id: 'show',
                text: '显示窗口',
                onClick: function() {
                    view.windowState = 'normal';
                    view.focus();
                }
            },
            {
                id: 'hide',
                text: '隐藏窗口',
                onClick: function() {
                    view.windowState = 'minimized';
                }
            },
            { type: 'separator' },
            {
                id: 'settings',
                text: '设置',
                icon: 'settings-icon.png',
                submenu: [
                    {
                        id: 'general',
                        text: '常规设置',
                        onClick: function() {
                            stdout.println('打开常规设置');
                        }
                    },
                    {
                        id: 'advanced',
                        text: '高级设置',
                        onClick: function() {
                            stdout.println('打开高级设置');
                        }
                    }
                ]
            },
            {
                id: 'about',
                text: '关于',
                onClick: function() {
                    trayManager.showBalloon('关于', 'Sciter应用程序 v1.0', {
                        icon: 'info'
                    });
                }
            },
            { type: 'separator' },
            {
                id: 'exit',
                text: '退出',
                onClick: function() {
                    // 确认退出
                    var result = view.msgbox({
                        type: 'question',
                        title: '确认退出',
                        text: '确定要退出应用程序吗?',
                        buttons: ['是', '否']
                    });
                    
                    if (result === 0) {
                        trayManager.destroy();
                        view.close();
                    }
                }
            }
        ]);
        
        // 测试气泡提示
        setTimeout(function() {
            trayManager.showBalloon('欢迎', '应用程序已最小化到系统托盘', {
                icon: 'info',
                timeout: 3000
            });
        }, 2000);
        
        // 测试闪烁
        setTimeout(function() {
            trayManager.blink(2000, 300);
        }, 5000);
        
        // 监听窗口最小化事件
        view.on('statechange', function(event) {
            if (event.detail.state === 'minimized') {
                trayManager.showBalloon('最小化', '应用程序已最小化到托盘', {
                    icon: 'info',
                    timeout: 2000
                });
            }
        });
    } else {
        stdout.println('托盘图标创建失败:', createResult.error);
    }
}

8.5 数据库操作

8.5.1 SQLite数据库

// SQLite数据库管理器
class SQLiteManager {
    function this(dbPath) {
        this.dbPath = dbPath;
        this.db = null;
        this.isConnected = false;
        this.transactionLevel = 0;
    }
    
    // 连接数据库
    function connect() {
        try {
            // 使用Sciter的SQLite API
            this.db = System.database.sqlite.open(this.dbPath);
            this.isConnected = true;
            
            stdout.println('SQLite数据库连接成功:', this.dbPath);
            
            return {
                success: true,
                database: this.db
            };
        } catch (error) {
            return {
                success: false,
                error: error.message
            };
        }
    }
    
    // 关闭数据库连接
    function close() {
        if (this.db && this.isConnected) {
            try {
                this.db.close();
                this.isConnected = false;
                this.db = null;
                
                stdout.println('SQLite数据库连接已关闭');
                
                return { success: true };
            } catch (error) {
                return {
                    success: false,
                    error: error.message
                };
            }
        }
        
        return {
            success: false,
            error: '数据库未连接'
        };
    }
    
    // 执行SQL查询
    function query(sql, params = []) {
        if (!this.isConnected) {
            return {
                success: false,
                error: '数据库未连接'
            };
        }
        
        try {
            var statement = this.db.prepare(sql);
            var result;
            
            if (params.length > 0) {
                result = statement.all(params);
            } else {
                result = statement.all();
            }
            
            return {
                success: true,
                data: result,
                rowCount: result.length
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                sql: sql,
                params: params
            };
        }
    }
    
    // 执行SQL命令(INSERT, UPDATE, DELETE)
    function execute(sql, params = []) {
        if (!this.isConnected) {
            return {
                success: false,
                error: '数据库未连接'
            };
        }
        
        try {
            var statement = this.db.prepare(sql);
            var result;
            
            if (params.length > 0) {
                result = statement.run(params);
            } else {
                result = statement.run();
            }
            
            return {
                success: true,
                changes: result.changes,
                lastInsertRowid: result.lastInsertRowid
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                sql: sql,
                params: params
            };
        }
    }
    
    // 开始事务
    function beginTransaction() {
        if (!this.isConnected) {
            return {
                success: false,
                error: '数据库未连接'
            };
        }
        
        try {
            if (this.transactionLevel === 0) {
                this.db.exec('BEGIN TRANSACTION');
            } else {
                // 嵌套事务使用保存点
                this.db.exec(`SAVEPOINT sp${this.transactionLevel}`);
            }
            
            this.transactionLevel++;
            
            return {
                success: true,
                transactionLevel: this.transactionLevel
            };
        } catch (error) {
            return {
                success: false,
                error: error.message
            };
        }
    }
    
    // 提交事务
    function commitTransaction() {
        if (!this.isConnected) {
            return {
                success: false,
                error: '数据库未连接'
            };
        }
        
        if (this.transactionLevel === 0) {
            return {
                success: false,
                error: '没有活动的事务'
            };
        }
        
        try {
            this.transactionLevel--;
            
            if (this.transactionLevel === 0) {
                this.db.exec('COMMIT');
            } else {
                // 释放保存点
                this.db.exec(`RELEASE SAVEPOINT sp${this.transactionLevel}`);
            }
            
            return {
                success: true,
                transactionLevel: this.transactionLevel
            };
        } catch (error) {
            return {
                success: false,
                error: error.message
            };
        }
    }
    
    // 回滚事务
    function rollbackTransaction() {
        if (!this.isConnected) {
            return {
                success: false,
                error: '数据库未连接'
            };
        }
        
        if (this.transactionLevel === 0) {
            return {
                success: false,
                error: '没有活动的事务'
            };
        }
        
        try {
            this.transactionLevel--;
            
            if (this.transactionLevel === 0) {
                this.db.exec('ROLLBACK');
            } else {
                // 回滚到保存点
                this.db.exec(`ROLLBACK TO SAVEPOINT sp${this.transactionLevel}`);
            }
            
            return {
                success: true,
                transactionLevel: this.transactionLevel
            };
        } catch (error) {
            return {
                success: false,
                error: error.message
            };
        }
    }
    
    // 创建表
    function createTable(tableName, columns, options = {}) {
        var {
            ifNotExists = true,
            primaryKey = null,
            indexes = []
        } = options;
        
        var sql = `CREATE TABLE ${ifNotExists ? 'IF NOT EXISTS' : ''} ${tableName} (`;
        
        var columnDefs = [];
        for (var [name, type] of Object.entries(columns)) {
            var columnDef = `${name} ${type}`;
            if (primaryKey === name) {
                columnDef += ' PRIMARY KEY';
            }
            columnDefs.push(columnDef);
        }
        
        sql += columnDefs.join(', ') + ')';
        
        var result = this.execute(sql);
        
        if (result.success && indexes.length > 0) {
            // 创建索引
            for (var index of indexes) {
                var indexSql = `CREATE INDEX IF NOT EXISTS idx_${tableName}_${index.columns.join('_')} ON ${tableName} (${index.columns.join(', ')})`;
                this.execute(indexSql);
            }
        }
        
        return result;
    }
    
    // 插入数据
    function insert(tableName, data) {
        var columns = Object.keys(data);
        var values = Object.values(data);
        var placeholders = columns.map(() => '?').join(', ');
        
        var sql = `INSERT INTO ${tableName} (${columns.join(', ')}) VALUES (${placeholders})`;
        
        return this.execute(sql, values);
    }
    
    // 批量插入数据
    function insertBatch(tableName, dataArray) {
        if (dataArray.length === 0) {
            return {
                success: false,
                error: '数据数组为空'
            };
        }
        
        var beginResult = this.beginTransaction();
        if (!beginResult.success) {
            return beginResult;
        }
        
        try {
            var insertedCount = 0;
            
            for (var data of dataArray) {
                var result = this.insert(tableName, data);
                if (result.success) {
                    insertedCount++;
                } else {
                    this.rollbackTransaction();
                    return {
                        success: false,
                        error: `批量插入失败: ${result.error}`,
                        insertedCount: insertedCount
                    };
                }
            }
            
            var commitResult = this.commitTransaction();
            if (commitResult.success) {
                return {
                    success: true,
                    insertedCount: insertedCount
                };
            } else {
                return commitResult;
            }
        } catch (error) {
            this.rollbackTransaction();
            return {
                success: false,
                error: error.message,
                insertedCount: insertedCount
            };
        }
    }
    
    // 更新数据
    function update(tableName, data, where, whereParams = []) {
        var setClause = Object.keys(data).map(key => `${key} = ?`).join(', ');
        var values = Object.values(data).concat(whereParams);
        
        var sql = `UPDATE ${tableName} SET ${setClause}`;
        if (where) {
            sql += ` WHERE ${where}`;
        }
        
        return this.execute(sql, values);
    }
    
    // 删除数据
    function delete(tableName, where, whereParams = []) {
        var sql = `DELETE FROM ${tableName}`;
        if (where) {
            sql += ` WHERE ${where}`;
        }
        
        return this.execute(sql, whereParams);
    }
    
    // 查询数据
    function select(tableName, options = {}) {
        var {
            columns = '*',
            where = null,
            whereParams = [],
            orderBy = null,
            limit = null,
            offset = null
        } = options;
        
        var sql = `SELECT ${Array.isArray(columns) ? columns.join(', ') : columns} FROM ${tableName}`;
        
        if (where) {
            sql += ` WHERE ${where}`;
        }
        
        if (orderBy) {
            sql += ` ORDER BY ${orderBy}`;
        }
        
        if (limit) {
            sql += ` LIMIT ${limit}`;
            if (offset) {
                sql += ` OFFSET ${offset}`;
            }
        }
        
        return this.query(sql, whereParams);
    }
    
    // 获取表信息
    function getTableInfo(tableName) {
        var result = this.query(`PRAGMA table_info(${tableName})`);
        
        if (result.success) {
            return {
                success: true,
                columns: result.data,
                columnCount: result.data.length
            };
        }
        
        return result;
    }
    
    // 获取数据库信息
    function getDatabaseInfo() {
        try {
            var tablesResult = this.query("SELECT name FROM sqlite_master WHERE type='table'");
            var indexesResult = this.query("SELECT name FROM sqlite_master WHERE type='index'");
            var viewsResult = this.query("SELECT name FROM sqlite_master WHERE type='view'");
            
            return {
                success: true,
                tables: tablesResult.success ? tablesResult.data.map(row => row.name) : [],
                indexes: indexesResult.success ? indexesResult.data.map(row => row.name) : [],
                views: viewsResult.success ? viewsResult.data.map(row => row.name) : [],
                path: this.dbPath,
                connected: this.isConnected
            };
        } catch (error) {
            return {
                success: false,
                error: error.message
            };
        }
    }
    
    // 备份数据库
    function backup(backupPath) {
        if (!this.isConnected) {
            return {
                success: false,
                error: '数据库未连接'
            };
        }
        
        try {
            this.db.backup(backupPath);
            
            return {
                success: true,
                backupPath: backupPath
            };
        } catch (error) {
            return {
                success: false,
                error: error.message
            };
        }
    }
    
    // 恢复数据库
    function restore(backupPath) {
        try {
            // 关闭当前连接
            this.close();
            
            // 复制备份文件
            System.fs.copyFile(backupPath, this.dbPath);
            
            // 重新连接
            var connectResult = this.connect();
            
            return {
                success: connectResult.success,
                error: connectResult.error,
                restoredFrom: backupPath
            };
        } catch (error) {
            return {
                success: false,
                error: error.message
            };
        }
    }
}

// 使用示例
function sqliteExample() {
    var dbManager = new SQLiteManager('example.db');
    
    // 连接数据库
    var connectResult = dbManager.connect();
    if (!connectResult.success) {
        stdout.println('数据库连接失败:', connectResult.error);
        return;
    }
    
    // 创建用户表
    var createTableResult = dbManager.createTable('users', {
        id: 'INTEGER PRIMARY KEY AUTOINCREMENT',
        name: 'TEXT NOT NULL',
        email: 'TEXT UNIQUE NOT NULL',
        age: 'INTEGER',
        created_at: 'DATETIME DEFAULT CURRENT_TIMESTAMP'
    }, {
        indexes: [
            { columns: ['email'] },
            { columns: ['name', 'age'] }
        ]
    });
    
    stdout.println('创建表结果:', JSON.stringify(createTableResult, null, 2));
    
    // 插入测试数据
    var users = [
        { name: '张三', email: 'zhangsan@example.com', age: 25 },
        { name: '李四', email: 'lisi@example.com', age: 30 },
        { name: '王五', email: 'wangwu@example.com', age: 28 }
    ];
    
    var insertResult = dbManager.insertBatch('users', users);
    stdout.println('批量插入结果:', JSON.stringify(insertResult, null, 2));
    
    // 查询数据
    var selectResult = dbManager.select('users', {
        orderBy: 'age DESC',
        limit: 10
    });
    
    stdout.println('查询结果:', JSON.stringify(selectResult, null, 2));
    
    // 更新数据
    var updateResult = dbManager.update('users', 
        { age: 26 }, 
        'name = ?', 
        ['张三']
    );
    
    stdout.println('更新结果:', JSON.stringify(updateResult, null, 2));
    
    // 事务示例
    var transactionResult = dbManager.beginTransaction();
    if (transactionResult.success) {
        var insertResult1 = dbManager.insert('users', {
            name: '赵六',
            email: 'zhaoliu@example.com',
            age: 35
        });
        
        var insertResult2 = dbManager.insert('users', {
            name: '孙七',
            email: 'sunqi@example.com',
            age: 32
        });
        
        if (insertResult1.success && insertResult2.success) {
            dbManager.commitTransaction();
            stdout.println('事务提交成功');
        } else {
            dbManager.rollbackTransaction();
            stdout.println('事务回滚');
        }
    }
    
    // 获取数据库信息
    var dbInfo = dbManager.getDatabaseInfo();
    stdout.println('数据库信息:', JSON.stringify(dbInfo, null, 2));
    
    // 备份数据库
    var backupResult = dbManager.backup('example_backup.db');
    stdout.println('备份结果:', JSON.stringify(backupResult, null, 2));
    
    // 关闭数据库连接
    dbManager.close();
}

8.5.2 其他数据库支持

// 通用数据库连接管理器
class DatabaseManager {
    function this() {
        this.connections = new Map();
        this.defaultConnection = null;
    }
    
    // 添加数据库连接
    function addConnection(name, config) {
        try {
            var connection;
            
            switch (config.type) {
                case 'sqlite':
                    connection = new SQLiteManager(config.path);
                    break;
                    
                case 'mysql':
                    connection = System.database.mysql.connect({
                        host: config.host,
                        port: config.port || 3306,
                        user: config.user,
                        password: config.password,
                        database: config.database
                    });
                    break;
                    
                case 'postgresql':
                    connection = System.database.postgresql.connect({
                        host: config.host,
                        port: config.port || 5432,
                        user: config.user,
                        password: config.password,
                        database: config.database
                    });
                    break;
                    
                default:
                    throw new Error(`不支持的数据库类型: ${config.type}`);
            }
            
            this.connections.set(name, {
                connection: connection,
                config: config,
                type: config.type
            });
            
            if (!this.defaultConnection) {
                this.defaultConnection = name;
            }
            
            return {
                success: true,
                connectionName: name
            };
        } catch (error) {
            return {
                success: false,
                error: error.message
            };
        }
    }
    
    // 获取数据库连接
    function getConnection(name = null) {
        var connectionName = name || this.defaultConnection;
        
        if (!connectionName) {
            return {
                success: false,
                error: '没有可用的数据库连接'
            };
        }
        
        var connectionInfo = this.connections.get(connectionName);
        if (!connectionInfo) {
            return {
                success: false,
                error: `连接不存在: ${connectionName}`
            };
        }
        
        return {
            success: true,
            connection: connectionInfo.connection,
            type: connectionInfo.type
        };
    }
    
    // 移除数据库连接
    function removeConnection(name) {
        var connectionInfo = this.connections.get(name);
        if (connectionInfo) {
            try {
                if (connectionInfo.connection.close) {
                    connectionInfo.connection.close();
                }
                
                this.connections.delete(name);
                
                if (this.defaultConnection === name) {
                    this.defaultConnection = this.connections.size > 0 ? 
                        this.connections.keys().next().value : null;
                }
                
                return { success: true };
            } catch (error) {
                return {
                    success: false,
                    error: error.message
                };
            }
        }
        
        return {
            success: false,
            error: `连接不存在: ${name}`
        };
    }
    
    // 获取所有连接信息
    function getConnectionList() {
        var connections = [];
        
        for (var [name, info] of this.connections) {
            connections.push({
                name: name,
                type: info.type,
                isDefault: name === this.defaultConnection
            });
        }
        
        return {
            success: true,
            connections: connections,
            defaultConnection: this.defaultConnection
        };
    }
    
    // 设置默认连接
    function setDefaultConnection(name) {
        if (this.connections.has(name)) {
            this.defaultConnection = name;
            return { success: true };
        }
        
        return {
            success: false,
            error: `连接不存在: ${name}`
        };
    }
}

// 使用示例
function databaseManagerExample() {
    var dbManager = new DatabaseManager();
    
    // 添加SQLite连接
    dbManager.addConnection('main', {
        type: 'sqlite',
        path: 'main.db'
    });
    
    // 添加MySQL连接(如果支持)
    dbManager.addConnection('mysql', {
        type: 'mysql',
        host: 'localhost',
        user: 'root',
        password: 'password',
        database: 'testdb'
    });
    
    // 获取连接列表
    var connectionList = dbManager.getConnectionList();
    stdout.println('数据库连接列表:', JSON.stringify(connectionList, null, 2));
    
    // 使用默认连接
    var defaultConn = dbManager.getConnection();
    if (defaultConn.success) {
        stdout.println('使用默认连接:', defaultConn.type);
        
        if (defaultConn.type === 'sqlite') {
            var connectResult = defaultConn.connection.connect();
            stdout.println('连接结果:', JSON.stringify(connectResult, null, 2));
        }
    }
}

8.6 本章总结

8.6.1 核心要点

  1. 文件系统操作

    • 文件读写、复制、移动、删除
    • 目录管理和搜索
    • 文件监控和变化检测
    • 路径处理和文件信息获取
  2. 网络通信

    • HTTP客户端请求处理
    • 文件上传和下载
    • 请求拦截器和响应处理
    • WebSocket实时通信
    • 连接管理和自动重连
  3. 系统集成

    • 系统通知管理
    • 托盘图标和上下文菜单
    • 权限检查和用户交互
    • 系统事件监听
  4. 数据库操作

    • SQLite数据库管理
    • 事务处理和批量操作
    • 数据库备份和恢复
    • 多数据库连接管理

8.6.2 最佳实践

  1. 错误处理

    • 统一的错误返回格式
    • 详细的错误信息记录
    • 优雅的错误恢复机制
    • 用户友好的错误提示
  2. 资源管理

    • 及时释放文件句柄
    • 正确关闭数据库连接
    • 清理定时器和监听器
    • 内存使用优化
  3. 安全考虑

    • 文件路径验证
    • SQL注入防护
    • 网络请求安全
    • 权限检查机制
  4. 性能优化

    • 异步操作处理
    • 批量数据操作
    • 连接池管理
    • 缓存策略应用

8.6.3 练习题

基础练习

  1. 创建一个文件管理器,实现文件的基本操作
  2. 实现一个简单的HTTP客户端,支持GET和POST请求
  3. 创建系统通知功能,支持不同类型的通知
  4. 实现SQLite数据库的基本CRUD操作

进阶练习

  1. 开发文件同步工具,监控文件变化并自动同步
  2. 实现WebSocket聊天客户端,支持实时消息传递
  3. 创建系统托盘应用,提供快捷操作菜单
  4. 开发数据库管理工具,支持多种数据库类型

高级练习

  1. 构建完整的文件备份系统,支持增量备份
  2. 实现分布式文件传输系统
  3. 开发系统监控工具,集成通知和托盘功能
  4. 创建数据库迁移工具,支持版本管理

通过本章的学习,你已经掌握了Sciter中原生API的集成方法,能够开发功能丰富的桌面应用程序。下一章我们将学习性能优化与调试,帮助你构建高性能的Sciter应用。

8.1.3 API使用原则

  1. 安全性:原生API具有系统级权限,需要谨慎使用
  2. 异步处理:大多数API操作是异步的,需要正确处理回调
  3. 错误处理:必须实现完善的错误处理机制
  4. 资源管理:及时释放文件句柄、网络连接等资源
  5. 跨平台兼容:考虑不同操作系统的差异

8.2 文件系统操作

8.2.1 基础文件操作

// 文件操作管理器
class FileManager {
    function this() {
        this.encoding = 'utf-8';
    }
    
    // 读取文件
    function readFile(filePath, encoding = null) {
        try {
            var actualEncoding = encoding || this.encoding;
            
            // 检查文件是否存在
            if (!System.fs.stat(filePath)) {
                throw new Error('文件不存在: ' + filePath);
            }
            
            // 读取文件内容
            var content = System.fs.readFile(filePath, actualEncoding);
            
            return {
                success: true,
                content: content,
                size: content.length,
                encoding: actualEncoding
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                filePath: filePath
            };
        }
    }
    
    // 写入文件
    function writeFile(filePath, content, encoding = null) {
        try {
            var actualEncoding = encoding || this.encoding;
            
            // 确保目录存在
            var dirPath = System.path.dirname(filePath);
            this.ensureDirectory(dirPath);
            
            // 写入文件
            System.fs.writeFile(filePath, content, actualEncoding);
            
            return {
                success: true,
                filePath: filePath,
                size: content.length,
                encoding: actualEncoding
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                filePath: filePath
            };
        }
    }
    
    // 追加文件内容
    function appendFile(filePath, content, encoding = null) {
        try {
            var actualEncoding = encoding || this.encoding;
            
            // 如果文件不存在,创建新文件
            if (!System.fs.stat(filePath)) {
                return this.writeFile(filePath, content, actualEncoding);
            }
            
            // 读取现有内容
            var existingContent = System.fs.readFile(filePath, actualEncoding);
            var newContent = existingContent + content;
            
            // 写入合并后的内容
            return this.writeFile(filePath, newContent, actualEncoding);
        } catch (error) {
            return {
                success: false,
                error: error.message,
                filePath: filePath
            };
        }
    }
    
    // 复制文件
    function copyFile(sourcePath, destPath) {
        try {
            // 检查源文件
            if (!System.fs.stat(sourcePath)) {
                throw new Error('源文件不存在: ' + sourcePath);
            }
            
            // 确保目标目录存在
            var destDir = System.path.dirname(destPath);
            this.ensureDirectory(destDir);
            
            // 读取源文件
            var content = System.fs.readFile(sourcePath, 'binary');
            
            // 写入目标文件
            System.fs.writeFile(destPath, content, 'binary');
            
            return {
                success: true,
                sourcePath: sourcePath,
                destPath: destPath,
                size: content.length
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                sourcePath: sourcePath,
                destPath: destPath
            };
        }
    }
    
    // 移动文件
    function moveFile(sourcePath, destPath) {
        try {
            // 先复制文件
            var copyResult = this.copyFile(sourcePath, destPath);
            
            if (!copyResult.success) {
                return copyResult;
            }
            
            // 删除源文件
            var deleteResult = this.deleteFile(sourcePath);
            
            if (!deleteResult.success) {
                // 如果删除失败,尝试删除已复制的文件
                this.deleteFile(destPath);
                return deleteResult;
            }
            
            return {
                success: true,
                sourcePath: sourcePath,
                destPath: destPath
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                sourcePath: sourcePath,
                destPath: destPath
            };
        }
    }
    
    // 删除文件
    function deleteFile(filePath) {
        try {
            if (!System.fs.stat(filePath)) {
                return {
                    success: true,
                    message: '文件不存在,无需删除',
                    filePath: filePath
                };
            }
            
            System.fs.unlink(filePath);
            
            return {
                success: true,
                filePath: filePath
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                filePath: filePath
            };
        }
    }
    
    // 获取文件信息
    function getFileInfo(filePath) {
        try {
            var stat = System.fs.stat(filePath);
            
            if (!stat) {
                throw new Error('文件不存在: ' + filePath);
            }
            
            return {
                success: true,
                path: filePath,
                size: stat.size,
                isFile: stat.isFile,
                isDirectory: stat.isDirectory,
                created: new Date(stat.ctime),
                modified: new Date(stat.mtime),
                accessed: new Date(stat.atime),
                permissions: stat.mode
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                filePath: filePath
            };
        }
    }
    
    // 确保目录存在
    function ensureDirectory(dirPath) {
        try {
            if (System.fs.stat(dirPath)) {
                return { success: true, existed: true };
            }
            
            // 递归创建父目录
            var parentDir = System.path.dirname(dirPath);
            if (parentDir !== dirPath) {
                this.ensureDirectory(parentDir);
            }
            
            System.fs.mkdir(dirPath);
            
            return {
                success: true,
                created: true,
                dirPath: dirPath
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                dirPath: dirPath
            };
        }
    }
}

// 使用示例
function fileOperationExample() {
    var fileManager = new FileManager();
    
    // 写入文件
    var writeResult = fileManager.writeFile('test.txt', 'Hello, Sciter!');
    stdout.println('写入结果:', JSON.stringify(writeResult, null, 2));
    
    // 读取文件
    var readResult = fileManager.readFile('test.txt');
    stdout.println('读取结果:', JSON.stringify(readResult, null, 2));
    
    // 追加内容
    var appendResult = fileManager.appendFile('test.txt', '\n追加的内容');
    stdout.println('追加结果:', JSON.stringify(appendResult, null, 2));
    
    // 获取文件信息
    var infoResult = fileManager.getFileInfo('test.txt');
    stdout.println('文件信息:', JSON.stringify(infoResult, null, 2));
    
    // 复制文件
    var copyResult = fileManager.copyFile('test.txt', 'backup/test_copy.txt');
    stdout.println('复制结果:', JSON.stringify(copyResult, null, 2));
}

8.2.2 目录操作

// 目录操作管理器
class DirectoryManager {
    function this() {
        this.fileManager = new FileManager();
    }
    
    // 列出目录内容
    function listDirectory(dirPath, options = {}) {
        try {
            var {
                recursive = false,
                includeFiles = true,
                includeDirectories = true,
                filter = null,
                sortBy = 'name' // name, size, modified
            } = options;
            
            if (!System.fs.stat(dirPath)) {
                throw new Error('目录不存在: ' + dirPath);
            }
            
            var items = [];
            
            // 获取目录项
            var entries = System.fs.readdir(dirPath);
            
            for (var entry of entries) {
                var fullPath = System.path.join(dirPath, entry);
                var stat = System.fs.stat(fullPath);
                
                if (!stat) continue;
                
                var item = {
                    name: entry,
                    path: fullPath,
                    isFile: stat.isFile,
                    isDirectory: stat.isDirectory,
                    size: stat.size,
                    modified: new Date(stat.mtime),
                    created: new Date(stat.ctime)
                };
                
                // 应用过滤器
                if (filter && !filter(item)) {
                    continue;
                }
                
                // 根据类型过滤
                if ((item.isFile && !includeFiles) || 
                    (item.isDirectory && !includeDirectories)) {
                    continue;
                }
                
                items.push(item);
                
                // 递归处理子目录
                if (recursive && item.isDirectory) {
                    var subItems = this.listDirectory(fullPath, options);
                    if (subItems.success) {
                        items = items.concat(subItems.items);
                    }
                }
            }
            
            // 排序
            this.sortItems(items, sortBy);
            
            return {
                success: true,
                path: dirPath,
                items: items,
                count: items.length
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                path: dirPath
            };
        }
    }
    
    // 创建目录
    function createDirectory(dirPath, recursive = true) {
        try {
            if (System.fs.stat(dirPath)) {
                return {
                    success: true,
                    existed: true,
                    path: dirPath
                };
            }
            
            if (recursive) {
                return this.fileManager.ensureDirectory(dirPath);
            } else {
                System.fs.mkdir(dirPath);
                return {
                    success: true,
                    created: true,
                    path: dirPath
                };
            }
        } catch (error) {
            return {
                success: false,
                error: error.message,
                path: dirPath
            };
        }
    }
    
    // 删除目录
    function removeDirectory(dirPath, recursive = false) {
        try {
            if (!System.fs.stat(dirPath)) {
                return {
                    success: true,
                    message: '目录不存在,无需删除',
                    path: dirPath
                };
            }
            
            if (recursive) {
                // 递归删除目录内容
                var listResult = this.listDirectory(dirPath, {
                    includeFiles: true,
                    includeDirectories: true
                });
                
                if (listResult.success) {
                    // 先删除文件,再删除子目录
                    var files = listResult.items.filter(item => item.isFile);
                    var dirs = listResult.items.filter(item => item.isDirectory);
                    
                    // 删除文件
                    for (var file of files) {
                        this.fileManager.deleteFile(file.path);
                    }
                    
                    // 删除子目录(逆序,确保先删除深层目录)
                    dirs.sort((a, b) => b.path.length - a.path.length);
                    for (var dir of dirs) {
                        System.fs.rmdir(dir.path);
                    }
                }
            }
            
            // 删除目录本身
            System.fs.rmdir(dirPath);
            
            return {
                success: true,
                path: dirPath
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                path: dirPath
            };
        }
    }
    
    // 复制目录
    function copyDirectory(sourcePath, destPath, options = {}) {
        try {
            var { overwrite = false } = options;
            
            if (!System.fs.stat(sourcePath)) {
                throw new Error('源目录不存在: ' + sourcePath);
            }
            
            if (System.fs.stat(destPath) && !overwrite) {
                throw new Error('目标目录已存在: ' + destPath);
            }
            
            // 创建目标目录
            this.createDirectory(destPath, true);
            
            // 获取源目录内容
            var listResult = this.listDirectory(sourcePath, {
                recursive: true,
                includeFiles: true,
                includeDirectories: true
            });
            
            if (!listResult.success) {
                throw new Error('无法读取源目录: ' + listResult.error);
            }
            
            var copiedFiles = 0;
            var copiedDirs = 0;
            
            for (var item of listResult.items) {
                var relativePath = System.path.relative(sourcePath, item.path);
                var targetPath = System.path.join(destPath, relativePath);
                
                if (item.isDirectory) {
                    this.createDirectory(targetPath);
                    copiedDirs++;
                } else {
                    var copyResult = this.fileManager.copyFile(item.path, targetPath);
                    if (copyResult.success) {
                        copiedFiles++;
                    }
                }
            }
            
            return {
                success: true,
                sourcePath: sourcePath,
                destPath: destPath,
                copiedFiles: copiedFiles,
                copiedDirectories: copiedDirs
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                sourcePath: sourcePath,
                destPath: destPath
            };
        }
    }
    
    // 排序项目
    function sortItems(items, sortBy) {
        switch (sortBy) {
            case 'name':
                items.sort((a, b) => a.name.localeCompare(b.name));
                break;
            case 'size':
                items.sort((a, b) => b.size - a.size);
                break;
            case 'modified':
                items.sort((a, b) => b.modified.getTime() - a.modified.getTime());
                break;
        }
    }
    
    // 搜索文件
    function searchFiles(dirPath, pattern, options = {}) {
        try {
            var {
                recursive = true,
                caseSensitive = false,
                searchContent = false,
                fileExtensions = null
            } = options;
            
            var results = [];
            var regex = new RegExp(pattern, caseSensitive ? 'g' : 'gi');
            
            var listResult = this.listDirectory(dirPath, {
                recursive: recursive,
                includeFiles: true,
                includeDirectories: false
            });
            
            if (!listResult.success) {
                return listResult;
            }
            
            for (var item of listResult.items) {
                var matched = false;
                var matchType = '';
                var matchDetails = null;
                
                // 检查文件扩展名
                if (fileExtensions) {
                    var ext = System.path.extname(item.name).toLowerCase();
                    if (!fileExtensions.includes(ext)) {
                        continue;
                    }
                }
                
                // 检查文件名
                if (regex.test(item.name)) {
                    matched = true;
                    matchType = 'filename';
                }
                
                // 搜索文件内容
                if (searchContent && !matched) {
                    var readResult = this.fileManager.readFile(item.path);
                    if (readResult.success && regex.test(readResult.content)) {
                        matched = true;
                        matchType = 'content';
                        
                        // 找到匹配的行
                        var lines = readResult.content.split('\n');
                        var matchedLines = [];
                        
                        for (var i = 0; i < lines.length; i++) {
                            if (regex.test(lines[i])) {
                                matchedLines.push({
                                    lineNumber: i + 1,
                                    content: lines[i].trim()
                                });
                            }
                        }
                        
                        matchDetails = { matchedLines: matchedLines };
                    }
                }
                
                if (matched) {
                    results.push({
                        ...item,
                        matchType: matchType,
                        matchDetails: matchDetails
                    });
                }
            }
            
            return {
                success: true,
                pattern: pattern,
                searchPath: dirPath,
                results: results,
                count: results.length
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                pattern: pattern,
                searchPath: dirPath
            };
        }
    }
}

// 使用示例
function directoryOperationExample() {
    var dirManager = new DirectoryManager();
    
    // 创建测试目录结构
    dirManager.createDirectory('test_project/src/components');
    dirManager.createDirectory('test_project/src/utils');
    dirManager.createDirectory('test_project/docs');
    
    var fileManager = new FileManager();
    
    // 创建一些测试文件
    fileManager.writeFile('test_project/src/components/Button.js', 'export class Button {}');
    fileManager.writeFile('test_project/src/components/Modal.js', 'export class Modal {}');
    fileManager.writeFile('test_project/src/utils/helpers.js', 'export function helper() {}');
    fileManager.writeFile('test_project/README.md', '# Test Project\nThis is a test project.');
    
    // 列出目录内容
    var listResult = dirManager.listDirectory('test_project', {
        recursive: true,
        sortBy: 'name'
    });
    stdout.println('目录内容:', JSON.stringify(listResult, null, 2));
    
    // 搜索文件
    var searchResult = dirManager.searchFiles('test_project', 'Button', {
        recursive: true,
        searchContent: true
    });
    stdout.println('搜索结果:', JSON.stringify(searchResult, null, 2));
    
    // 复制目录
    var copyResult = dirManager.copyDirectory('test_project', 'test_project_backup');
    stdout.println('复制结果:', JSON.stringify(copyResult, null, 2));
}

8.2.3 文件监控

// 文件监控管理器
class FileWatcher {
    function this() {
        this.watchers = new Map();
        this.watchId = 0;
    }
    
    // 监控文件或目录
    function watch(path, options = {}) {
        try {
            var {
                recursive = false,
                events = ['created', 'modified', 'deleted'],
                debounceMs = 100,
                filter = null
            } = options;
            
            var watchId = ++this.watchId;
            
            // 创建监控器
            var watcher = {
                id: watchId,
                path: path,
                options: options,
                lastEvents: new Map(),
                callbacks: [],
                active: true
            };
            
            // 使用Sciter的文件系统监控API
            var systemWatcher = System.fs.watch(path, {
                recursive: recursive,
                callback: function(event) {
                    this.handleFileEvent(watcher, event);
                }.bind(this)
            });
            
            watcher.systemWatcher = systemWatcher;
            this.watchers.set(watchId, watcher);
            
            return {
                success: true,
                watchId: watchId,
                path: path
            };
        } catch (error) {
            return {
                success: false,
                error: error.message,
                path: path
            };
        }
    }
    
    // 处理文件事件
    function handleFileEvent(watcher, event) {
        try {
            var { path, type, filename } = event;
            var fullPath = filename ? System.path.join(path, filename) : path;
            
            // 应用过滤器
            if (watcher.options.filter && !watcher.options.filter(fullPath, type)) {
                return;
            }
            
            // 防抖处理
            var eventKey = fullPath + ':' + type;
            var now = Date.now();
            var lastTime = watcher.lastEvents.get(eventKey) || 0;
            
            if (now - lastTime < watcher.options.debounceMs) {
                return;
            }
            
            watcher.lastEvents.set(eventKey, now);
            
            // 创建事件对象
            var fileEvent = {
                type: type,
                path: fullPath,
                filename: filename,
                timestamp: new Date(),
                watchId: watcher.id
            };
            
            // 触发回调
            for (var callback of watcher.callbacks) {
                try {
                    callback(fileEvent);
                } catch (callbackError) {
                    stdout.println('文件监控回调错误:', callbackError.message);
                }
            }
        } catch (error) {
            stdout.println('文件事件处理错误:', error.message);
        }
    }
    
    // 添加事件监听器
    function on(watchId, callback) {
        var watcher = this.watchers.get(watchId);
        if (watcher) {
            watcher.callbacks.push(callback);
            return true;
        }
        return false;
    }
    
    // 移除事件监听器
    function off(watchId, callback) {
        var watcher = this.watchers.get(watchId);
        if (watcher) {
            var index = watcher.callbacks.indexOf(callback);
            if (index !== -1) {
                watcher.callbacks.splice(index, 1);
                return true;
            }
        }
        return false;
    }
    
    // 停止监控
    function unwatch(watchId) {
        var watcher = this.watchers.get(watchId);
        if (watcher) {
            watcher.active = false;
            
            if (watcher.systemWatcher) {
                watcher.systemWatcher.close();
            }
            
            this.watchers.delete(watchId);
            
            return {
                success: true,
                watchId: watchId
            };
        }
        
        return {
            success: false,
            error: '监控器不存在',
            watchId: watchId
        };
    }
    
    // 停止所有监控
    function unwatchAll() {
        var stopped = [];
        
        for (var [watchId, watcher] of this.watchers) {
            var result = this.unwatch(watchId);
            stopped.push(result);
        }
        
        return {
            success: true,
            stopped: stopped
        };
    }
    
    // 获取监控状态
    function getWatcherInfo(watchId) {
        var watcher = this.watchers.get(watchId);
        if (watcher) {
            return {
                success: true,
                id: watcher.id,
                path: watcher.path,
                options: watcher.options,
                active: watcher.active,
                callbackCount: watcher.callbacks.length
            };
        }
        
        return {
            success: false,
            error: '监控器不存在',
            watchId: watchId
        };
    }
    
    // 列出所有监控器
    function listWatchers() {
        var watchers = [];
        
        for (var [watchId, watcher] of this.watchers) {
            watchers.push({
                id: watcher.id,
                path: watcher.path,
                active: watcher.active,
                callbackCount: watcher.callbacks.length
            });
        }
        
        return {
            success: true,
            watchers: watchers,
            count: watchers.length
        };
    }
}

// 使用示例
function fileWatcherExample() {
    var watcher = new FileWatcher();
    
    // 监控项目目录
    var watchResult = watcher.watch('test_project', {
        recursive: true,
        events: ['created', 'modified', 'deleted'],
        debounceMs: 200,
        filter: function(path, type) {
            // 只监控特定文件类型
            var ext = System.path.extname(path).toLowerCase();
            return ['.js', '.ts', '.css', '.html', '.md'].includes(ext);
        }
    });
    
    if (watchResult.success) {
        stdout.println('开始监控:', watchResult.path);
        
        // 添加事件监听器
        watcher.on(watchResult.watchId, function(event) {
            stdout.println('文件事件:', {
                type: event.type,
                path: event.path,
                time: event.timestamp.toLocaleString()
            });
        });
        
        // 模拟文件操作
        setTimeout(function() {
            var fileManager = new FileManager();
            
            // 创建新文件
            fileManager.writeFile('test_project/new_file.js', 'console.log("Hello");');
            
            // 修改现有文件
            setTimeout(function() {
                fileManager.appendFile('test_project/README.md', '\n\n## 更新内容');
            }, 500);
            
            // 删除文件
            setTimeout(function() {
                fileManager.deleteFile('test_project/new_file.js');
            }, 1000);
        }, 1000);
        
        // 10秒后停止监控
        setTimeout(function() {
            watcher.unwatch(watchResult.watchId);
            stdout.println('停止监控');
        }, 10000);
    } else {
        stdout.println('监控失败:', watchResult.error);
    }
}

8.3 网络请求处理

8.3.1 HTTP客户端

// HTTP客户端管理器
class HttpClient {
    function this(options = {}) {
        this.baseURL = options.baseURL || '';
        this.timeout = options.timeout || 30000;
        this.headers = options.headers || {};
        this.interceptors = {
            request: [],
            response: []
        };
    }
    
    // 发送HTTP请求
    function request(method, url, options = {}) {
        return new Promise(function(resolve, reject) {
            try {
                var {
                    data = null,
                    headers = {},
                    timeout = this.timeout,
                    responseType = 'json', // json, text, blob
                    withCredentials = false
                } = options;
                
                // 构建完整URL
                var fullURL = this.buildURL(url);
                
                // 合并请求头
                var requestHeaders = Object.assign({}, this.headers, headers);
                
                // 应用请求拦截器
                var requestConfig = {
                    method: method,
                    url: fullURL,
                    data: data,
                    headers: requestHeaders,
                    timeout: timeout
                };
                
                for (var interceptor of this.interceptors.request) {
                    requestConfig = interceptor(requestConfig) || requestConfig;
                }
                
                // 创建XMLHttpRequest
                var xhr = new XMLHttpRequest();
                
                // 设置超时
                xhr.timeout = timeout;
                
                // 设置响应类型
                if (responseType === 'blob') {
                    xhr.responseType = 'blob';
                } else if (responseType === 'text') {
                    xhr.responseType = 'text';
                }
                
                // 设置事件处理器
                xhr.onload = function() {
                    var response = this.createResponse(xhr, responseType);
                    
                    // 应用响应拦截器
                    for (var interceptor of this.interceptors.response) {
                        response = interceptor(response) || response;
                    }
                    
                    if (xhr.status >= 200 && xhr.status < 300) {
                        resolve(response);
                    } else {
                        reject(new Error('HTTP Error: ' + xhr.status + ' ' + xhr.statusText));
                    }
                }.bind(this);
                
                xhr.onerror = function() {
                    reject(new Error('Network Error'));
                };
                
                xhr.ontimeout = function() {
                    reject(new Error('Request Timeout'));
                };
                
                // 打开连接
                xhr.open(method.toUpperCase(), requestConfig.url, true);
                
                // 设置请求头
                for (var [key, value] of Object.entries(requestConfig.headers)) {
                    xhr.setRequestHeader(key, value);
                }
                
                // 发送请求
                if (data) {
                    if (typeof data === 'object' && !(data instanceof FormData)) {
                        xhr.setRequestHeader('Content-Type', 'application/json');
                        xhr.send(JSON.stringify(data));
                    } else {
                        xhr.send(data);
                    }
                } else {
                    xhr.send();
                }
            } catch (error) {
                reject(error);
            }
        }.bind(this));
    }
    
    // 创建响应对象
    function createResponse(xhr, responseType) {
        var data;
        
        if (responseType === 'json') {
            try {
                data = JSON.parse(xhr.responseText);
            } catch (e) {
                data = xhr.responseText;
            }
        } else if (responseType === 'blob') {
            data = xhr.response;
        } else {
            data = xhr.responseText;
        }
        
        return {
            data: data,
            status: xhr.status,
            statusText: xhr.statusText,
            headers: this.parseHeaders(xhr.getAllResponseHeaders()),
            config: {
                method: xhr.method,
                url: xhr.responseURL
            }
        };
    }
    
    // 解析响应头
    function parseHeaders(headerString) {
        var headers = {};
        
        if (!headerString) return headers;
        
        var lines = headerString.split('\r\n');
        for (var line of lines) {
            var parts = line.split(': ');
            if (parts.length === 2) {
                headers[parts[0].toLowerCase()] = parts[1];
            }
        }
        
        return headers;
    }
    
    // 构建完整URL
    function buildURL(url) {
        if (url.startsWith('http://') || url.startsWith('https://')) {
            return url;
        }
        
        if (this.baseURL) {
            return this.baseURL.replace(/\/$/, '') + '/' + url.replace(/^\//, '');
        }
        
        return url;
    }
    
    // GET请求
    function get(url, options = {}) {
        return this.request('GET', url, options);
    }
    
    // POST请求
    function post(url, data, options = {}) {
        return this.request('POST', url, Object.assign({ data: data }, options));
    }
    
    // PUT请求
    function put(url, data, options = {}) {
        return this.request('PUT', url, Object.assign({ data: data }, options));
    }
    
    // DELETE请求
    function delete(url, options = {}) {
        return this.request('DELETE', url, options);
    }
    
    // PATCH请求
    function patch(url, data, options = {}) {
        return this.request('PATCH', url, Object.assign({ data: data }, options));
    }
    
    // 添加请求拦截器
    function addRequestInterceptor(interceptor) {
        this.interceptors.request.push(interceptor);
    }
    
    // 添加响应拦截器
    function addResponseInterceptor(interceptor) {
        this.interceptors.response.push(interceptor);
    }
    
    // 下载文件
    function downloadFile(url, localPath, options = {}) {
        return new Promise(function(resolve, reject) {
            var {
                onProgress = null,
                headers = {}
            } = options;
            
            this.request('GET', url, {
                headers: headers,
                responseType: 'blob'
            }).then(function(response) {
                try {
                    // 将blob数据写入文件
                    var fileManager = new FileManager();
                    var writeResult = fileManager.writeFile(localPath, response.data, 'binary');
                    
                    if (writeResult.success) {
                        resolve({
                            success: true,
                            localPath: localPath,
                            size: writeResult.size,
                            url: url
                        });
                    } else {
                        reject(new Error('文件写入失败: ' + writeResult.error));
                    }
                } catch (error) {
                    reject(error);
                }
            }).catch(reject);
        }.bind(this));
    }
    
    // 上传文件
    function uploadFile(url, filePath, options = {}) {
        return new Promise(function(resolve, reject) {
            try {
                var {
                    fieldName = 'file',
                    additionalFields = {},
                    headers = {},
                    onProgress = null
                } = options;
                
                // 读取文件
                var fileManager = new FileManager();
                var readResult = fileManager.readFile(filePath, 'binary');
                
                if (!readResult.success) {
                    reject(new Error('文件读取失败: ' + readResult.error));
                    return;
                }
                
                // 创建FormData
                var formData = new FormData();
                
                // 添加文件
                var fileName = System.path.basename(filePath);
                var blob = new Blob([readResult.content]);
                formData.append(fieldName, blob, fileName);
                
                // 添加其他字段
                for (var [key, value] of Object.entries(additionalFields)) {
                    formData.append(key, value);
                }
                
                // 发送请求
                this.request('POST', url, {
                    data: formData,
                    headers: headers
                }).then(resolve).catch(reject);
            } catch (error) {
                reject(error);
            }
        }.bind(this));
    }
}

// 使用示例
function httpClientExample() {
    // 创建HTTP客户端
    var client = new HttpClient({
        baseURL: 'https://api.example.com',
        timeout: 10000,
        headers: {
            'User-Agent': 'Sciter-App/1.0'
        }
    });
    
    // 添加请求拦截器
    client.addRequestInterceptor(function(config) {
        stdout.println('发送请求:', config.method, config.url);
        
        // 添加认证头
        config.headers['Authorization'] = 'Bearer your-token-here';
        
        return config;
    });
    
    // 添加响应拦截器
    client.addResponseInterceptor(function(response) {
        stdout.println('收到响应:', response.status, response.statusText);
        return response;
    });
    
    // GET请求示例
    client.get('/users/1')
        .then(function(response) {
            stdout.println('用户数据:', JSON.stringify(response.data, null, 2));
        })
        .catch(function(error) {
            stdout.println('请求失败:', error.message);
        });
    
    // POST请求示例
    client.post('/users', {
        name: 'John Doe',
        email: 'john@example.com'
    })
        .then(function(response) {
            stdout.println('创建用户成功:', JSON.stringify(response.data, null, 2));
        })
        .catch(function(error) {
            stdout.println('创建用户失败:', error.message);
        });
    
    // 文件下载示例
    client.downloadFile('https://example.com/file.pdf', 'downloads/file.pdf')
        .then(function(result) {
            stdout.println('下载完成:', result.localPath, '大小:', result.size);
        })
        .catch(function(error) {
            stdout.println('下载失败:', error.message);
        });
    
    // 文件上传示例
    client.uploadFile('/upload', 'local_file.jpg', {
        fieldName: 'image',
        additionalFields: {
            description: '测试图片',
            category: 'test'
        }
    })
        .then(function(response) {
            stdout.println('上传成功:', JSON.stringify(response.data, null, 2));
        })
        .catch(function(error) {
            stdout.println('上传失败:', error.message);
        });
}