diff --git a/.gitignore b/.gitignore index 0fa6b675..a4794805 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,6 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release + +/android/app/fjy.androidstudio.key +/release diff --git a/android/app/build.gradle b/android/app/build.gradle index c59123a3..4f2899b0 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -6,6 +6,12 @@ if (localPropertiesFile.exists()) { } } +def keystoreProperties = new Properties() +def keystorePropertiesFile = rootProject.file('key.properties') +if (keystorePropertiesFile.exists()) { + keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) +} + def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") @@ -50,6 +56,15 @@ android { versionName flutterVersionName } + signingConfigs { + release { + keyAlias keystoreProperties['keyAlias'] + keyPassword keystoreProperties['keyPassword'] + storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null + storePassword keystoreProperties['storePassword'] + } + } + buildTypes { release { // TODO: Add your own signing config for the release build. diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 22bcc5ad..a6daf69f 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2,8 +2,12 @@ PODS: - countly_flutter (20.11.4): - Flutter - Flutter (1.0.0) + - GZ-NMSSH (4.1.5) - path_provider (0.0.1): - Flutter + - ssh2 (2.2.2): + - Flutter + - GZ-NMSSH (~> 4.1.5) - url_launcher (0.0.1): - Flutter @@ -11,8 +15,13 @@ DEPENDENCIES: - countly_flutter (from `.symlinks/plugins/countly_flutter/ios`) - Flutter (from `Flutter`) - path_provider (from `.symlinks/plugins/path_provider/ios`) + - ssh2 (from `.symlinks/plugins/ssh2/ios`) - url_launcher (from `.symlinks/plugins/url_launcher/ios`) +SPEC REPOS: + trunk: + - GZ-NMSSH + EXTERNAL SOURCES: countly_flutter: :path: ".symlinks/plugins/countly_flutter/ios" @@ -20,15 +29,19 @@ EXTERNAL SOURCES: :path: Flutter path_provider: :path: ".symlinks/plugins/path_provider/ios" + ssh2: + :path: ".symlinks/plugins/ssh2/ios" url_launcher: :path: ".symlinks/plugins/url_launcher/ios" SPEC CHECKSUMS: countly_flutter: 38419412e193a1faa5babeb5d28a63fda260687d Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a + GZ-NMSSH: d749f8ae2fd0094b953cd1d5abd8e0cab3c93f8d path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c + ssh2: 5ded7906964d0e71e2204e5e031a155528df4674 url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c -COCOAPODS: 1.10.2 +COCOAPODS: 1.11.2 diff --git a/ios/build/Pods.build/Release-iphonesimulator/GZ-NMSSH.build/dgph b/ios/build/Pods.build/Release-iphonesimulator/GZ-NMSSH.build/dgph new file mode 100644 index 00000000..c64f034c Binary files /dev/null and b/ios/build/Pods.build/Release-iphonesimulator/GZ-NMSSH.build/dgph differ diff --git a/ios/build/Pods.build/Release-iphonesimulator/ssh2.build/dgph b/ios/build/Pods.build/Release-iphonesimulator/ssh2.build/dgph new file mode 100644 index 00000000..c64f034c Binary files /dev/null and b/ios/build/Pods.build/Release-iphonesimulator/ssh2.build/dgph differ diff --git a/lib/data/model/server.dart b/lib/data/model/server.dart new file mode 100644 index 00000000..bc543bb4 --- /dev/null +++ b/lib/data/model/server.dart @@ -0,0 +1,11 @@ +import 'package:ssh2/ssh2.dart'; +import 'package:toolbox/data/model/server_private_info.dart'; +import 'package:toolbox/data/model/server_status.dart'; + +class ServerInfo { + ServerPrivateInfo info; + ServerStatus status; + SSHClient client; + + ServerInfo(this.info, this.status, this.client); +} diff --git a/lib/data/provider/server.dart b/lib/data/provider/server.dart index ce817a89..a3c02fac 100644 --- a/lib/data/provider/server.dart +++ b/lib/data/provider/server.dart @@ -11,9 +11,9 @@ import 'package:toolbox/data/store/server.dart'; import 'package:toolbox/locator.dart'; class ServerProvider extends BusyProvider { - late List _servers; - late List _serversStatus; - late List _clients; + List _servers = []; + List _serversStatus = []; + List _clients = []; List get servers => _servers; List get serversStatus => _serversStatus; @@ -23,11 +23,11 @@ class ServerProvider extends BusyProvider { memList: [100, 0], disk: [ DiskInfo( - mountLocation: '', - mountPath: '', - used: '', - size: '', - avail: '', + mountLocation: '/', + mountPath: '/', + used: '0', + size: '0', + avail: '0', usedPercent: 0) ], sysVer: '', @@ -37,17 +37,35 @@ class ServerProvider extends BusyProvider { Future loadLocalData() async { setBusyState(true); _servers = locator().fetch(); - _serversStatus = List.generate(_servers.length, (_) => emptyStatus); + initStatusList(); + setBusyState(false); + notifyListeners(); + } + + void initStatusList() { _clients = List.generate( _servers.length, - (idx) => SSHClient( + (idx) => _fillClient(idx)); + _serversStatus = List.generate(_servers.length, (idx) => _fillStatus(idx)); + } + + SSHClient _fillClient(int idx) { + if (idx < _clients.length) { + return _clients[idx]; + } + return SSHClient( host: _servers[idx].ip!, port: _servers[idx].port!, username: _servers[idx].user!, passwordOrKey: _servers[idx].authorization, - )); - setBusyState(false); - notifyListeners(); + ); + } + + ServerStatus _fillStatus(int idx) { + if (idx < _serversStatus.length) { + return _serversStatus[idx]; + } + return emptyStatus; } Future refreshData() async { @@ -57,7 +75,7 @@ class ServerProvider extends BusyProvider { } Future startAutoRefresh() async { - Timer.periodic(const Duration(seconds: 3), (_) async { + Timer.periodic(const Duration(seconds: 7), (_) async { await refreshData(); }); } @@ -65,12 +83,21 @@ class ServerProvider extends BusyProvider { void addServer(ServerPrivateInfo info) { _servers.add(info); locator().put(info); + initStatusList(); notifyListeners(); } void delServer(ServerPrivateInfo info) { _servers.remove(info); locator().delete(info); + initStatusList(); + notifyListeners(); + } + + void updateServer(ServerPrivateInfo old, ServerPrivateInfo newInfo) { + _servers[_servers.indexOf(old)] = newInfo; + locator().update(old, newInfo); + initStatusList(); notifyListeners(); } diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index c9bd77ba..b3a17e7c 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,9 +2,8 @@ class BuildData { static const String name = "ToolBox"; - static const int build = 40; - static const String engine = - "Flutter 2.2.3 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision f4abaa0735 (9 weeks ago) • 2021-07-01 12:46:11 -0700\nEngine • revision 241c87ad80\nTools • Dart 2.13.4\n"; - static const String buildAt = "2021-09-04 09:34:17.507782"; - static const int modifications = 0; + static const int build = 10; + static const String engine = "Flutter 2.5.0 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 4cc385b4b8 (10 days ago) • 2021-09-07 23:01:49 -0700\nEngine • revision f0826da7ef\nTools • Dart 2.14.0\n"; + static const String buildAt = "2021-09-18 17:25:30.528659"; + static const int modifications = 9; } diff --git a/lib/data/store/server.dart b/lib/data/store/server.dart index 06568f21..40b1e6ec 100644 --- a/lib/data/store/server.dart +++ b/lib/data/store/server.dart @@ -17,11 +17,18 @@ class ServerStore extends PersistentStore { void delete(ServerPrivateInfo s) { final ss = fetch(); - ss.removeWhere((e) => e.ip == s.ip && e.port == s.port && e.user == e.user); + ss.removeAt(index(s)); box.put('servers', json.encode(ss)); } - bool have(ServerPrivateInfo s) => fetch() - .where((e) => e.ip == s.ip && e.port == s.port && e.user == e.user) - .isNotEmpty; + void update(ServerPrivateInfo old, ServerPrivateInfo newInfo) { + final ss = fetch(); + ss[index(old)] = newInfo; + box.put('servers', json.encode(ss)); + } + + int index(ServerPrivateInfo s) => fetch() + .indexWhere((e) => e.ip == s.ip && e.port == s.port && e.user == e.user); + + bool have(ServerPrivateInfo s) => index(s) != -1; } diff --git a/lib/view/page/server.dart b/lib/view/page/server.dart index 0571c280..caafea9e 100644 --- a/lib/view/page/server.dart +++ b/lib/view/page/server.dart @@ -81,36 +81,7 @@ class _ServerPageState extends State onTap: () => FocusScope.of(context).requestFocus(FocusNode()), ), floatingActionButton: FloatingActionButton( - onPressed: () { - showRoundDialog(context, '新建服务器连接', _buildTextInputField(context), [ - TextButton( - onPressed: () => Navigator.of(context).pop(), - child: const Text('关闭')), - TextButton( - onPressed: () { - final authorization = keyController.text.isEmpty - ? passwordController.text - : { - "privateKey": keyController.text, - "passphrase": passwordController.text - }; - serverProvider.addServer(ServerPrivateInfo( - name: nameController.text, - ip: ipController.text, - port: int.parse(portController.text), - user: usernameController.text, - authorization: authorization)); - nameController.clear(); - ipController.clear(); - portController.clear(); - usernameController.clear(); - passwordController.clear(); - keyController.clear(); - Navigator.of(context).pop(); - }, - child: const Text('连接')) - ]); - }, + onPressed: () => showAddServerDialog(), tooltip: 'add a server', heroTag: 'server page fab', child: const Icon(Icons.add), @@ -118,6 +89,37 @@ class _ServerPageState extends State ); } + void showAddServerDialog() { + showRoundDialog(context, '新建服务器连接', _buildTextInputField(context), [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('关闭')), + TextButton( + onPressed: () { + final authorization = keyController.text.isEmpty + ? passwordController.text + : { + "privateKey": keyController.text, + "passphrase": passwordController.text + }; + serverProvider.addServer(ServerPrivateInfo( + name: nameController.text, + ip: ipController.text, + port: int.parse(portController.text), + user: usernameController.text, + authorization: authorization)); + nameController.clear(); + ipController.clear(); + portController.clear(); + usernameController.clear(); + passwordController.clear(); + keyController.clear(); + Navigator.of(context).pop(); + }, + child: const Text('连接')) + ]); + } + InputDecoration _buildDecoration(String label, {TextStyle? textStyle}) { return InputDecoration(labelText: label, labelStyle: textStyle); } @@ -214,6 +216,13 @@ class _ServerPageState extends State for (var e in ss.memList!) { memData.add(IndexPercent(ss.memList!.indexOf(e), e!.toInt())); } + + final mem1 = memData[1]; + memData[1] = memData.last; + memData.last = mem1; + + final rootDisk = ss.disk!.firstWhere((element) => element!.mountLocation == '/'); + return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -247,42 +256,45 @@ class _ServerPageState extends State ss.memList![1]! / ss.memList![0]! * 100, 'Mem', [ chart.Series( id: 'Mem', - domainFn: (IndexPercent sales, _) => sales.id, - measureFn: (IndexPercent sales, _) => sales.percent, + domainFn: (IndexPercent mem, _) => mem.id, + measureFn: (IndexPercent mem, _) => mem.percent, data: memData, ) ]), - _buildIOData('Net', ss.tcp!.maxConn!.toString(), '0kb/s'), - _buildIOData('Disk', '0kb/s', '0kb/s') + _buildIOData('Net', 'Conn:\n' + ss.tcp!.maxConn!.toString(), 'Fail:\n' + ss.tcp!.fail.toString()), + _buildIOData('Disk', 'Total:\n' + rootDisk!.size!, 'Used:\n' + rootDisk.usedPercent.toString() + '%') ], - ) + ), ], ); } Widget _buildIOData(String title, String up, String down) { + final statusTextStyle = TextStyle(fontSize: 11, color: _theme.textTheme.bodyText1!.color!.withAlpha(177)); return SizedBox( width: _media.size.width * 0.2, height: _media.size.height * 0.1, child: Stack( children: [ - Positioned( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, + Positioned.fill( + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - '↓$up', - textAlign: TextAlign.start, + up, + style: statusTextStyle, + textAlign: TextAlign.center, ), + const SizedBox(height: 3), Text( - '↑$down', + down + '\n', + style: statusTextStyle, textAlign: TextAlign.center, ) ], ), - top: _media.size.height * 0.012, - left: 0, - right: 0, + ), ), Positioned( child: Text(title, textAlign: TextAlign.center), @@ -302,14 +314,11 @@ class _ServerPageState extends State child: Stack( children: [ DonutPieChart(series), - Positioned( - child: Text( - '${percent.toStringAsFixed(1)}%', + Positioned.fill( + child: Center(child: Text( + '${percent.toStringAsFixed(1)}%\n', textAlign: TextAlign.center, - ), - left: 0, - right: 0, - top: _media.size.height * 0.03, + ),), ), Positioned( child: Text(title, textAlign: TextAlign.center), diff --git a/make.dart b/make.dart old mode 100644 new mode 100755 diff --git a/pubspec.lock b/pubspec.lock index b43347df..5d322f71 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,63 +5,63 @@ packages: dependency: "direct main" description: name: after_layout - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.1.0" async: dependency: transitive description: name: async - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.8.1" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.1.0" characters: dependency: transitive description: name: characters - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.1.0" charcode: dependency: transitive description: name: charcode - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.3.1" charts_common: dependency: transitive description: name: charts_common - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "0.11.0" charts_flutter: dependency: "direct main" description: name: charts_flutter - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "0.11.0" clock: dependency: transitive description: name: clock - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.1.0" collection: dependency: transitive description: name: collection - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.15.0" countly_flutter: @@ -77,49 +77,49 @@ packages: dependency: transitive description: name: crypto - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "3.0.1" dio: dependency: "direct main" description: name: dio - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "4.0.0" extended_image: dependency: "direct main" description: name: extended_image - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "4.2.1" extended_image_library: dependency: transitive description: name: extended_image_library - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "3.1.0" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.2.0" ffi: dependency: transitive description: name: ffi - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.1.2" file: dependency: transitive description: name: file - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "6.1.2" flutter: @@ -131,21 +131,21 @@ packages: dependency: "direct dev" description: name: flutter_lints - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.0.4" flutter_plugin_android_lifecycle: dependency: transitive description: name: flutter_plugin_android_lifecycle - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.0.3" flutter_staggered_animations: dependency: "direct main" description: name: flutter_staggered_animations - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.0.0" flutter_test: @@ -162,168 +162,168 @@ packages: dependency: "direct main" description: name: get_it - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "7.2.0" hive: dependency: "direct main" description: name: hive - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.0.4" hive_flutter: dependency: "direct main" description: name: hive_flutter - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.1.0" http: dependency: transitive description: name: http - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "0.13.3" http_client_helper: dependency: transitive description: name: http_client_helper - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.0.2" http_parser: dependency: transitive description: name: http_parser - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "4.0.0" intl: dependency: transitive description: name: intl - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "0.17.0" js: dependency: transitive description: name: js - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "0.6.3" lints: dependency: transitive description: name: lints - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.0.1" logging: dependency: transitive description: name: logging - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.0.2" matcher: dependency: transitive description: name: matcher - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "0.12.10" meta: dependency: transitive description: name: meta - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.7.0" nested: dependency: transitive description: name: nested - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.0.0" path: dependency: transitive description: name: path - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.8.0" path_provider: dependency: transitive description: name: path_provider - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.0.4" path_provider_linux: dependency: transitive description: name: path_provider_linux - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.1.0" path_provider_macos: dependency: transitive description: name: path_provider_macos - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.0.2" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.0.1" path_provider_windows: dependency: transitive description: name: path_provider_windows - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.0.3" pedantic: dependency: transitive description: name: pedantic - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.11.1" platform: dependency: transitive description: name: platform - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "3.0.2" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.0.1" process: dependency: transitive description: name: process - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "4.2.3" provider: dependency: "direct main" description: name: provider - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "6.0.0" sky_engine: @@ -335,126 +335,126 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.8.1" ssh2: dependency: "direct main" description: name: ssh2 - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.2.2" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.2.0" test_api: dependency: transitive description: name: test_api - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "0.4.2" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "1.3.0" url_launcher: dependency: "direct main" description: name: url_launcher - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "6.0.10" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.0.2" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.0.2" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.0.4" url_launcher_web: dependency: transitive description: name: url_launcher_web - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.0.4" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.0.2" uuid: dependency: transitive description: name: uuid - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "3.0.4" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.1.0" win32: dependency: transitive description: name: win32 - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "2.2.9" xdg_directories: dependency: transitive description: name: xdg_directories - url: "https://pub.flutter-io.cn" + url: "https://pub.dartlang.org" source: hosted version: "0.2.0" sdks: