diff --git a/.gitignore b/.gitignore index 1bdf522..85320f2 100755 --- a/.gitignore +++ b/.gitignore @@ -58,7 +58,6 @@ app.*.map.json /android/app/profile /android/app/release - /data /.gradle/ @@ -99,3 +98,6 @@ libcore/*.aar # Android 编译产物 android/app/libs/*.aar + +# FVM Version Cache +.fvm/ \ No newline at end of file diff --git a/lib/app/model/business/kr_outbound_item.dart b/lib/app/model/business/kr_outbound_item.dart index b63152e..fd6b4ff 100755 --- a/lib/app/model/business/kr_outbound_item.dart +++ b/lib/app/model/business/kr_outbound_item.dart @@ -138,7 +138,9 @@ class KROutboundItem { "password": nodeListItem.uuid }; break; + case "hysteria": case "hysteria2": + // 后端的 "hysteria" 实际上是 Hysteria2 协议 final securityConfig = json["security_config"] as Map? ?? {}; config = { @@ -156,8 +158,7 @@ class KROutboundItem { "tls": { "enabled": true, "server_name": securityConfig["sni"] ?? "", - "insecure": securityConfig["allow_insecure"] ?? true, - "alpn": ["h3"] + "insecure": securityConfig["allow_insecure"] ?? true } }; break; @@ -260,6 +261,10 @@ class KROutboundItem { print('📄 完整配置: $config'); break; case "vless": + // 判断是否为域名(非IP地址) + final bool isDomain = !RegExp(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$') + .hasMatch(nodeListItem.serverAddr); + config = { "type": "vless", "tag": nodeListItem.name, @@ -268,7 +273,7 @@ class KROutboundItem { "uuid": nodeListItem.uuid, "tls": { "enabled": true, - "server_name": nodeListItem.serverAddr, + if (isDomain) "server_name": nodeListItem.serverAddr, "insecure": true, "utls": { "enabled": true, @@ -280,6 +285,10 @@ class KROutboundItem { print('📄 完整配置: $config'); break; case "vmess": + // 判断是否为域名(非IP地址) + final bool isDomain = !RegExp(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$') + .hasMatch(nodeListItem.serverAddr); + config = { "type": "vmess", "tag": nodeListItem.name, @@ -290,7 +299,7 @@ class KROutboundItem { "security": "auto", "tls": { "enabled": true, - "server_name": nodeListItem.serverAddr, + if (isDomain) "server_name": nodeListItem.serverAddr, "insecure": true, "utls": {"enabled": true, "fingerprint": "chrome"} } @@ -299,6 +308,10 @@ class KROutboundItem { print('📄 完整配置: $config'); break; case "trojan": + // 判断是否为域名(非IP地址) + final bool isDomain = !RegExp(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$') + .hasMatch(nodeListItem.serverAddr); + config = { "type": "trojan", "tag": nodeListItem.name, @@ -307,7 +320,7 @@ class KROutboundItem { "password": nodeListItem.uuid, "tls": { "enabled": true, - "server_name": nodeListItem.serverAddr, + if (isDomain) "server_name": nodeListItem.serverAddr, "insecure": true, "utls": {"enabled": true, "fingerprint": "chrome"} } @@ -316,42 +329,30 @@ class KROutboundItem { print('📄 完整配置: $config'); break; case "hysteria": - config = { - "type": "hysteria", - "tag": nodeListItem.name, - "server": nodeListItem.serverAddr, - "server_port": nodeListItem.port, - "up_mbps": 100, - "down_mbps": 100, - "auth_str": nodeListItem.uuid, - "tls": { - "enabled": true, - "server_name": nodeListItem.serverAddr, - "insecure": true, - "alpn": ["h3"] - } - }; - print('✅ Hysteria 节点配置构建成功: ${nodeListItem.name}'); - print('📄 完整配置: $config'); - break; case "hysteria2": + // 后端的 "hysteria" 实际上是 Hysteria2 协议 + print('🔍 构建 Hysteria2 节点: ${nodeListItem.name}'); + print(' - serverAddr: ${nodeListItem.serverAddr}'); + print(' - port: ${nodeListItem.port}'); + print(' - uuid: ${nodeListItem.uuid}'); + + //判断是否为域名 + final bool isDomain = !RegExp(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$') + .hasMatch(nodeListItem.serverAddr); + config = { "type": "hysteria2", "tag": nodeListItem.name, "server": nodeListItem.serverAddr, "server_port": nodeListItem.port, "password": nodeListItem.uuid, - "up_mbps": 100, - "down_mbps": 100, "tls": { "enabled": true, - "server_name": nodeListItem.serverAddr, - "insecure": true, - "alpn": ["h3"] + if (isDomain) "server_name": nodeListItem.serverAddr, } }; - print('✅ Hysteria2 节点配置构建成功: ${nodeListItem.name}'); - print('📄 完整配置: $config'); + print('✅ Hysteria2 节点配置构建成功'); + print('📄 完整配置: ${jsonEncode(config)}'); break; default: print('⚠️ 不支持的协议类型: ${nodeListItem.protocol}'); diff --git a/lib/app/modules/kr_home/controllers/kr_home_controller.dart b/lib/app/modules/kr_home/controllers/kr_home_controller.dart index d8ca04f..1d09f88 100755 --- a/lib/app/modules/kr_home/controllers/kr_home_controller.dart +++ b/lib/app/modules/kr_home/controllers/kr_home_controller.dart @@ -665,6 +665,8 @@ class KRHomeController extends GetxController with WidgetsBindingObserver { try { kr_isSwitching = true; + KRLogUtil.kr_i('🔄 开始切换连接状态: $value', tag: 'HomeController'); + if (value) { await KRSingBoxImp.instance.kr_start(); @@ -678,16 +680,28 @@ class KRHomeController extends GetxController with WidgetsBindingObserver { kr_forceSyncConnectionStatus(); }); } else { - await KRSingBoxImp.instance.kr_stop(); + KRLogUtil.kr_i('🛑 准备停止连接...', tag: 'HomeController'); + // 添加超时保护 + await KRSingBoxImp.instance.kr_stop().timeout( + const Duration(seconds: 10), + onTimeout: () { + KRLogUtil.kr_e('⚠️ 停止操作超时', tag: 'HomeController'); + // 强制同步状态 + kr_forceSyncConnectionStatus(); + throw TimeoutException('Stop operation timeout'); + }, + ); + KRLogUtil.kr_i('✅ 停止命令已发送', tag: 'HomeController'); } } catch (e) { KRLogUtil.kr_e('切换失败: $e', tag: 'HomeController'); - // 当启动失败时(如VPN权限被拒绝),强制同步状态 + // 当启动或停止失败时,强制同步状态 Future.delayed(const Duration(milliseconds: 100), () { kr_forceSyncConnectionStatus(); }); } finally { // 确保在任何情况下都会重置标志 + KRLogUtil.kr_i('🔓 重置切换标志', tag: 'HomeController'); kr_isSwitching = false; } } @@ -1088,10 +1102,11 @@ class KRHomeController extends GetxController with WidgetsBindingObserver { // 更新连接信息 kr_updateConnectionInfo(); + // 🔧 修复:只有在核心已启动时才选择节点,避免触发重启 if (KRSingBoxImp.instance.kr_status.value == SingboxStarted()) { KRSingBoxImp.instance.kr_selectOutbound(tag); - // 🔧 修复:选择节点后启动延迟值更新(带超时保护) + // 🔧 修复:选择节点后启动延迟值更新(带超时保护) Future.delayed(const Duration(milliseconds: 500), () { if (kr_currentNodeLatency.value == -1 && kr_isConnected.value) { KRLogUtil.kr_w('⚠️ 选择节点后延迟值未更新,尝试手动更新', tag: 'HomeController'); @@ -1101,7 +1116,13 @@ class KRHomeController extends GetxController with WidgetsBindingObserver { } }); } else { - KRSingBoxImp().kr_start(); + // 🔧 修复:核心未启动时,仍需保存用户选择,以便启动VPN时应用 + KRLogUtil.kr_i('💾 核心未启动,保存节点选择以便稍后应用: $tag', tag: 'HomeController'); + KRSecureStorage().kr_saveData(key: 'SELECTED_NODE_TAG', value: tag).then((_) { + KRLogUtil.kr_i('✅ 节点选择已保存: $tag', tag: 'HomeController'); + }).catchError((e) { + KRLogUtil.kr_e('❌ 保存节点选择失败: $e', tag: 'HomeController'); + }); } // 移动到选中的节点 diff --git a/lib/app/services/singbox_imp/kr_sing_box_imp.dart b/lib/app/services/singbox_imp/kr_sing_box_imp.dart index a951958..987ef90 100755 --- a/lib/app/services/singbox_imp/kr_sing_box_imp.dart +++ b/lib/app/services/singbox_imp/kr_sing_box_imp.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'dart:async'; import 'package:flutter/services.dart'; +import 'package:fpdart/fpdart.dart'; import 'package:get/get.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -19,6 +20,7 @@ import '../../../singbox/model/singbox_stats.dart'; import '../../../singbox/model/singbox_status.dart'; import '../../utils/kr_country_util.dart'; import '../../utils/kr_log_util.dart'; +import '../../utils/kr_secure_storage.dart'; enum KRConnectionType { global, @@ -45,6 +47,9 @@ class KRSingBoxImp { /// 配置文件名称 String kr_configName = "hiFastVPN"; + /// 存储键:用户选择的节点 + static const String _keySelectedNode = 'SELECTED_NODE_TAG'; + /// 通道方法 final _kr_methodChannel = const MethodChannel("com.hi.app/platform"); @@ -65,10 +70,10 @@ class KRSingBoxImp { final kr_status = SingboxStatus.stopped().obs; /// 拦截广告 - final kr_blockAds = true.obs; + final kr_blockAds = false.obs; /// 是否自动自动选择线路 - final kr_isAutoOutbound = true.obs; + final kr_isAutoOutbound = false.obs; bool _initialized = false; @@ -396,8 +401,27 @@ class KRSingBoxImp { } } + // 🔑 关键步骤:调用 setup() 将 NativePort 传递给 libcore + // 这样 libcore 才能通过 GoDart_PostCObject() 向 Dart 发送消息 + KRLogUtil.kr_i('📡 开始调用 setup() 注册 FFI 端口', tag: 'SingBox'); + final setupResult = await kr_singBox.setup(kr_configDics, false).run(); + setupResult.match( + (error) { + KRLogUtil.kr_e('❌ setup() 失败: $error', tag: 'SingBox'); + throw Exception('FFI setup 失败: $error'); + }, + (_) { + KRLogUtil.kr_i('✅ setup() 成功,FFI 端口已注册', tag: 'SingBox'); + }, + ); + KRLogUtil.kr_i('✅ SingBox 初始化完成'); _kr_isInitialized = true; + + // 🔑 关键:在初始化完成后立即订阅状态变化流 + // 这样可以确保 UI 始终与 libcore 的实际状态同步 + _kr_subscribeToStatus(); + KRLogUtil.kr_i('✅ 状态订阅已设置', tag: 'SingBox'); } catch (e, stackTrace) { KRLogUtil.kr_e('❌ SingBox 初始化失败: $e'); KRLogUtil.kr_e('📚 错误堆栈: $stackTrace'); @@ -438,20 +462,21 @@ class KRSingBoxImp { } Map _getConfigOption() { - if (kr_configOption.isNotEmpty) { - return kr_configOption; - } + // 不使用缓存,每次都重新生成配置 + // if (kr_configOption.isNotEmpty) { + // return kr_configOption; + // } final op = { - "region": KRCountryUtil.kr_getCurrentCountryCode(), - "block-ads": kr_blockAds.value, + "region": "other", // 参考 hiddify-app: 默认使用 "other" 跳过规则集下载 + "block-ads": false, // 参考 hiddify-app: 默认关闭广告拦截 "use-xray-core-when-possible": false, "execute-config-as-is": false, - "log-level": "warn", + "log-level": "info", // 调试阶段使用 info,生产环境改为 warn "resolve-destination": false, - "ipv6-mode": "ipv4_only", - "remote-dns-address": "udp://8.8.8.8", + "ipv6-mode": "ipv4_only", // 参考 hiddify-app: 仅使用 IPv4 (有效值: ipv4_only, prefer_ipv4, prefer_ipv6, ipv6_only) + "remote-dns-address": "udp://1.1.1.1", // 参考 hiddify-app: 使用 Cloudflare DNS "remote-dns-domain-strategy": "prefer_ipv4", - "direct-dns-address": "udp://1.1.1.1", + "direct-dns-address": "udp://1.1.1.1", // 参考 hiddify-app: 统一使用 1.1.1.1 "direct-dns-domain-strategy": "prefer_ipv4", "mixed-port": kr_port, "tproxy-port": kr_port, @@ -459,8 +484,7 @@ class KRSingBoxImp { "tun-implementation": "gvisor", "mtu": 9000, "strict-route": true, - // "connection-test-url": "http://www.cloudflare.com", - "connection-test-url": "http://www.gstatic.com/generate_204", + "connection-test-url": "http://cp.cloudflare.com", // 参考 hiddify-app: 使用 Cloudflare 测试端点 "url-test-interval": 30, "enable-clash-api": true, "clash-api-port": 36756, @@ -521,6 +545,32 @@ class KRSingBoxImp { return op; } + /// 订阅状态变化流 + /// 参考 hiddify-app: 监听 libcore 发送的状态事件来自动更新 UI + void _kr_subscribeToStatus() { + // 取消之前的状态订阅 + for (var sub in _kr_subscriptions) { + if (sub.hashCode.toString().contains('Status')) { + sub.cancel(); + } + } + _kr_subscriptions + .removeWhere((sub) => sub.hashCode.toString().contains('Status')); + + _kr_subscriptions.add( + kr_singBox.watchStatus().listen( + (status) { + KRLogUtil.kr_i('📡 收到状态更新: $status', tag: 'SingBox'); + kr_status.value = status; + }, + onError: (error) { + KRLogUtil.kr_e('📡 状态流错误: $error', tag: 'SingBox'); + }, + cancelOnError: false, + ), + ); + } + /// 订阅统计数据流 void _kr_subscribeToStats() { // 取消之前的统计订阅 @@ -532,17 +582,20 @@ class KRSingBoxImp { _kr_subscriptions .removeWhere((sub) => sub.hashCode.toString().contains('Stats')); - _kr_subscriptions.add( - kr_singBox.watchStats().listen( - (stats) { - kr_stats.value = stats; - }, - onError: (error) { - KRLogUtil.kr_e('统计数据监听错误: $error'); - }, - cancelOnError: false, - ), + // ⚠️ 关键:watchStats() 内部会调用 FFI startCommandClient + // 如果此时 command.sock 未就绪,会抛出异常 + // 所以外层必须有 try-catch + final stream = kr_singBox.watchStats(); + final subscription = stream.listen( + (stats) { + kr_stats.value = stats; + }, + onError: (error) { + KRLogUtil.kr_e('统计数据监听错误: $error', tag: 'SingBox'); + }, + cancelOnError: false, ); + _kr_subscriptions.add(subscription); } /// 订阅分组数据流 @@ -594,6 +647,261 @@ class KRSingBoxImp { ); } + /// 带重试机制的节点选择 + /// + /// 确保 command.sock 准备好后再执行节点选择 + Future _kr_selectOutboundWithRetry( + String groupTag, + String outboundTag, { + int maxAttempts = 3, + int initialDelay = 100, + }) async { + int attempt = 0; + int delay = initialDelay; + + while (attempt < maxAttempts) { + attempt++; + KRLogUtil.kr_i( + '🔄 尝试选择节点 $outboundTag (第 $attempt/$maxAttempts 次)', + tag: 'SingBox', + ); + + // 只在失败后才延迟,首次尝试立即执行 + if (attempt > 1) { + await Future.delayed(Duration(milliseconds: delay)); + } + + try { + await kr_singBox.selectOutbound(groupTag, outboundTag).run(); + KRLogUtil.kr_i('✅ 节点选择成功: $outboundTag', tag: 'SingBox'); + return; + } catch (e) { + KRLogUtil.kr_w( + '⚠️ 第 $attempt 次节点选择失败: $e', + tag: 'SingBox', + ); + + if (attempt >= maxAttempts) { + KRLogUtil.kr_e( + '❌ 节点选择失败,已达到最大重试次数', + tag: 'SingBox', + ); + throw Exception('节点选择失败: $e'); + } + + // 指数退避 + delay = delay * 2; + } + } + } + + /// 带重试机制的命令客户端初始化 + /// + /// command.sock 需要时间创建,因此需要重试机制 + /// maxAttempts: 最大重试次数(默认10次,针对macOS优化) + /// initialDelay: 初始延迟毫秒数(默认1000ms,针对macOS优化) + Future _kr_initializeCommandClientsWithRetry({ + int maxAttempts = 10, + int initialDelay = 1000, + }) async { + int attempt = 0; + int delay = initialDelay; + + while (attempt < maxAttempts) { + attempt++; + KRLogUtil.kr_i( + '🔄 尝试初始化命令客户端 (第 $attempt/$maxAttempts 次,延迟 ${delay}ms)', + tag: 'SingBox', + ); + + await Future.delayed(Duration(milliseconds: delay)); + + try { + // 先验证 command.sock 是否可访问 + final socketFile = File(p.join(kr_configDics.baseDir.path, 'command.sock')); + KRLogUtil.kr_i('🔍 检查 socket 文件: ${socketFile.path}', tag: 'SingBox'); + + if (!socketFile.existsSync()) { + throw Exception('command.sock 文件不存在: ${socketFile.path}'); + } + + KRLogUtil.kr_i('✅ socket 文件存在,开始订阅...', tag: 'SingBox'); + + // 尝试订阅统计和分组数据 + // ⚠️ 关键:分别 try-catch,避免一个失败影响另一个 + bool statsSubscribed = false; + bool groupsSubscribed = false; + + // ⚠️ 关键修复:使用 Future.delayed(Duration.zero) 将订阅推到下一个事件循环 + // 这样可以避免阻塞当前的异步执行 + try { + KRLogUtil.kr_i('📊 订阅统计数据流...', tag: 'SingBox'); + await Future.delayed(Duration.zero); // 让出 UI 线程 + _kr_subscribeToStats(); + statsSubscribed = true; + KRLogUtil.kr_i('✅ 统计数据流订阅成功', tag: 'SingBox'); + } catch (e) { + KRLogUtil.kr_w('⚠️ 统计数据流订阅失败: $e', tag: 'SingBox'); + } + + try { + KRLogUtil.kr_i('📋 订阅分组数据流...', tag: 'SingBox'); + await Future.delayed(Duration.zero); // 让出 UI 线程 + _kr_subscribeToGroups(); + groupsSubscribed = true; + KRLogUtil.kr_i('✅ 分组数据流订阅成功', tag: 'SingBox'); + } catch (e) { + KRLogUtil.kr_w('⚠️ 分组数据流订阅失败: $e', tag: 'SingBox'); + } + + // 至少有一个订阅成功才算初始化成功 + if (!statsSubscribed && !groupsSubscribed) { + throw Exception('所有订阅都失败了'); + } + + // 等待更长时间验证订阅是否成功,并实际接收到数据 + KRLogUtil.kr_i('⏳ 等待800ms验证订阅状态...', tag: 'SingBox'); + await Future.delayed(const Duration(milliseconds: 800)); + + // 验证订阅是否真正工作(检查是否有数据流) + if (_kr_subscriptions.isEmpty) { + throw Exception('订阅列表为空,command client 未成功连接'); + } + + KRLogUtil.kr_i('✅ 命令客户端初始化成功,活跃订阅数: ${_kr_subscriptions.length}', tag: 'SingBox'); + return; + } catch (e, stackTrace) { + // 详细记录失败原因和堆栈信息 + KRLogUtil.kr_w( + '⚠️ 第 $attempt 次尝试失败', + tag: 'SingBox', + ); + KRLogUtil.kr_w('❌ 错误类型: ${e.runtimeType}', tag: 'SingBox'); + KRLogUtil.kr_w('❌ 错误信息: $e', tag: 'SingBox'); + KRLogUtil.kr_w('📚 错误堆栈: $stackTrace', tag: 'SingBox'); + + if (attempt >= maxAttempts) { + KRLogUtil.kr_e( + '❌ 命令客户端初始化失败,已达到最大重试次数 ($maxAttempts)', + tag: 'SingBox', + ); + KRLogUtil.kr_e('💡 提示: command.sock 可能未准备好或权限不足', tag: 'SingBox'); + throw Exception('命令客户端初始化失败: $e'); + } + + // 指数退避:每次失败后延迟翻倍(1000ms -> 2000ms -> 4000ms -> 8000ms) + delay = delay * 2; + } + } + } + + /// 在后台尝试预连接 command client(不阻塞启动流程) + /// + /// 借鉴 Hiddify 的设计思想: + /// - watchStats/watchGroups 是懒加载的,首次调用时才会 startCommandClient() + /// - 但我们可以在后台提前尝试连接,提高成功率 + /// - 即使失败也不影响主流程,真正的订阅会在 UI 调用时发生 + void _kr_tryPreconnectCommandClientsInBackground() { + KRLogUtil.kr_i('🔄 后台启动 command client 预连接任务...', tag: 'SingBox'); + + // 使用 Future.microtask 确保不阻塞当前执行 + Future.microtask(() async { + try { + // 等待 command.sock 就绪(macOS 需要更长时间) + await Future.delayed(const Duration(milliseconds: 1500)); + + // 检查 socket 文件 + final socketFile = File(p.join(kr_configDics.baseDir.path, 'command.sock')); + if (!socketFile.existsSync()) { + KRLogUtil.kr_w('⚠️ command.sock 尚未创建,预连接取消', tag: 'SingBox'); + return; + } + + KRLogUtil.kr_i('✅ command.sock 已就绪,尝试预订阅...', tag: 'SingBox'); + + // ⚠️ 注意:这里只是"触发"订阅,不等待结果 + // 如果失败,UI 调用时会重新尝试 + try { + _kr_subscribeToStats(); + KRLogUtil.kr_i('✅ 统计流预订阅成功', tag: 'SingBox'); + } catch (e) { + KRLogUtil.kr_w('⚠️ 统计流预订阅失败(正常,UI 调用时会重试): $e', tag: 'SingBox'); + } + + try { + _kr_subscribeToGroups(); + KRLogUtil.kr_i('✅ 分组流预订阅成功', tag: 'SingBox'); + } catch (e) { + KRLogUtil.kr_w('⚠️ 分组流预订阅失败(正常,UI 调用时会重试): $e', tag: 'SingBox'); + } + + } catch (e) { + // 静默失败,不影响主流程 + KRLogUtil.kr_w('⚠️ 后台预连接任务失败(不影响正常使用): $e', tag: 'SingBox'); + } + }); + } + + /// 确保 command client 已初始化(通过触发订阅来初始化) + /// + /// 借鉴 Hiddify:watchGroups() 会在首次调用时自动 startCommandClient() + Future _kr_ensureCommandClientInitialized() async { + // 如果已经有订阅,说明 command client 已初始化 + if (_kr_subscriptions.isNotEmpty) { + KRLogUtil.kr_i('✅ Command client 已初始化(订阅数: ${_kr_subscriptions.length})', tag: 'SingBox'); + return; + } + + KRLogUtil.kr_i('⚠️ Command client 未初始化,触发订阅...', tag: 'SingBox'); + + try { + // 触发 watchGroups(),这会自动调用 startCommandClient() + _kr_subscribeToGroups(); + + // 等待一小段时间让订阅建立 + await Future.delayed(const Duration(milliseconds: 300)); + + if (_kr_subscriptions.isEmpty) { + throw Exception('订阅失败,command client 未初始化'); + } + + KRLogUtil.kr_i('✅ Command client 初始化成功', tag: 'SingBox'); + } catch (e) { + KRLogUtil.kr_e('❌ Command client 初始化失败: $e', tag: 'SingBox'); + rethrow; + } + } + + /// 在后台恢复用户保存的节点选择(不阻塞启动流程) + /// + /// selectOutbound() 依赖 command client,必须延迟执行 + void _kr_restoreSavedNodeInBackground() { + KRLogUtil.kr_i('🔄 启动节点恢复后台任务...', tag: 'SingBox'); + + Future.microtask(() async { + try { + // 等待 command client 初始化 + await Future.delayed(const Duration(milliseconds: 2000)); + + final savedNode = await KRSecureStorage().kr_readData(key: _keySelectedNode); + if (savedNode != null && savedNode.isNotEmpty && savedNode != 'auto') { + KRLogUtil.kr_i('🔄 恢复用户选择的节点: $savedNode', tag: 'SingBox'); + + try { + await _kr_selectOutboundWithRetry("select", savedNode); + KRLogUtil.kr_i('✅ 节点恢复完成', tag: 'SingBox'); + } catch (e) { + KRLogUtil.kr_w('⚠️ 节点恢复失败(可能 command client 未就绪): $e', tag: 'SingBox'); + } + } else { + KRLogUtil.kr_i('ℹ️ 使用默认节点选择 (auto)', tag: 'SingBox'); + } + } catch (e) { + KRLogUtil.kr_w('⚠️ 节点恢复后台任务失败: $e', tag: 'SingBox'); + } + }); + } + /// 监听活动组的详细实现 // Future watchActiveGroups() async { // try { @@ -643,7 +951,17 @@ class KRSingBoxImp { KRLogUtil.kr_i(' - 完整配置: ${jsonEncode(outbound)}', tag: 'SingBox'); } - kr_outbounds = outbounds; + // ⚠️ 临时过滤 Hysteria2 节点以避免 libcore 崩溃 + kr_outbounds = outbounds.where((outbound) { + final type = outbound['type']; + if (type == 'hysteria2' || type == 'hysteria') { + KRLogUtil.kr_w('⚠️ 跳过 Hysteria2 节点: ${outbound['tag']} (libcore bug)', tag: 'SingBox'); + return false; + } + return true; + }).toList(); + + KRLogUtil.kr_i('✅ 过滤后节点数量: ${kr_outbounds.length}/${outbounds.length}', tag: 'SingBox'); // 只保存 outbounds,Mobile.buildConfig() 会添加其他配置 final map = { @@ -673,12 +991,39 @@ class KRSingBoxImp { } Future kr_start() async { - kr_status.value = SingboxStarting(); + // 不再手动设置状态,libcore 会通过 status stream 自动发送状态更新 try { - KRLogUtil.kr_i('🚀 开始启动 SingBox...', tag: 'SingBox'); + // ⚠️ 强制编译标记 - v2.0-lazy-load + KRLogUtil.kr_i('🚀🚀🚀 [v2.0-lazy-load] 开始启动 SingBox...', tag: 'SingBox'); KRLogUtil.kr_i('📁 配置文件路径: $_cutPath', tag: 'SingBox'); KRLogUtil.kr_i('📝 配置名称: $kr_configName', tag: 'SingBox'); + // 🔑 先尝试停止旧实例,避免 command.sock 冲突 + // 注意:如果没有旧实例,libcore 会报错 "command.sock: no such file",这是正常的 + try { + await kr_singBox.stop().run(); + await Future.delayed(const Duration(milliseconds: 500)); + KRLogUtil.kr_i('✅ 已清理旧实例', tag: 'SingBox'); + } catch (e) { + // 预期行为:没有旧实例时会报错,可以忽略 + KRLogUtil.kr_i('ℹ️ 没有运行中的旧实例(正常)', tag: 'SingBox'); + } + + // 🔑 关键步骤:在 start 之前必须调用 changeOptions 初始化 HiddifyOptions + // 否则 libcore 的 StartService 会因为 HiddifyOptions == nil 而 panic + KRLogUtil.kr_i('📡 初始化 HiddifyOptions...', tag: 'SingBox'); + final oOption = SingboxConfigOption.fromJson(_getConfigOption()); + final changeResult = await kr_singBox.changeOptions(oOption).run(); + changeResult.match( + (error) { + KRLogUtil.kr_e('❌ changeOptions() 失败: $error', tag: 'SingBox'); + throw Exception('初始化 HiddifyOptions 失败: $error'); + }, + (_) { + KRLogUtil.kr_i('✅ HiddifyOptions 初始化成功', tag: 'SingBox'); + }, + ); + // 检查配置文件是否存在 final configFile = File(_cutPath); if (await configFile.exists()) { @@ -695,19 +1040,26 @@ class KRSingBoxImp { }, ).mapLeft((err) { KRLogUtil.kr_e('❌ SingBox 启动失败: $err', tag: 'SingBox'); - // 确保状态重置为Stopped,触发UI更新 - kr_status.value = SingboxStopped(); - // 强制刷新状态以触发观察者 - kr_status.refresh(); + // 不需要手动设置状态,libcore 会通过 status stream 自动发送 Stopped 事件 throw err; }).run(); + + // ⚠️ 借鉴 Hiddify 架构:不在 start() 时立即订阅 command client + // 原因: + // 1. 避免阻塞 UI 线程 - startCommandClient() 是同步 FFI 调用 + // 2. watchStats/watchGroups 是懒加载的,首次调用时自动初始化 + // 3. 如果 command.sock 未就绪,会在后台自动抛出异常,不影响启动流程 + + KRLogUtil.kr_i('✅ SingBox 核心已启动,command client 将延迟初始化', tag: 'SingBox'); + KRLogUtil.kr_i('💡 watchStats/watchGroups 会在首次调用时自动连接', tag: 'SingBox'); + + // ⚠️ 完全不主动订阅,避免阻塞 UI 线程 + // 借鉴 Hiddify:所有订阅由 UI 被动触发(懒加载) + KRLogUtil.kr_i('⚠️ 不再主动订阅 command client,完全由 UI 触发', tag: 'SingBox'); } catch (e, stackTrace) { KRLogUtil.kr_e('💥 SingBox 启动异常: $e', tag: 'SingBox'); KRLogUtil.kr_e('📚 错误堆栈: $stackTrace', tag: 'SingBox'); - // 确保状态重置为Stopped,触发UI更新 - kr_status.value = SingboxStopped(); - // 强制刷新状态以触发观察者 - kr_status.refresh(); + // 不需要手动设置状态,libcore 会自动处理 rethrow; } } @@ -715,26 +1067,53 @@ class KRSingBoxImp { /// 停止服务 Future kr_stop() async { try { - // 不主动赋值 kr_status + KRLogUtil.kr_i('🛑 停止 SingBox 服务...', tag: 'SingBox'); + + // 取消节点选择监控定时器 + _nodeSelectionTimer?.cancel(); + _nodeSelectionTimer = null; + KRLogUtil.kr_i('✅ 节点选择监控已停止', tag: 'SingBox'); + await Future.delayed(const Duration(milliseconds: 100)); - await kr_singBox.stop().run(); - await Future.delayed(const Duration(milliseconds: 1000)); - // 取消订阅 - final subscriptions = List>.from(_kr_subscriptions); - _kr_subscriptions.clear(); - for (var subscription in subscriptions) { + + // 添加超时保护,防止 stop() 调用阻塞 + // 缩短超时时间,避免用户等待过久 + try { + await kr_singBox.stop().run().timeout( + const Duration(seconds: 3), + onTimeout: () { + KRLogUtil.kr_w('⚠️ 停止操作超时(3秒),强制继续', tag: 'SingBox'); + return const Left('timeout'); + }, + ); + } catch (e) { + KRLogUtil.kr_w('⚠️ 停止操作失败(可能已经停止): $e', tag: 'SingBox'); + // 继续执行清理操作 + } + + await Future.delayed(const Duration(milliseconds: 500)); + + // 取消统计和分组订阅,但保留状态订阅以便继续接收状态更新 + final subscriptionsToCancel = _kr_subscriptions.where((sub) { + final hashStr = sub.hashCode.toString(); + return !hashStr.contains('Status'); // 不取消状态订阅 + }).toList(); + + for (var subscription in subscriptionsToCancel) { try { await subscription.cancel(); + _kr_subscriptions.remove(subscription); } catch (e) { KRLogUtil.kr_e('取消订阅时出错: $e'); } } - // 不主动赋值 kr_status + + // 不手动设置状态,由 libcore 通过 status stream 自动发送 Stopped 事件 + KRLogUtil.kr_i('✅ SingBox 停止请求已发送', tag: 'SingBox'); } catch (e, stackTrace) { KRLogUtil.kr_e('停止服务时出错: $e'); KRLogUtil.kr_e('错误堆栈: $stackTrace'); - // 兜底,防止状态卡死 - kr_status.value = SingboxStopped(); + // 不手动设置状态,信任 libcore 的状态管理 rethrow; } } @@ -859,20 +1238,52 @@ class KRSingBoxImp { return kr_singBox.watchGroups(); } - void kr_selectOutbound(String tag) { - KRLogUtil.kr_i('🎯 开始选择出站节点: $tag', tag: 'SingBox'); + // 节点选择监控定时器 + Timer? _nodeSelectionTimer; + + void kr_selectOutbound(String tag) async { + KRLogUtil.kr_i('🎯 [v2.1] 开始选择出站节点: $tag', tag: 'SingBox'); KRLogUtil.kr_i('📊 当前活动组数量: ${kr_activeGroups.length}', tag: 'SingBox'); - // 打印所有活动组信息 - for (int i = 0; i < kr_activeGroups.length; i++) { - final group = kr_activeGroups[i]; - KRLogUtil.kr_i('📋 活动组[$i]: tag=${group.tag}, type=${group.type}, selected=${group.selected}', tag: 'SingBox'); - for (int j = 0; j < group.items.length; j++) { - final item = group.items[j]; - KRLogUtil.kr_i(' └─ 节点[$j]: tag=${item.tag}, type=${item.type}, delay=${item.urlTestDelay}', tag: 'SingBox'); - } + // 持久化用户选择的节点(异步执行,不阻塞UI) + KRSecureStorage().kr_saveData(key: _keySelectedNode, value: tag).then((_) { + KRLogUtil.kr_i('✅ 节点选择已保存: $tag', tag: 'SingBox'); + }).catchError((e) { + KRLogUtil.kr_e('❌ 保存节点选择失败: $e', tag: 'SingBox'); + }); + + // ⚠️ 关键修复:确保 command client 已初始化 + // 借鉴 Hiddify:通过触发 watchGroups() 来初始化 command client + _kr_ensureCommandClientInitialized().then((_) { + KRLogUtil.kr_i('✅ Command client 已就绪,执行节点切换', tag: 'SingBox'); + + // 🔄 使用重试机制执行节点选择(异步执行,不阻塞UI) + _kr_selectOutboundWithRetry("select", tag, maxAttempts: 3, initialDelay: 50).catchError((e) { + KRLogUtil.kr_e('❌ 节点选择失败: $e', tag: 'SingBox'); + }); + }).catchError((e) { + KRLogUtil.kr_e('❌ Command client 初始化失败,节点切换取消: $e', tag: 'SingBox'); + }); + + // 🔄 如果用户选择了具体节点(不是 auto),启动定期检查和重新选择 + // 这是为了防止 urltest 自动覆盖用户的手动选择 + _nodeSelectionTimer?.cancel(); + if (tag != 'auto') { + KRLogUtil.kr_i('🔁 启动节点选择监控,防止被 auto 覆盖', tag: 'SingBox'); + _nodeSelectionTimer = Timer.periodic(const Duration(seconds: 20), (timer) { + // 每 20 秒重新选择一次,确保用户选择不被覆盖 + // 使用 then/catchError 避免异常导致 UI 阻塞 + kr_singBox.selectOutbound("select", tag).run().then((result) { + result.match( + (error) => KRLogUtil.kr_w('🔁 定时器重选节点失败: $error', tag: 'SingBox'), + (_) => KRLogUtil.kr_d('🔁 定时器重选节点成功', tag: 'SingBox'), + ); + }).catchError((error) { + KRLogUtil.kr_w('🔁 定时器重选节点异常: $error', tag: 'SingBox'); + }); + KRLogUtil.kr_d('🔁 重新确认节点选择: $tag', tag: 'SingBox'); + }); } - kr_singBox.selectOutbound("select", tag).run(); } /// 配合文件地址 diff --git a/lib/singbox/service/ffi_singbox_service.dart b/lib/singbox/service/ffi_singbox_service.dart index 2c9dd81..261188e 100755 --- a/lib/singbox/service/ffi_singbox_service.dart +++ b/lib/singbox/service/ffi_singbox_service.dart @@ -3,13 +3,11 @@ import 'dart:convert'; import 'dart:ffi'; import 'dart:io'; import 'dart:isolate'; - -// import 'package:combine/combine.dart'; // 暂时注释掉,使用 Isolate.run 替代 +import 'package:combine/combine.dart'; import 'package:ffi/ffi.dart'; import 'package:fpdart/fpdart.dart'; import 'package:kaer_with_panels/core/model/directories.dart'; import 'package:kaer_with_panels/gen/singbox_generated_bindings.dart'; - import 'package:kaer_with_panels/singbox/model/singbox_config_option.dart'; import 'package:kaer_with_panels/singbox/model/singbox_outbound.dart'; import 'package:kaer_with_panels/singbox/model/singbox_stats.dart'; @@ -31,9 +29,6 @@ class FFISingboxService with InfraLogger implements SingboxService { late final ReceivePort _statusReceiver; Stream? _serviceStatsStream; Stream>? _outboundsStream; - - /// 初始化标志,防止重复初始化 - bool _isInitialized = false; static SingboxNativeLibrary _gen() { String fullPath = ""; @@ -53,26 +48,14 @@ class FFISingboxService with InfraLogger implements SingboxService { } @override - Future init() async { - // 防止重复初始化 - if (_isInitialized) { - loggy.debug("already initialized, skipping"); - return; - } - loggy.debug("initializing"); _statusReceiver = ReceivePort('service status receiver'); - final source = _statusReceiver - .asBroadcastStream() - .map((event) => jsonDecode(event as String)) - .map(SingboxStatus.fromEvent); + final source = _statusReceiver.asBroadcastStream().map((event) => jsonDecode(event as String)).map(SingboxStatus.fromEvent); _status = ValueConnectableStream.seeded( source, const SingboxStopped(), ).autoConnect(); - - _isInitialized = true; } @override @@ -82,7 +65,7 @@ class FFISingboxService with InfraLogger implements SingboxService { ) { final port = _statusReceiver.sendPort.nativePort; return TaskEither( - () => Isolate.run( + () => CombineWorker().execute( () { _box.setupOnce(NativeApi.initializeApiDLData); final err = _box @@ -111,7 +94,7 @@ class FFISingboxService with InfraLogger implements SingboxService { bool debug, ) { return TaskEither( - () => Isolate.run( + () => CombineWorker().execute( () { final err = _box .parse( @@ -133,13 +116,10 @@ class FFISingboxService with InfraLogger implements SingboxService { @override TaskEither changeOptions(SingboxConfigOption options) { return TaskEither( - () => Isolate.run( + () => CombineWorker().execute( () { final json = jsonEncode(options.toJson()); - final err = _box - .changeHiddifyOptions(json.toNativeUtf8().cast()) - .cast() - .toDartString(); + final err = _box.changeHiddifyOptions(json.toNativeUtf8().cast()).cast().toDartString(); if (err.isNotEmpty) { return left(err); } @@ -154,7 +134,7 @@ class FFISingboxService with InfraLogger implements SingboxService { String path, ) { return TaskEither( - () => Isolate.run( + () => CombineWorker().execute( () { final response = _box .generateConfig( @@ -179,7 +159,7 @@ class FFISingboxService with InfraLogger implements SingboxService { ) { loggy.debug("starting, memory limit: [${!disableMemoryLimit}]"); return TaskEither( - () => Isolate.run( + () => CombineWorker().execute( () { final err = _box .start( @@ -200,7 +180,7 @@ class FFISingboxService with InfraLogger implements SingboxService { @override TaskEither stop() { return TaskEither( - () => Isolate.run( + () => CombineWorker().execute( () { final err = _box.stop().cast().toDartString(); if (err.isNotEmpty) { @@ -220,7 +200,7 @@ class FFISingboxService with InfraLogger implements SingboxService { ) { loggy.debug("restarting, memory limit: [${!disableMemoryLimit}]"); return TaskEither( - () => Isolate.run( + () => CombineWorker().execute( () { final err = _box .restart( @@ -278,10 +258,7 @@ class FFISingboxService with InfraLogger implements SingboxService { }, ); - final err = _box - .startCommandClient(1, receiver.sendPort.nativePort) - .cast() - .toDartString(); + final err = _box.startCommandClient(1, receiver.sendPort.nativePort).cast().toDartString(); if (err.isNotEmpty) { loggy.error("error starting status command: $err"); throw err; @@ -323,10 +300,7 @@ class FFISingboxService with InfraLogger implements SingboxService { ); try { - final err = _box - .startCommandClient(5, receiver.sendPort.nativePort) - .cast() - .toDartString(); + final err = _box.startCommandClient(5, receiver.sendPort.nativePort).cast().toDartString(); if (err.isNotEmpty) { logger.error("error starting group command: $err"); throw err; @@ -370,10 +344,7 @@ class FFISingboxService with InfraLogger implements SingboxService { ); try { - final err = _box - .startCommandClient(13, receiver.sendPort.nativePort) - .cast() - .toDartString(); + final err = _box.startCommandClient(13, receiver.sendPort.nativePort).cast().toDartString(); if (err.isNotEmpty) { logger.error("error starting: $err"); throw err; @@ -389,7 +360,7 @@ class FFISingboxService with InfraLogger implements SingboxService { @override TaskEither selectOutbound(String groupTag, String outboundTag) { return TaskEither( - () => Isolate.run( + () => CombineWorker().execute( () { final err = _box .selectOutbound( @@ -410,12 +381,9 @@ class FFISingboxService with InfraLogger implements SingboxService { @override TaskEither urlTest(String groupTag) { return TaskEither( - () => Isolate.run( + () => CombineWorker().execute( () { - final err = _box - .urlTest(groupTag.toNativeUtf8().cast()) - .cast() - .toDartString(); + final err = _box.urlTest(groupTag.toNativeUtf8().cast()).cast().toDartString(); if (err.isNotEmpty) { return left(err); } @@ -431,9 +399,7 @@ class FFISingboxService with InfraLogger implements SingboxService { @override Stream> watchLogs(String path) async* { yield await _readLogFile(File(path)); - yield* Watcher(path, pollingDelay: const Duration(seconds: 1)) - .events - .asyncMap((event) async { + yield* Watcher(path, pollingDelay: const Duration(seconds: 1)).events.asyncMap((event) async { if (event.type == ChangeType.MODIFY) { await _readLogFile(File(path)); } @@ -444,7 +410,7 @@ class FFISingboxService with InfraLogger implements SingboxService { @override TaskEither clearLogs() { return TaskEither( - () => Isolate.run( + () => CombineWorker().execute( () { _logBuffer.clear(); return right(unit); @@ -455,8 +421,7 @@ class FFISingboxService with InfraLogger implements SingboxService { Future> _readLogFile(File file) async { if (_logFilePosition == 0 && file.lengthSync() == 0) return []; - final content = - await file.openRead(_logFilePosition).transform(utf8.decoder).join(); + final content = await file.openRead(_logFilePosition).transform(utf8.decoder).join(); _logFilePosition = file.lengthSync(); final lines = const LineSplitter().convert(content); if (lines.length > 300) { @@ -479,7 +444,7 @@ class FFISingboxService with InfraLogger implements SingboxService { }) { loggy.debug("generating warp config"); return TaskEither( - () => Isolate.run( + () => CombineWorker().execute( () { final response = _box .generateWarpConfig( diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 1c93e55..aa6c143 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -82,7 +82,7 @@ SPEC CHECKSUMS: device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76 flutter_inappwebview_macos: c2d68649f9f8f1831bfcd98d73fd6256366d9d1d flutter_udid: d26e455e8c06174e6aff476e147defc6cae38495 - FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1 + FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94 package_info_plus: f0052d280d17aa382b932f399edf32507174e870 path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 diff --git a/pubspec.lock b/pubspec.lock old mode 100755 new mode 100644 index 07d5ada..f9124b2 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,32 +5,32 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: da0d9209ca76bde579f2da330aeb9df62b6319c834fa7baae052021b0462401f - url: "https://pub.dev" + sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" + url: "https://pub.flutter-io.cn" source: hosted - version: "85.0.0" + version: "67.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: f4ad0fea5f102201015c9aae9d93bc02f75dd9491529a8c21f88d17a8523d44c - url: "https://pub.dev" + sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" + url: "https://pub.flutter-io.cn" source: hosted - version: "7.6.0" + version: "6.4.1" analyzer_plugin: dependency: transitive description: name: analyzer_plugin - sha256: a5ab7590c27b779f3d4de67f31c4109dbe13dd7339f86461a6f2a8ab2594d8ce - url: "https://pub.dev" + sha256: "9661b30b13a685efaee9f02e5d01ed9f2b423bd889d28a304d02d704aee69161" + url: "https://pub.flutter-io.cn" source: hosted - version: "0.13.4" + version: "0.11.3" ansicolor: dependency: transitive description: name: ansicolor sha256: "50e982d500bc863e1d703448afdbf9e5a72eb48840a4f766fa361ffd6877055f" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.3" archive: @@ -38,7 +38,7 @@ packages: description: name: archive sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.6.1" args: @@ -46,7 +46,7 @@ packages: description: name: args sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.7.0" asn1lib: @@ -54,79 +54,79 @@ packages: description: name: asn1lib sha256: "9a8f69025044eb466b9b60ef3bc3ac99b4dc6c158ae9c56d25eeccf5bc56d024" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.6.5" async: dependency: transitive description: name: async - sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" - url: "https://pub.dev" + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.13.0" + version: "2.11.0" boolean_selector: dependency: transitive description: name: boolean_selector - sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" - url: "https://pub.dev" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.2" + version: "2.1.1" build: dependency: transitive description: name: build - sha256: "51dc711996cbf609b90cbe5b335bbce83143875a9d58e4b5c6d3c4f684d3dda7" - url: "https://pub.dev" + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.5.4" + version: "2.4.1" build_config: dependency: transitive description: name: build_config - sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33" - url: "https://pub.dev" + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.2" + version: "1.1.1" build_daemon: dependency: transitive description: name: build_daemon - sha256: "409002f1adeea601018715d613115cfaf0e31f512cb80ae4534c79867ae2363d" - url: "https://pub.dev" + sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" + url: "https://pub.flutter-io.cn" source: hosted - version: "4.1.0" + version: "4.0.2" build_resolvers: dependency: transitive description: name: build_resolvers - sha256: ee4257b3f20c0c90e72ed2b57ad637f694ccba48839a821e87db762548c22a62 - url: "https://pub.dev" + sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.5.4" + version: "2.4.2" build_runner: dependency: "direct dev" description: name: build_runner - sha256: "382a4d649addbfb7ba71a3631df0ec6a45d5ab9b098638144faf27f02778eb53" - url: "https://pub.dev" + sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.5.4" + version: "2.4.13" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: "85fbbb1036d576d966332a3f5ce83f2ce66a40bea1a94ad2d5fc29a19a0d3792" - url: "https://pub.dev" + sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 + url: "https://pub.flutter-io.cn" source: hosted - version: "9.1.2" + version: "7.3.2" built_collection: dependency: transitive description: name: built_collection sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "5.1.1" built_value: @@ -134,79 +134,87 @@ packages: description: name: built_value sha256: a30f0a0e38671e89a492c44d005b5545b830a961575bbd8336d42869ff71066d - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "8.12.0" characters: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 - url: "https://pub.dev" + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.flutter-io.cn" source: hosted - version: "1.4.0" + version: "1.3.0" charcode: dependency: transitive description: name: charcode sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.4.0" checked_yaml: dependency: transitive description: name: checked_yaml - sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f" - url: "https://pub.dev" + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.4" + version: "2.0.3" cli_util: dependency: transitive description: name: cli_util sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.4.2" clock: dependency: transitive description: name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b - url: "https://pub.dev" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.2" + version: "1.1.1" code_builder: dependency: transitive description: name: code_builder - sha256: "11654819532ba94c34de52ff5feb52bd81cba1de00ef2ed622fd50295f9d4243" - url: "https://pub.dev" + sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" + url: "https://pub.flutter-io.cn" source: hosted - version: "4.11.0" + version: "4.10.1" collection: dependency: transitive description: name: collection - sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" - url: "https://pub.dev" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.flutter-io.cn" source: hosted - version: "1.19.1" + version: "1.18.0" color: dependency: transitive description: name: color sha256: ddcdf1b3badd7008233f5acffaf20ca9f5dc2cd0172b75f68f24526a5f5725cb - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.0" + combine: + dependency: "direct main" + description: + name: combine + sha256: c16464b55d140871fbab5b37909e1808c2f020e46f9ba7deca59d40faabb6008 + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.5.7" connectivity_plus: dependency: "direct main" description: name: connectivity_plus sha256: "224a77051d52a11fbad53dd57827594d3bd24f945af28bd70bab376d68d437f0" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "5.0.2" connectivity_plus_platform_interface: @@ -214,7 +222,7 @@ packages: description: name: connectivity_plus_platform_interface sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.4" convert: @@ -222,23 +230,23 @@ packages: description: name: convert sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.1.2" country_flags: dependency: "direct main" description: name: country_flags - sha256: "78a7bf8aabd7ae1a90087f0c517471ac9ebfe07addc652692f58da0f0f833196" - url: "https://pub.dev" + sha256: "66726c7070d60c2f90c4a1d58980e9188fa04335d6287e98aef835461019c3c2" + url: "https://pub.flutter-io.cn" source: hosted - version: "3.3.0" + version: "3.2.0" crisp_sdk: dependency: "direct main" description: name: crisp_sdk sha256: "46f3112b9212bf78f166fc4e3bf7121fad2c7cada204c0dfdedef4f3d99f3cf5" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.0" crypto: @@ -246,23 +254,23 @@ packages: description: name: crypto sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.6" csslib: dependency: transitive description: name: csslib - sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" - url: "https://pub.dev" + sha256: "831883fb353c8bdc1d71979e5b342c7d88acfbc643113c14ae51e2442ea0f20f" + url: "https://pub.flutter-io.cn" source: hosted - version: "1.0.2" + version: "0.17.3" csv: dependency: transitive description: name: csv sha256: c6aa2679b2a18cb57652920f674488d89712efaf4d3fdf2e537215b35fc19d6c - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "6.0.0" cupertino_icons: @@ -270,63 +278,55 @@ packages: description: name: cupertino_icons sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.8" custom_lint_core: dependency: transitive description: name: custom_lint_core - sha256: "31110af3dde9d29fb10828ca33f1dce24d2798477b167675543ce3d208dee8be" - url: "https://pub.dev" + sha256: a85e8f78f4c52f6c63cdaf8c872eb573db0231dcdf3c3a5906d493c1f8bc20e6 + url: "https://pub.flutter-io.cn" source: hosted - version: "0.7.5" - custom_lint_visitor: - dependency: transitive - description: - name: custom_lint_visitor - sha256: "4a86a0d8415a91fbb8298d6ef03e9034dc8e323a599ddc4120a0e36c433983a2" - url: "https://pub.dev" - source: hosted - version: "1.0.0+7.7.0" + version: "0.6.3" dart_earcut: dependency: transitive description: name: dart_earcut sha256: e485001bfc05dcbc437d7bfb666316182e3522d4c3f9668048e004d0eb2ce43b - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.0" dart_mappable: dependency: "direct main" description: name: dart_mappable - sha256: "0e219930c9f7b9e0f14ae7c1de931c401875110fd5c67975b6b9492a6d3a531b" - url: "https://pub.dev" + sha256: "6eda273146ed930c1f161d0b29f4bc9ef9e87ecfb9341607833bf76b008fb7d5" + url: "https://pub.flutter-io.cn" source: hosted - version: "4.6.1" + version: "4.3.1" dart_mappable_builder: dependency: "direct dev" description: name: dart_mappable_builder - sha256: adea8c55aac73c8254aa14a8272b788eb0f72799dd8e4810a9b664ec9b4e353c - url: "https://pub.dev" + sha256: b3673a6d190f2ea766b39ea298d4c55d1caca9382a536cf164ffe7e2f955c501 + url: "https://pub.flutter-io.cn" source: hosted - version: "4.5.0" + version: "4.3.1+1" dart_style: dependency: transitive description: name: dart_style - sha256: "8a0e5fba27e8ee025d2ffb4ee820b4e6e2cf5e4246a6b1a477eb66866947e0bb" - url: "https://pub.dev" + sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" + url: "https://pub.flutter-io.cn" source: hosted - version: "3.1.1" + version: "2.3.6" dartx: dependency: "direct main" description: name: dartx sha256: "8b25435617027257d43e6508b5fe061012880ddfdaa75a71d607c3de2a13d244" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.0" dbus: @@ -334,7 +334,7 @@ packages: description: name: dbus sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.7.11" dependency_validator: @@ -342,7 +342,7 @@ packages: description: name: dependency_validator sha256: f727a5627aa405965fab4aef4f468e50a9b632ba0737fd2f98c932fec6d712b9 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.2.3" device_info_plus: @@ -350,23 +350,23 @@ packages: description: name: device_info_plus sha256: "72d146c6d7098689ff5c5f66bcf593ac11efc530095385356e131070333e64da" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "11.3.0" device_info_plus_platform_interface: dependency: transitive description: name: device_info_plus_platform_interface - sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f - url: "https://pub.dev" + sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2" + url: "https://pub.flutter-io.cn" source: hosted - version: "7.0.3" + version: "7.0.2" dio: dependency: "direct main" description: name: dio sha256: d90ee57923d1828ac14e492ca49440f65477f4bb1263575900be731a3dac66a9 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "5.9.0" dio_web_adapter: @@ -374,31 +374,31 @@ packages: description: name: dio_web_adapter sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.1" drift: dependency: transitive description: name: drift - sha256: "540cf382a3bfa99b76e51514db5b0ebcd81ce3679b7c1c9cb9478ff3735e47a1" - url: "https://pub.dev" + sha256: df027d168a2985a2e9da900adeba2ab0136f0d84436592cf3cd5135f82c8579c + url: "https://pub.flutter-io.cn" source: hosted - version: "2.28.2" + version: "2.21.0" drift_dev: dependency: "direct dev" description: name: drift_dev - sha256: "68c138e884527d2bd61df2ade276c3a144df84d1adeb0ab8f3196b5afe021bd4" - url: "https://pub.dev" + sha256: "623649abe932fc17bd32e578e7e05f7ac5e7dd0b33e6c8669a0634105d1389bf" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.28.0" + version: "2.21.2" easy_refresh: dependency: "direct main" description: name: easy_refresh sha256: "486e30abfcaae66c0f2c2798a10de2298eb9dc5e0bb7e1dba9328308968cae0c" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.4.0" encrypt: @@ -406,7 +406,7 @@ packages: description: name: encrypt sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "5.0.3" equatable: @@ -414,7 +414,7 @@ packages: description: name: equatable sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.7" extended_image: @@ -422,7 +422,7 @@ packages: description: name: extended_image sha256: "69d4299043334ecece679996e47d0b0891cd8c29d8da0034868443506f1d9a78" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "8.3.1" extended_image_library: @@ -430,31 +430,31 @@ packages: description: name: extended_image_library sha256: e61dafd94400fff6ef7ed1523d445ff3af137f198f3228e4a3107bc5b4bec5d1 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "4.0.6" fake_async: dependency: transitive description: name: fake_async - sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" - url: "https://pub.dev" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.flutter-io.cn" source: hosted - version: "1.3.3" + version: "1.3.1" ffi: dependency: transitive description: name: ffi - sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" - url: "https://pub.dev" + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.4" + version: "2.1.3" ffigen: dependency: "direct dev" description: name: ffigen sha256: d3e76c2ad48a4e7f93a29a162006f00eba46ce7c08194a77bb5c5e97d1b5ff0a - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "8.0.2" file: @@ -462,7 +462,7 @@ packages: description: name: file sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "6.1.4" fixnum: @@ -470,7 +470,7 @@ packages: description: name: fixnum sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.1" fl_chart: @@ -478,7 +478,7 @@ packages: description: name: fl_chart sha256: "00b74ae680df6b1135bdbea00a7d1fc072a9180b7c3f3702e4b19a9943f5ed7d" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.66.2" flutter: @@ -490,40 +490,40 @@ packages: dependency: transitive description: name: flutter_gen_core - sha256: "3eaa2d3d8be58267ac4cd5e215ac965dd23cae0410dc073de2e82e227be32bfc" - url: "https://pub.dev" + sha256: "53890b653738f34363d9f0d40f82104c261716bd551d3ba65f648770b6764c21" + url: "https://pub.flutter-io.cn" source: hosted - version: "5.10.0" + version: "5.9.0" flutter_gen_runner: dependency: "direct dev" description: name: flutter_gen_runner - sha256: e74b4ead01df3e8f02e73a26ca856759dbbe8cb3fd60941ba9f4005cd0cd19c9 - url: "https://pub.dev" + sha256: de70b42eb5329f712c8b041069d081ad5fb5109f32d6d1ea9c1b39596786215d + url: "https://pub.flutter-io.cn" source: hosted - version: "5.10.0" + version: "5.9.0" flutter_hooks: dependency: transitive description: name: flutter_hooks - sha256: "8ae1f090e5f4ef5cfa6670ce1ab5dddadd33f3533a7f9ba19d9f958aa2a89f42" - url: "https://pub.dev" + sha256: b772e710d16d7a20c0740c4f855095026b31c7eb5ba3ab67d2bd52021cd9461d + url: "https://pub.flutter-io.cn" source: hosted - version: "0.21.3+1" + version: "0.21.2" flutter_html: dependency: "direct main" description: name: flutter_html - sha256: "38a2fd702ffdf3243fb7441ab58aa1bc7e6922d95a50db76534de8260638558d" - url: "https://pub.dev" + sha256: "02ad69e813ecfc0728a455e4bf892b9379983e050722b1dce00192ee2e41d1ee" + url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.0" + version: "3.0.0-beta.2" flutter_inappwebview: dependency: "direct main" description: name: flutter_inappwebview sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "6.1.5" flutter_inappwebview_android: @@ -531,7 +531,7 @@ packages: description: name: flutter_inappwebview_android sha256: "62557c15a5c2db5d195cb3892aab74fcaec266d7b86d59a6f0027abd672cddba" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.3" flutter_inappwebview_internal_annotations: @@ -539,7 +539,7 @@ packages: description: name: flutter_inappwebview_internal_annotations sha256: "787171d43f8af67864740b6f04166c13190aa74a1468a1f1f1e9ee5b90c359cd" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.0" flutter_inappwebview_ios: @@ -547,7 +547,7 @@ packages: description: name: flutter_inappwebview_ios sha256: "5818cf9b26cf0cbb0f62ff50772217d41ea8d3d9cc00279c45f8aabaa1b4025d" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.2" flutter_inappwebview_macos: @@ -555,7 +555,7 @@ packages: description: name: flutter_inappwebview_macos sha256: c1fbb86af1a3738e3541364d7d1866315ffb0468a1a77e34198c9be571287da1 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.2" flutter_inappwebview_platform_interface: @@ -563,7 +563,7 @@ packages: description: name: flutter_inappwebview_platform_interface sha256: cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.3.0+1" flutter_inappwebview_web: @@ -571,7 +571,7 @@ packages: description: name: flutter_inappwebview_web sha256: "55f89c83b0a0d3b7893306b3bb545ba4770a4df018204917148ebb42dc14a598" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.2" flutter_inappwebview_windows: @@ -579,7 +579,7 @@ packages: description: name: flutter_inappwebview_windows sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.6.0" flutter_loggy: @@ -587,7 +587,7 @@ packages: description: name: flutter_loggy sha256: f7640f2d06e64a6141b2210e18cac3146f30bcb4b92349da53f969f59b78c04b - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.3+1" flutter_loggy_dio: @@ -595,7 +595,7 @@ packages: description: name: flutter_loggy_dio sha256: d17d26bb85667c14aefa6dce9b12bd2c1ae13cd75e89d25b0c799b063be55e3c - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.1.0" flutter_map: @@ -603,7 +603,7 @@ packages: description: name: flutter_map sha256: "2ecb34619a4be19df6f40c2f8dce1591675b4eff7a6857bd8f533706977385da" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "7.0.2" flutter_markdown: @@ -611,7 +611,7 @@ packages: description: name: flutter_markdown sha256: "08fb8315236099ff8e90cb87bb2b935e0a724a3af1623000a9cec930468e0f27" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.7.7+1" flutter_riverpod: @@ -619,7 +619,7 @@ packages: description: name: flutter_riverpod sha256: "9532ee6db4a943a1ed8383072a2e3eeda041db5657cdf6d2acecf3c21ecbe7e1" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.6.1" flutter_screenutil: @@ -627,17 +627,17 @@ packages: description: name: flutter_screenutil sha256: "8239210dd68bee6b0577aa4a090890342d04a136ce1c81f98ee513fc0ce891de" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "5.9.3" flutter_svg: dependency: "direct main" description: name: flutter_svg - sha256: b9c2ad5872518a27507ab432d1fb97e8813b05f0fc693f9d40fad06d073e0678 - url: "https://pub.dev" + sha256: d44bf546b13025ec7353091516f6881f1d4c633993cb109c3916c3a0159dadf1 + url: "https://pub.flutter-io.cn" source: hosted - version: "2.2.1" + version: "2.1.0" flutter_test: dependency: "direct dev" description: flutter @@ -648,7 +648,7 @@ packages: description: name: flutter_udid sha256: "166bee5989a58c66b8b62000ea65edccc7c8167bbafdbb08022638db330dd030" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "4.0.0" flutter_web_plugins: @@ -660,24 +660,24 @@ packages: dependency: "direct main" description: name: fpdart - sha256: "1b84ce64453974159f08046f5d05592020d1fcb2099d7fe6ec58da0e7337af77" - url: "https://pub.dev" + sha256: f8e9d0989ba293946673e382c59ac513e30cb6746a9452df195f29e3357a73d4 + url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.1" + version: "1.2.0" freezed: dependency: "direct dev" description: name: freezed - sha256: "59a584c24b3acdc5250bb856d0d3e9c0b798ed14a4af1ddb7dc1c7b41df91c9c" - url: "https://pub.dev" + sha256: a434911f643466d78462625df76fd9eb13e57348ff43fe1f77bbe909522c67a1 + url: "https://pub.flutter-io.cn" source: hosted - version: "2.5.8" + version: "2.5.2" freezed_annotation: dependency: "direct main" description: name: freezed_annotation sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.4.4" frontend_server_client: @@ -685,7 +685,7 @@ packages: description: name: frontend_server_client sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "4.0.0" get: @@ -693,7 +693,7 @@ packages: description: name: get sha256: c79eeb4339f1f3deffd9ec912f8a923834bec55f7b49c9e882b8fef2c139d425 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "4.7.2" glob: @@ -701,23 +701,23 @@ packages: description: name: glob sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.3" go_router_builder: dependency: "direct dev" description: name: go_router_builder - sha256: "7f6f4bfb97cadc3d25378a0237fe4ddd98b54d6094b5a5c158b775a2cc30843e" - url: "https://pub.dev" + sha256: "3425b72dea69209754ac6b71b4da34165dcd4d4a2934713029945709a246427a" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.9.0" + version: "2.7.1" google_identity_services_web: dependency: transitive description: name: google_identity_services_web sha256: "5d187c46dc59e02646e10fe82665fc3884a9b71bc1c90c2b8b749316d33ee454" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.3.3+1" googleapis_auth: @@ -725,7 +725,7 @@ packages: description: name: googleapis_auth sha256: befd71383a955535060acde8792e7efc11d2fccd03dd1d3ec434e85b68775938 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.6.0" graphs: @@ -733,7 +733,7 @@ packages: description: name: graphs sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.3.2" grpc: @@ -741,7 +741,7 @@ packages: description: name: grpc sha256: e93ee3bce45c134bf44e9728119102358c7cd69de7832d9a874e2e74eb8cab40 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.2.4" hashcodes: @@ -749,7 +749,7 @@ packages: description: name: hashcodes sha256: "80f9410a5b3c8e110c4b7604546034749259f5d6dcca63e0d3c17c9258f1a651" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.0" hive: @@ -757,7 +757,7 @@ packages: description: name: hive sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.2.3" hive_flutter: @@ -765,7 +765,7 @@ packages: description: name: hive_flutter sha256: dca1da446b1d808a51689fb5d0c6c9510c0a2ba01e22805d492c73b68e33eecc - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.0" hooks_riverpod: @@ -773,23 +773,23 @@ packages: description: name: hooks_riverpod sha256: "70bba33cfc5670c84b796e6929c54b8bc5be7d0fe15bb28c2560500b9ad06966" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.6.1" html: dependency: transitive description: name: html - sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" - url: "https://pub.dev" + sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" + url: "https://pub.flutter-io.cn" source: hosted - version: "0.15.6" + version: "0.15.4" http: dependency: transitive description: name: http sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.5.0" http2: @@ -797,7 +797,7 @@ packages: description: name: http2 sha256: "382d3aefc5bd6dc68c6b892d7664f29b5beb3251611ae946a98d35158a82bbfa" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.3.1" http_client_helper: @@ -805,7 +805,7 @@ packages: description: name: http_client_helper sha256: "8a9127650734da86b5c73760de2b404494c968a3fd55602045ffec789dac3cb1" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.0" http_multi_server: @@ -813,23 +813,23 @@ packages: description: name: http_multi_server sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.2.2" http_parser: dependency: transitive description: name: http_parser - sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" - url: "https://pub.dev" + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.flutter-io.cn" source: hosted - version: "4.1.2" + version: "4.0.2" image_size_getter: dependency: transitive description: name: image_size_getter sha256: "7c26937e0ae341ca558b7556591fd0cc456fcc454583b7cb665d2f03e93e590f" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.4.1" intl: @@ -837,7 +837,7 @@ packages: description: name: intl sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.20.2" io: @@ -845,7 +845,7 @@ packages: description: name: io sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.5" jovial_misc: @@ -853,23 +853,23 @@ packages: description: name: jovial_misc sha256: "4301011027d87b8b919cb862db84071a34448eadbb32cc8d40fe505424dfe69a" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.9.2" jovial_svg: dependency: transitive description: name: jovial_svg - sha256: "08dd24b800d48796c9c0227acb96eb00c6cacccb1d7de58d79fc924090049868" - url: "https://pub.dev" + sha256: ca14d42956b9949c36333065c9141f100e930c918f57f4bd8dd59d35581bd3fc + url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.28" + version: "1.1.24" js: dependency: transitive description: name: js sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.6.7" json2yaml: @@ -877,7 +877,7 @@ packages: description: name: json2yaml sha256: da94630fbc56079426fdd167ae58373286f603371075b69bf46d848d63ba3e51 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.1" json_annotation: @@ -885,63 +885,63 @@ packages: description: name: json_annotation sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "4.9.0" json_serializable: dependency: "direct dev" description: name: json_serializable - sha256: c50ef5fc083d5b5e12eef489503ba3bf5ccc899e487d691584699b4bdefeea8c - url: "https://pub.dev" + sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b + url: "https://pub.flutter-io.cn" source: hosted - version: "6.9.5" + version: "6.8.0" latlong2: dependency: "direct main" description: name: latlong2 sha256: "98227922caf49e6056f91b6c56945ea1c7b166f28ffcd5fb8e72fc0b453cc8fe" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.9.1" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" - url: "https://pub.dev" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + url: "https://pub.flutter-io.cn" source: hosted - version: "11.0.2" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" - url: "https://pub.dev" + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.10" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" - url: "https://pub.dev" + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.2" + version: "3.0.1" lint: dependency: "direct dev" description: name: lint - sha256: "3cd03646de313481336500ba02eb34d07c590535525f154aae7fda7362aa07a9" - url: "https://pub.dev" + sha256: "2a1da23938013e5ec7cba18b97376fa685968ce96ae752c27b16742489006af2" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.8.0" + version: "2.6.2" list_counter: dependency: transitive description: name: list_counter sha256: c447ae3dfcd1c55f0152867090e67e219d42fe6d4f2807db4bbe8b8d69912237 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.2" lists: @@ -949,7 +949,7 @@ packages: description: name: lists sha256: "4ca5c19ae4350de036a7e996cdd1ee39c93ac0a2b840f4915459b7d0a7d4ab27" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.1" logger: @@ -957,7 +957,7 @@ packages: description: name: logger sha256: a7967e31b703831a893bbc3c3dd11db08126fe5f369b5c648a36f821979f5be3 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.6.2" logging: @@ -965,7 +965,7 @@ packages: description: name: logging sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.3.0" loggy: @@ -973,7 +973,7 @@ packages: description: name: loggy sha256: "981e03162bbd3a5a843026f75f73d26e4a0d8aa035ae060456ca7b30dfd1e339" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.3" markdown: @@ -981,23 +981,23 @@ packages: description: name: markdown sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "7.3.0" matcher: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 - url: "https://pub.dev" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + url: "https://pub.flutter-io.cn" source: hosted - version: "0.12.17" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.11.1" menu_base: @@ -1005,23 +1005,23 @@ packages: description: name: menu_base sha256: "820368014a171bd1241030278e6c2617354f492f5c703d7b7d4570a6b8b84405" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.1" meta: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c - url: "https://pub.dev" + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + url: "https://pub.flutter-io.cn" source: hosted - version: "1.16.0" + version: "1.15.0" mgrs_dart: dependency: transitive description: name: mgrs_dart sha256: fb89ae62f05fa0bb90f70c31fc870bcbcfd516c843fb554452ab3396f78586f7 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.0" mime: @@ -1029,7 +1029,7 @@ packages: description: name: mime sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.0" nm: @@ -1037,7 +1037,7 @@ packages: description: name: nm sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.5.0" package_config: @@ -1045,7 +1045,7 @@ packages: description: name: package_config sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.2.0" package_info_plus: @@ -1053,7 +1053,7 @@ packages: description: name: package_info_plus sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "8.3.1" package_info_plus_platform_interface: @@ -1061,23 +1061,23 @@ packages: description: name: package_info_plus_platform_interface sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.2.1" path: dependency: "direct main" description: name: path - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" - url: "https://pub.dev" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + url: "https://pub.flutter-io.cn" source: hosted - version: "1.9.1" + version: "1.9.0" path_drawing: dependency: transitive description: name: path_drawing sha256: bbb1934c0cbb03091af082a6389ca2080345291ef07a5fa6d6e078ba8682f977 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.1" path_parsing: @@ -1085,7 +1085,7 @@ packages: description: name: path_parsing sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.0" path_provider: @@ -1093,31 +1093,31 @@ packages: description: name: path_provider sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.5" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: e122c5ea805bb6773bb12ce667611265980940145be920cd09a4b0ec0285cb16 - url: "https://pub.dev" + sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.2.20" + version: "2.2.15" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: efaec349ddfc181528345c56f8eda9d6cccd71c177511b132c6a0ddaefaa2738 - url: "https://pub.dev" + sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.4.3" + version: "2.4.1" path_provider_linux: dependency: transitive description: name: path_provider_linux sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.2.1" path_provider_platform_interface: @@ -1125,7 +1125,7 @@ packages: description: name: path_provider_platform_interface sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.2" path_provider_windows: @@ -1133,7 +1133,7 @@ packages: description: name: path_provider_windows sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.3.0" permission_handler: @@ -1141,7 +1141,7 @@ packages: description: name: permission_handler sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "11.4.0" permission_handler_android: @@ -1149,7 +1149,7 @@ packages: description: name: permission_handler_android sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "12.1.0" permission_handler_apple: @@ -1157,7 +1157,7 @@ packages: description: name: permission_handler_apple sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "9.4.7" permission_handler_html: @@ -1165,7 +1165,7 @@ packages: description: name: permission_handler_html sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.3+5" permission_handler_platform_interface: @@ -1173,7 +1173,7 @@ packages: description: name: permission_handler_platform_interface sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "4.3.0" permission_handler_windows: @@ -1181,23 +1181,23 @@ packages: description: name: permission_handler_windows sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.2.1" petitparser: dependency: transitive description: name: petitparser - sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1" - url: "https://pub.dev" + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + url: "https://pub.flutter-io.cn" source: hosted - version: "7.0.1" + version: "6.0.2" platform: dependency: transitive description: name: platform sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.1.6" plugin_platform_interface: @@ -1205,7 +1205,7 @@ packages: description: name: plugin_platform_interface sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.8" pointycastle: @@ -1213,7 +1213,7 @@ packages: description: name: pointycastle sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.9.1" polylabel: @@ -1221,7 +1221,7 @@ packages: description: name: polylabel sha256: "41b9099afb2aa6c1730bdd8a0fab1400d287694ec7615dd8516935fa3144214b" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.1" pool: @@ -1229,7 +1229,7 @@ packages: description: name: pool sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.5.2" proj4dart: @@ -1237,7 +1237,7 @@ packages: description: name: proj4dart sha256: c8a659ac9b6864aa47c171e78d41bbe6f5e1d7bd790a5814249e6b68bc44324e - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.0" protobuf: @@ -1245,7 +1245,7 @@ packages: description: name: protobuf sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.1.0" protocol_handler_platform_interface: @@ -1253,7 +1253,7 @@ packages: description: name: protocol_handler_platform_interface sha256: "53776b10526fdc25efdf1abcf68baf57fdfdb75342f4101051db521c9e3f3e5b" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.2.0" protocol_handler_windows: @@ -1261,7 +1261,7 @@ packages: description: name: protocol_handler_windows sha256: d8f3a58938386aca2c76292757392f4d059d09f11439d6d896d876ebe997f2c4 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.2.0" pub_semver: @@ -1269,23 +1269,23 @@ packages: description: name: pub_semver sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.2.0" pubspec_parse: dependency: transitive description: name: pubspec_parse - sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" - url: "https://pub.dev" + sha256: "81876843eb50dc2e1e5b151792c9a985c5ed2536914115ed04e9c8528f6647b0" + url: "https://pub.flutter-io.cn" source: hosted - version: "1.5.0" + version: "1.4.0" qr: dependency: transitive description: name: qr sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.2" qr_flutter: @@ -1293,7 +1293,7 @@ packages: description: name: qr_flutter sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "4.1.0" quiver: @@ -1301,7 +1301,7 @@ packages: description: name: quiver sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.2.2" recase: @@ -1309,7 +1309,7 @@ packages: description: name: recase sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "4.1.0" riverpod: @@ -1317,39 +1317,39 @@ packages: description: name: riverpod sha256: "59062512288d3056b2321804332a13ffdd1bf16df70dcc8e506e411280a72959" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.6.1" riverpod_analyzer_utils: dependency: transitive description: name: riverpod_analyzer_utils - sha256: "837a6dc33f490706c7f4632c516bcd10804ee4d9ccc8046124ca56388715fdf3" - url: "https://pub.dev" + sha256: "8b71f03fc47ae27d13769496a1746332df4cec43918aeba9aff1e232783a780f" + url: "https://pub.flutter-io.cn" source: hosted - version: "0.5.9" + version: "0.5.1" riverpod_annotation: dependency: "direct main" description: name: riverpod_annotation sha256: e14b0bf45b71326654e2705d462f21b958f987087be850afd60578fcd502d1b8 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.6.1" riverpod_generator: dependency: "direct dev" description: name: riverpod_generator - sha256: "120d3310f687f43e7011bb213b90a436f1bbc300f0e4b251a72c39bccb017a4f" - url: "https://pub.dev" + sha256: d451608bf17a372025fc36058863737636625dfdb7e3cbf6142e0dfeb366ab22 + url: "https://pub.flutter-io.cn" source: hosted - version: "2.6.4" + version: "2.4.0" rxdart: dependency: "direct main" description: name: rxdart sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.27.7" screen_retriever: @@ -1357,7 +1357,7 @@ packages: description: name: screen_retriever sha256: "570dbc8e4f70bac451e0efc9c9bb19fa2d6799a11e6ef04f946d7886d2e23d0c" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.2.0" screen_retriever_linux: @@ -1365,7 +1365,7 @@ packages: description: name: screen_retriever_linux sha256: f7f8120c92ef0784e58491ab664d01efda79a922b025ff286e29aa123ea3dd18 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.2.0" screen_retriever_macos: @@ -1373,7 +1373,7 @@ packages: description: name: screen_retriever_macos sha256: "71f956e65c97315dd661d71f828708bd97b6d358e776f1a30d5aa7d22d78a149" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.2.0" screen_retriever_platform_interface: @@ -1381,7 +1381,7 @@ packages: description: name: screen_retriever_platform_interface sha256: ee197f4581ff0d5608587819af40490748e1e39e648d7680ecf95c05197240c0 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.2.0" screen_retriever_windows: @@ -1389,44 +1389,44 @@ packages: description: name: screen_retriever_windows sha256: "449ee257f03ca98a57288ee526a301a430a344a161f9202b4fcc38576716fe13" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.2.0" shelf: dependency: transitive description: name: shelf - sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 - url: "https://pub.dev" + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + url: "https://pub.flutter-io.cn" source: hosted - version: "1.4.2" + version: "1.4.1" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" - url: "https://pub.dev" + sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67 + url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.0" + version: "2.0.1" shortid: dependency: transitive description: name: shortid sha256: d0b40e3dbb50497dad107e19c54ca7de0d1a274eb9b4404991e443dadb9ebedb - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.2" sky_engine: dependency: transitive description: flutter source: sdk - version: "0.0.0" + version: "0.0.99" slang: dependency: "direct main" description: name: slang sha256: a466773de768eb95bdf681e0a92e7c8010d44bb247b62130426c83ece33aeaed - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.32.0" slang_build_runner: @@ -1434,7 +1434,7 @@ packages: description: name: slang_build_runner sha256: b2e0c63f3c801a4aa70b4ca43173893d6eb7d5a421fc9d97ad983527397631b3 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.32.0" slang_flutter: @@ -1442,119 +1442,111 @@ packages: description: name: slang_flutter sha256: "1a98e878673996902fa5ef0b61ce5c245e41e4d25640d18af061c6aab917b0c7" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.32.0" source_gen: dependency: transitive description: name: source_gen - sha256: "35c8150ece9e8c8d263337a265153c3329667640850b9304861faea59fc98f6b" - url: "https://pub.dev" + sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.0" + version: "1.5.0" source_helper: dependency: transitive description: name: source_helper - sha256: a447acb083d3a5ef17f983dd36201aeea33fedadb3228fa831f2f0c92f0f3aca - url: "https://pub.dev" + sha256: "86d247119aedce8e63f4751bd9626fc9613255935558447569ad42f9f5b48b3c" + url: "https://pub.flutter-io.cn" source: hosted - version: "1.3.7" + version: "1.3.5" source_span: dependency: transitive description: name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" - url: "https://pub.dev" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.flutter-io.cn" source: hosted - version: "1.10.1" - sprintf: - dependency: transitive - description: - name: sprintf - sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" - url: "https://pub.dev" - source: hosted - version: "7.0.0" + version: "1.10.0" sqlite3: dependency: transitive description: name: sqlite3 sha256: f18fd9a72d7a1ad2920db61368f2a69368f1cc9b56b8233e9d83b47b0a8435aa - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.9.3" sqlparser: dependency: transitive description: name: sqlparser - sha256: "57090342af1ce32bb499aa641f4ecdd2d6231b9403cea537ac059e803cc20d67" - url: "https://pub.dev" + sha256: d77749237609784e337ec36c979d41f6f38a7b279df98622ae23929c8eb954a4 + url: "https://pub.flutter-io.cn" source: hosted - version: "0.41.2" + version: "0.39.2" stack_trace: dependency: transitive description: name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" - url: "https://pub.dev" + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.flutter-io.cn" source: hosted - version: "1.12.1" + version: "1.11.1" state_notifier: dependency: transitive description: name: state_notifier sha256: b8677376aa54f2d7c58280d5a007f9e8774f1968d1fb1c096adcb4792fba29bb - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.0" stream_channel: dependency: transitive description: name: stream_channel - sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" - url: "https://pub.dev" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.4" + version: "2.1.2" stream_transform: dependency: transitive description: name: stream_transform sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.1" string_scanner: dependency: transitive description: name: string_scanner - sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" - url: "https://pub.dev" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.flutter-io.cn" source: hosted - version: "1.4.1" + version: "1.2.0" term_glyph: dependency: transitive description: name: term_glyph - sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" - url: "https://pub.dev" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.flutter-io.cn" source: hosted - version: "1.2.2" + version: "1.2.1" test_api: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" - url: "https://pub.dev" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + url: "https://pub.flutter-io.cn" source: hosted - version: "0.7.6" + version: "0.7.2" time: dependency: transitive description: name: time sha256: "370572cf5d1e58adcb3e354c47515da3f7469dac3a95b447117e728e7be6f461" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.5" timing: @@ -1562,7 +1554,7 @@ packages: description: name: timing sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.2" tint: @@ -1570,7 +1562,7 @@ packages: description: name: tint sha256: "9652d9a589f4536d5e392cf790263d120474f15da3cf1bee7f1fdb31b4de5f46" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.1" tray_manager: @@ -1578,7 +1570,7 @@ packages: description: name: tray_manager sha256: bdc3ac6c36f3d12d871459e4a9822705ce5a1165a17fa837103bc842719bf3f7 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.2.4" type_plus: @@ -1586,7 +1578,7 @@ packages: description: name: type_plus sha256: d5d1019471f0d38b91603adb9b5fd4ce7ab903c879d2fbf1a3f80a630a03fcc9 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.1" typed_data: @@ -1594,7 +1586,7 @@ packages: description: name: typed_data sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.4.0" unicode: @@ -1602,127 +1594,119 @@ packages: description: name: unicode sha256: "0f69e46593d65245774d4f17125c6084d2c20b4e473a983f6e21b7d7762218f1" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.3.1" url_launcher: dependency: "direct main" description: name: url_launcher - sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 - url: "https://pub.dev" + sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603" + url: "https://pub.flutter-io.cn" source: hosted - version: "6.3.2" + version: "6.3.1" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "5c8b6c2d89a78f5a1cca70a73d9d5f86c701b36b42f9c9dac7bad592113c28e9" - url: "https://pub.dev" + sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193" + url: "https://pub.flutter-io.cn" source: hosted - version: "6.3.24" + version: "6.3.14" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "6b63f1441e4f653ae799166a72b50b1767321ecc263a57aadf825a7a2a5477d9" - url: "https://pub.dev" + sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb" + url: "https://pub.flutter-io.cn" source: hosted - version: "6.3.5" + version: "6.3.3" url_launcher_linux: dependency: transitive description: name: url_launcher_linux sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.2.1" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - sha256: "8262208506252a3ed4ff5c0dc1e973d2c0e0ef337d0a074d35634da5d44397c9" - url: "https://pub.dev" + sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2" + url: "https://pub.flutter-io.cn" source: hosted - version: "3.2.4" + version: "3.2.2" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.3.2" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" - url: "https://pub.dev" + sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.4.1" + version: "2.3.3" url_launcher_windows: dependency: transitive description: name: url_launcher_windows sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.1.4" - uuid: - dependency: transitive - description: - name: uuid - sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff - url: "https://pub.dev" - source: hosted - version: "4.5.1" vector_graphics: dependency: transitive description: name: vector_graphics - sha256: a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6 - url: "https://pub.dev" + sha256: "44cc7104ff32563122a929e4620cf3efd584194eec6d1d913eb5ba593dbcf6de" + url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.19" + version: "1.1.18" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.13" vector_graphics_compiler: dependency: transitive description: name: vector_graphics_compiler - sha256: d354a7ec6931e6047785f4db12a1f61ec3d43b207fc0790f863818543f8ff0dc - url: "https://pub.dev" + sha256: "1b4b9e706a10294258727674a340ae0d6e64a7231980f9f9a3d12e4b42407aad" + url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.19" + version: "1.1.16" vector_math: dependency: transitive description: name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b - url: "https://pub.dev" + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.2.0" + version: "2.1.4" vm_service: dependency: transitive description: name: vm_service - sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" - url: "https://pub.dev" + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + url: "https://pub.flutter-io.cn" source: hosted - version: "15.0.2" + version: "14.2.5" watcher: dependency: transitive description: name: watcher sha256: "592ab6e2892f67760543fb712ff0177f4ec76c031f02f5b4ff8d3fc5eb9fb61a" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.4" web: @@ -1730,7 +1714,7 @@ packages: description: name: web sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.1" web_socket: @@ -1738,7 +1722,7 @@ packages: description: name: web_socket sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.1" web_socket_channel: @@ -1746,55 +1730,55 @@ packages: description: name: web_socket_channel sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.3" webview_flutter: dependency: "direct main" description: name: webview_flutter - sha256: c3e4fe614b1c814950ad07186007eff2f2e5dd2935eba7b9a9a1af8e5885f1ba - url: "https://pub.dev" + sha256: "889a0a678e7c793c308c68739996227c9661590605e70b1f6cf6b9a6634f7aec" + url: "https://pub.flutter-io.cn" source: hosted - version: "4.13.0" + version: "4.10.0" webview_flutter_android: dependency: transitive description: name: webview_flutter_android - sha256: e5201c620eb2637dca88a756961fae4a7191bb30b4f2271e08b746405ffdf3fd - url: "https://pub.dev" + sha256: "512c26ccc5b8a571fd5d13ec994b7509f142ff6faf85835e243dde3538fdc713" + url: "https://pub.flutter-io.cn" source: hosted - version: "4.10.5" + version: "4.3.2" webview_flutter_platform_interface: dependency: transitive description: name: webview_flutter_platform_interface - sha256: "63d26ee3aca7256a83ccb576a50272edd7cfc80573a4305caa98985feb493ee0" - url: "https://pub.dev" + sha256: "7cb32b21825bd65569665c32bb00a34ded5779786d6201f5350979d2d529940d" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.14.0" + version: "2.13.0" webview_flutter_wkwebview: dependency: transitive description: name: webview_flutter_wkwebview - sha256: fea63576b3b7e02b2df8b78ba92b48ed66caec2bb041e9a0b1cbd586d5d80bfd - url: "https://pub.dev" + sha256: a3d461fe3467014e05f3ac4962e5fdde2a4bf44c561cb53e9ae5c586600fdbc3 + url: "https://pub.flutter-io.cn" source: hosted - version: "3.23.1" + version: "3.22.0" win32: dependency: transitive description: name: win32 - sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e - url: "https://pub.dev" + sha256: daf97c9d80197ed7b619040e86c8ab9a9dad285e7671ee7390f9180cc828a51e + url: "https://pub.flutter-io.cn" source: hosted - version: "5.15.0" + version: "5.10.1" win32_registry: dependency: transitive description: name: win32_registry sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.5" window_manager: @@ -1802,7 +1786,7 @@ packages: description: name: window_manager sha256: "732896e1416297c63c9e3fb95aea72d0355f61390263982a47fd519169dc5059" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.4.3" wkt_parser: @@ -1810,7 +1794,7 @@ packages: description: name: wkt_parser sha256: "8a555fc60de3116c00aad67891bcab20f81a958e4219cc106e3c037aa3937f13" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.0" xdg_directories: @@ -1818,23 +1802,23 @@ packages: description: name: xdg_directories sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.0" xml: dependency: transitive description: name: xml - sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" - url: "https://pub.dev" + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + url: "https://pub.flutter-io.cn" source: hosted - version: "6.6.1" + version: "6.5.0" yaml: dependency: transitive description: name: yaml sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.1.3" yaml_edit: @@ -1842,9 +1826,9 @@ packages: description: name: yaml_edit sha256: fb38626579fb345ad00e674e2af3a5c9b0cc4b9bfb8fd7f7ff322c7c9e62aef5 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.2.2" sdks: - dart: ">=3.9.0 <4.0.0" - flutter: ">=3.35.0" + dart: ">=3.5.0 <4.0.0" + flutter: ">=3.24.0" diff --git a/pubspec.yaml b/pubspec.yaml index 3f38d5f..dac0f5f 100755 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -61,7 +61,7 @@ dependencies: fpdart: ^1.1.0 dartx: ^1.2.0 rxdart: ^0.27.7 - # combine: ^0.5.8 # 暂时移除,使用 Isolate.run 替代 + combine: 0.5.7 # 精确版本,兼容 Flutter 3.24.3(与 hiddify-app 相同) encrypt: ^5.0.0 path: ^1.8.3 path_provider: ^2.1.1 @@ -140,6 +140,7 @@ dev_dependencies: flutter: assets: - assets/images/ + - assets/geosite/ - assets/translations/strings_en.i18n.json - assets/translations/strings_zh.i18n.json - assets/translations/strings_es.i18n.json