* chore: e2ee.

* update.

* update.

* update.

* update.

* chore: Use feat/frame-encryption branch of flutter-webrtc.

* chore: Add E2EEKEY defines for dart environment, and e2ee switch.

* Add encodedInsertableStreams to RTCConfiguration.

* update.

* feat: Add e2ee indicator for Participant.

* feat: add e2ee worker js for flutter web.

* dart format.

* remove unused file.

* fix flutter analyze .

* update.

* update.

* add: indicate for decryption failure, and string key.

* remove .lock files.

* update.

* update.

* update e2ee.worker for web.

* feat: support setCodecPreferences.

* state TrackE2EEStateEvent.

* fix wrong import interface from dart_webrtc.

* update.

* update.

* update.

* update.

* update pubspec.lock.

* chore: update protocol and add EncryptionType for Participant.

* Update lib/src/e2ee/options.dart

Co-authored-by: Théo Monnom <theo.monnom@outlook.com>

* fix typo.

* revert changes for internal import.

* Add _cleanUp() for previous room.

* Add e2ee supports detection method for native/web.

* Remove redundant overriding methods.

* dart format.

* Add e2ee.worker code and deployment docs.

* chore: remove duplicate words.

* chore: using Pbkdf2 derive the key.

* Update pubspec.yaml

* fix e2ee for safari.

* fix key length.

* update e2ee.worker.dart.js.

* fix.

* update proto.

* update.

* chore: add simulate for rachetKey.

* update.

* chore: key ratchet for flutter web.

* update.

* update.

* update.

* chore: key ratchet export for web.

* bump version for xframeworks.

* update.

* chore: some changes for key safety ratcheting.

* update.

* fix typo.

* update.

* rename.

* magic bytes for web.

* bump version for flutter-webrtc.

* fix analyzer.

---------

Co-authored-by: Théo Monnom <theo.monnom@outlook.com>
This commit is contained in:
CloudWebRTC
2023-04-27 17:54:32 +08:00
committed by GitHub
parent 3407221fc4
commit 26947e96d6
42 changed files with 12523 additions and 39 deletions
+1
View File
@@ -194,4 +194,5 @@ enum SimulateScenarioResult {
serverLeave,
switchCandidate,
clear,
e2eeKeyRatchet,
}
+46
View File
@@ -25,14 +25,18 @@ class _ConnectPageState extends State<ConnectPage> {
static const _storeKeyAdaptiveStream = 'adaptive-stream';
static const _storeKeyDynacast = 'dynacast';
static const _storeKeyFastConnect = 'fast-connect';
static const _storeKeyE2EE = 'e2ee';
static const _storeKeySharedKey = 'shared-key';
final _uriCtrl = TextEditingController();
final _tokenCtrl = TextEditingController();
final _sharedKeyCtrl = TextEditingController();
bool _simulcast = true;
bool _adaptiveStream = true;
bool _dynacast = true;
bool _busy = false;
bool _fastConnect = false;
bool _e2ee = false;
@override
void initState() {
@@ -56,11 +60,15 @@ class _ConnectPageState extends State<ConnectPage> {
_tokenCtrl.text = const bool.hasEnvironment('TOKEN')
? const String.fromEnvironment('TOKEN')
: prefs.getString(_storeKeyToken) ?? '';
_sharedKeyCtrl.text = const bool.hasEnvironment('E2EEKEY')
? const String.fromEnvironment('E2EEKEY')
: prefs.getString(_storeKeySharedKey) ?? '';
setState(() {
_simulcast = prefs.getBool(_storeKeySimulcast) ?? true;
_adaptiveStream = prefs.getBool(_storeKeyAdaptiveStream) ?? true;
_dynacast = prefs.getBool(_storeKeyDynacast) ?? true;
_fastConnect = prefs.getBool(_storeKeyFastConnect) ?? false;
_e2ee = prefs.getBool(_storeKeyE2EE) ?? false;
});
}
@@ -69,10 +77,12 @@ class _ConnectPageState extends State<ConnectPage> {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_storeKeyUri, _uriCtrl.text);
await prefs.setString(_storeKeyToken, _tokenCtrl.text);
await prefs.setString(_storeKeySharedKey, _sharedKeyCtrl.text);
await prefs.setBool(_storeKeySimulcast, _simulcast);
await prefs.setBool(_storeKeyAdaptiveStream, _adaptiveStream);
await prefs.setBool(_storeKeyDynacast, _dynacast);
await prefs.setBool(_storeKeyFastConnect, _fastConnect);
await prefs.setBool(_storeKeyE2EE, _e2ee);
}
Future<void> _connect(BuildContext ctx) async {
@@ -93,6 +103,13 @@ class _ConnectPageState extends State<ConnectPage> {
// Create a Listener before connecting
final listener = room.createListener();
E2EEOptions? e2eeOptions;
if (_e2ee) {
final keyProvider = await BaseKeyProvider.create();
e2eeOptions = E2EEOptions(keyProvider: keyProvider);
var sharedKey = _sharedKeyCtrl.text;
await keyProvider.setKey(sharedKey);
}
// Try to connect to the room
// This will throw an Exception if it fails for any reason.
@@ -107,6 +124,7 @@ class _ConnectPageState extends State<ConnectPage> {
),
defaultScreenShareCaptureOptions:
const ScreenShareCaptureOptions(useiOSBroadcastExtension: true),
e2eeOptions: e2eeOptions,
),
fastConnectOptions: _fastConnect
? FastConnectOptions(
@@ -115,6 +133,7 @@ class _ConnectPageState extends State<ConnectPage> {
)
: null,
);
await Navigator.push<void>(
ctx,
MaterialPageRoute(builder: (_) => RoomPage(room, listener)),
@@ -136,6 +155,13 @@ class _ConnectPageState extends State<ConnectPage> {
});
}
void _setE2EE(bool? value) async {
if (value == null || _e2ee == value) return;
setState(() {
_e2ee = value;
});
}
void _setAdaptiveStream(bool? value) async {
if (value == null || _adaptiveStream == value) return;
setState(() {
@@ -192,6 +218,26 @@ class _ConnectPageState extends State<ConnectPage> {
ctrl: _tokenCtrl,
),
),
Padding(
padding: const EdgeInsets.only(bottom: 25),
child: LKTextField(
label: 'Shared Key',
ctrl: _sharedKeyCtrl,
),
),
Padding(
padding: const EdgeInsets.only(bottom: 5),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text('E2EE'),
Switch(
value: _e2ee,
onChanged: (value) => _setE2EE(value),
),
],
),
),
Padding(
padding: const EdgeInsets.only(bottom: 5),
child: Row(
+5
View File
@@ -66,6 +66,7 @@ class _RoomPageState extends State<RoomPage> {
})
..on<LocalTrackPublishedEvent>((_) => _sortParticipants())
..on<LocalTrackUnpublishedEvent>((_) => _sortParticipants())
..on<TrackE2EEStateEvent>(_onE2EEStateEvent)
..on<ParticipantNameUpdatedEvent>((event) {
print(
'Participant name updated: ${event.participant.identity}, name => ${event.name}');
@@ -102,6 +103,10 @@ class _RoomPageState extends State<RoomPage> {
_sortParticipants();
}
void _onE2EEStateEvent(TrackE2EEStateEvent e2eeState) {
print('e2ee state: $e2eeState');
}
void _sortParticipants() {
List<ParticipantTrack> userMediaTracks = [];
List<ParticipantTrack> screenTracks = [];
+5
View File
@@ -226,6 +226,11 @@ class _ControlsWidgetState extends State<ControlsWidget> {
final result = await context.showSimulateScenarioDialog();
if (result != null) {
print('${result}');
if (SimulateScenarioResult.e2eeKeyRatchet == result) {
await widget.room.e2eeManager?.ratchetKey();
}
await widget.room.sendSimulateScenario(
signalReconnect:
result == SimulateScenarioResult.signalReconnect ? true : null,
+2
View File
@@ -153,6 +153,8 @@ abstract class _ParticipantWidgetState<T extends ParticipantWidget>
firstAudioPublication?.subscribed == true,
connectionQuality: widget.participant.connectionQuality,
isScreenShare: widget.isScreenShare,
enabledE2EE: widget.participant.firstTrackEncryptionType !=
EncryptionType.kNone,
),
],
),
+10
View File
@@ -18,12 +18,14 @@ class ParticipantInfoWidget extends StatelessWidget {
final bool audioAvailable;
final ConnectionQuality connectionQuality;
final bool isScreenShare;
final bool enabledE2EE;
const ParticipantInfoWidget({
this.title,
this.audioAvailable = true,
this.connectionQuality = ConnectionQuality.unknown,
this.isScreenShare = false,
this.enabledE2EE = false,
Key? key,
}) : super(key: key);
@@ -77,6 +79,14 @@ class ParticipantInfoWidget extends StatelessWidget {
size: 16,
),
),
Padding(
padding: const EdgeInsets.only(left: 5),
child: Icon(
enabledE2EE ? EvaIcons.lock : EvaIcons.unlock,
color: enabledE2EE ? Colors.green : Colors.red,
size: 16,
),
),
],
),
);
File diff suppressed because one or more lines are too long
+232
View File
@@ -0,0 +1,232 @@
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/collection.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/algorithms.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/boollist.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/canonicalized_map.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/combined_wrappers/combined_iterable.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/combined_wrappers/combined_iterator.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/combined_wrappers/combined_list.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/combined_wrappers/combined_map.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/comparators.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/empty_unmodifiable_set.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/equality.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/equality_map.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/equality_set.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/functions.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/iterable_extensions.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/iterable_zip.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/list_extensions.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/priority_queue.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/queue_list.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/union_set.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/union_set_controller.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/unmodifiable_wrappers.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/utils.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/collection-1.17.0/lib/src/wrappers.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/js-0.6.5/lib/js.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/meta-1.8.0/lib/meta.dart
file:///Users/weiweiduan/.pub-cache/hosted/pub.flutter-io.cn/meta-1.8.0/lib/meta_meta.dart
file:///Users/weiweiduan/Desktop/projects/flutter-webrtc/lib/src/web/rtc_transform_stream.dart
file:///Users/weiweiduan/Desktop/projects/livekit/client-sdk-flutter/.dart_tool/package_config.json
file:///Users/weiweiduan/Desktop/projects/livekit/client-sdk-flutter/web/crypto.dart
file:///Users/weiweiduan/Desktop/projects/livekit/client-sdk-flutter/web/e2ee.cryptor.dart
file:///Users/weiweiduan/Desktop/projects/livekit/client-sdk-flutter/web/e2ee.utils.dart
file:///Users/weiweiduan/Desktop/projects/livekit/client-sdk-flutter/web/e2ee.worker.dart
file:///Users/weiweiduan/bin/flutter/bin/cache/dart-sdk/lib/_internal/dart2js_platform.dill
file:///Users/weiweiduan/bin/flutter/bin/cache/dart-sdk/lib/libraries.json
org-dartlang-sdk:///lib/_http/crypto.dart
org-dartlang-sdk:///lib/_http/embedder_config.dart
org-dartlang-sdk:///lib/_http/http.dart
org-dartlang-sdk:///lib/_http/http_date.dart
org-dartlang-sdk:///lib/_http/http_headers.dart
org-dartlang-sdk:///lib/_http/http_impl.dart
org-dartlang-sdk:///lib/_http/http_parser.dart
org-dartlang-sdk:///lib/_http/http_session.dart
org-dartlang-sdk:///lib/_http/http_testing.dart
org-dartlang-sdk:///lib/_http/overrides.dart
org-dartlang-sdk:///lib/_http/websocket.dart
org-dartlang-sdk:///lib/_http/websocket_impl.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/annotations.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/async_patch.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/collection_patch.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/constant_map.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/convert_patch.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/core_patch.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/dart2js_runtime_metrics.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/developer_patch.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/foreign_helper.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/instantiation.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/interceptors.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/internal_patch.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/io_patch.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/isolate_patch.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/js_array.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/js_helper.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/js_names.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/js_number.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/js_patch.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/js_primitives.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/js_string.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/late_helper.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/linked_hash_map.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/math_patch.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/native_helper.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/native_typed_data.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/regexp_helper.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/string_helper.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/synced/async_await_error_codes.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/synced/embedded_names.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/synced/load_library_priority.dart
org-dartlang-sdk:///lib/_internal/js_runtime/lib/typed_data_patch.dart
org-dartlang-sdk:///lib/_internal/js_shared/lib/js_util_patch.dart
org-dartlang-sdk:///lib/_internal/js_shared/lib/rti.dart
org-dartlang-sdk:///lib/_internal/js_shared/lib/synced/embedded_names.dart
org-dartlang-sdk:///lib/_internal/js_shared/lib/synced/recipe_syntax.dart
org-dartlang-sdk:///lib/async/async.dart
org-dartlang-sdk:///lib/async/async_error.dart
org-dartlang-sdk:///lib/async/broadcast_stream_controller.dart
org-dartlang-sdk:///lib/async/deferred_load.dart
org-dartlang-sdk:///lib/async/future.dart
org-dartlang-sdk:///lib/async/future_impl.dart
org-dartlang-sdk:///lib/async/schedule_microtask.dart
org-dartlang-sdk:///lib/async/stream.dart
org-dartlang-sdk:///lib/async/stream_controller.dart
org-dartlang-sdk:///lib/async/stream_impl.dart
org-dartlang-sdk:///lib/async/stream_pipe.dart
org-dartlang-sdk:///lib/async/stream_transformers.dart
org-dartlang-sdk:///lib/async/timer.dart
org-dartlang-sdk:///lib/async/zone.dart
org-dartlang-sdk:///lib/collection/collection.dart
org-dartlang-sdk:///lib/collection/collections.dart
org-dartlang-sdk:///lib/collection/hash_map.dart
org-dartlang-sdk:///lib/collection/hash_set.dart
org-dartlang-sdk:///lib/collection/iterable.dart
org-dartlang-sdk:///lib/collection/iterator.dart
org-dartlang-sdk:///lib/collection/linked_hash_map.dart
org-dartlang-sdk:///lib/collection/linked_hash_set.dart
org-dartlang-sdk:///lib/collection/linked_list.dart
org-dartlang-sdk:///lib/collection/list.dart
org-dartlang-sdk:///lib/collection/maps.dart
org-dartlang-sdk:///lib/collection/queue.dart
org-dartlang-sdk:///lib/collection/set.dart
org-dartlang-sdk:///lib/collection/splay_tree.dart
org-dartlang-sdk:///lib/convert/ascii.dart
org-dartlang-sdk:///lib/convert/base64.dart
org-dartlang-sdk:///lib/convert/byte_conversion.dart
org-dartlang-sdk:///lib/convert/chunked_conversion.dart
org-dartlang-sdk:///lib/convert/codec.dart
org-dartlang-sdk:///lib/convert/convert.dart
org-dartlang-sdk:///lib/convert/converter.dart
org-dartlang-sdk:///lib/convert/encoding.dart
org-dartlang-sdk:///lib/convert/html_escape.dart
org-dartlang-sdk:///lib/convert/json.dart
org-dartlang-sdk:///lib/convert/latin1.dart
org-dartlang-sdk:///lib/convert/line_splitter.dart
org-dartlang-sdk:///lib/convert/string_conversion.dart
org-dartlang-sdk:///lib/convert/utf.dart
org-dartlang-sdk:///lib/core/annotations.dart
org-dartlang-sdk:///lib/core/bigint.dart
org-dartlang-sdk:///lib/core/bool.dart
org-dartlang-sdk:///lib/core/comparable.dart
org-dartlang-sdk:///lib/core/core.dart
org-dartlang-sdk:///lib/core/date_time.dart
org-dartlang-sdk:///lib/core/double.dart
org-dartlang-sdk:///lib/core/duration.dart
org-dartlang-sdk:///lib/core/enum.dart
org-dartlang-sdk:///lib/core/errors.dart
org-dartlang-sdk:///lib/core/exceptions.dart
org-dartlang-sdk:///lib/core/function.dart
org-dartlang-sdk:///lib/core/int.dart
org-dartlang-sdk:///lib/core/invocation.dart
org-dartlang-sdk:///lib/core/iterable.dart
org-dartlang-sdk:///lib/core/iterator.dart
org-dartlang-sdk:///lib/core/list.dart
org-dartlang-sdk:///lib/core/map.dart
org-dartlang-sdk:///lib/core/null.dart
org-dartlang-sdk:///lib/core/num.dart
org-dartlang-sdk:///lib/core/object.dart
org-dartlang-sdk:///lib/core/pattern.dart
org-dartlang-sdk:///lib/core/print.dart
org-dartlang-sdk:///lib/core/record.dart
org-dartlang-sdk:///lib/core/regexp.dart
org-dartlang-sdk:///lib/core/set.dart
org-dartlang-sdk:///lib/core/sink.dart
org-dartlang-sdk:///lib/core/stacktrace.dart
org-dartlang-sdk:///lib/core/stopwatch.dart
org-dartlang-sdk:///lib/core/string.dart
org-dartlang-sdk:///lib/core/string_buffer.dart
org-dartlang-sdk:///lib/core/string_sink.dart
org-dartlang-sdk:///lib/core/symbol.dart
org-dartlang-sdk:///lib/core/type.dart
org-dartlang-sdk:///lib/core/uri.dart
org-dartlang-sdk:///lib/core/weak.dart
org-dartlang-sdk:///lib/developer/developer.dart
org-dartlang-sdk:///lib/developer/extension.dart
org-dartlang-sdk:///lib/developer/profiler.dart
org-dartlang-sdk:///lib/developer/service.dart
org-dartlang-sdk:///lib/developer/timeline.dart
org-dartlang-sdk:///lib/html/dart2js/html_dart2js.dart
org-dartlang-sdk:///lib/html/html_common/conversions.dart
org-dartlang-sdk:///lib/html/html_common/conversions_dart2js.dart
org-dartlang-sdk:///lib/html/html_common/css_class_set.dart
org-dartlang-sdk:///lib/html/html_common/device.dart
org-dartlang-sdk:///lib/html/html_common/filtered_element_list.dart
org-dartlang-sdk:///lib/html/html_common/html_common_dart2js.dart
org-dartlang-sdk:///lib/html/html_common/lists.dart
org-dartlang-sdk:///lib/html/html_common/metadata.dart
org-dartlang-sdk:///lib/indexed_db/dart2js/indexed_db_dart2js.dart
org-dartlang-sdk:///lib/internal/async_cast.dart
org-dartlang-sdk:///lib/internal/bytes_builder.dart
org-dartlang-sdk:///lib/internal/cast.dart
org-dartlang-sdk:///lib/internal/errors.dart
org-dartlang-sdk:///lib/internal/internal.dart
org-dartlang-sdk:///lib/internal/iterable.dart
org-dartlang-sdk:///lib/internal/linked_list.dart
org-dartlang-sdk:///lib/internal/list.dart
org-dartlang-sdk:///lib/internal/patch.dart
org-dartlang-sdk:///lib/internal/print.dart
org-dartlang-sdk:///lib/internal/sort.dart
org-dartlang-sdk:///lib/internal/symbol.dart
org-dartlang-sdk:///lib/io/common.dart
org-dartlang-sdk:///lib/io/data_transformer.dart
org-dartlang-sdk:///lib/io/directory.dart
org-dartlang-sdk:///lib/io/directory_impl.dart
org-dartlang-sdk:///lib/io/embedder_config.dart
org-dartlang-sdk:///lib/io/eventhandler.dart
org-dartlang-sdk:///lib/io/file.dart
org-dartlang-sdk:///lib/io/file_impl.dart
org-dartlang-sdk:///lib/io/file_system_entity.dart
org-dartlang-sdk:///lib/io/io.dart
org-dartlang-sdk:///lib/io/io_resource_info.dart
org-dartlang-sdk:///lib/io/io_service.dart
org-dartlang-sdk:///lib/io/io_sink.dart
org-dartlang-sdk:///lib/io/link.dart
org-dartlang-sdk:///lib/io/namespace_impl.dart
org-dartlang-sdk:///lib/io/network_profiling.dart
org-dartlang-sdk:///lib/io/overrides.dart
org-dartlang-sdk:///lib/io/platform.dart
org-dartlang-sdk:///lib/io/platform_impl.dart
org-dartlang-sdk:///lib/io/process.dart
org-dartlang-sdk:///lib/io/secure_server_socket.dart
org-dartlang-sdk:///lib/io/secure_socket.dart
org-dartlang-sdk:///lib/io/security_context.dart
org-dartlang-sdk:///lib/io/service_object.dart
org-dartlang-sdk:///lib/io/socket.dart
org-dartlang-sdk:///lib/io/stdio.dart
org-dartlang-sdk:///lib/io/string_transformer.dart
org-dartlang-sdk:///lib/io/sync_socket.dart
org-dartlang-sdk:///lib/isolate/capability.dart
org-dartlang-sdk:///lib/isolate/isolate.dart
org-dartlang-sdk:///lib/js/_js.dart
org-dartlang-sdk:///lib/js/_js_annotations.dart
org-dartlang-sdk:///lib/js/_js_client.dart
org-dartlang-sdk:///lib/js/js.dart
org-dartlang-sdk:///lib/js_util/js_util.dart
org-dartlang-sdk:///lib/math/math.dart
org-dartlang-sdk:///lib/math/point.dart
org-dartlang-sdk:///lib/math/random.dart
org-dartlang-sdk:///lib/math/rectangle.dart
org-dartlang-sdk:///lib/svg/dart2js/svg_dart2js.dart
org-dartlang-sdk:///lib/typed_data/typed_data.dart
org-dartlang-sdk:///lib/typed_data/unmodifiable_typed_data.dart
org-dartlang-sdk:///lib/web_audio/dart2js/web_audio_dart2js.dart
org-dartlang-sdk:///lib/web_gl/dart2js/web_gl_dart2js.dart
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB