Skip to content

Commit 990916d

Browse files
committed
FileIO module implemented
1 parent 0bd36b6 commit 990916d

File tree

4 files changed

+266
-14
lines changed

4 files changed

+266
-14
lines changed

.flutter-plugins-dependencies

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_jscore","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_jscore-1.0.0\\\\","dependencies":[]},{"name":"path_provider_ios","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_ios-2.0.7\\\\","dependencies":[]},{"name":"permission_handler","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler-8.3.0\\\\","dependencies":[]},{"name":"shared_preferences_ios","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_ios-2.0.8\\\\","dependencies":[]},{"name":"url_launcher","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\url_launcher-6.0.15\\\\","dependencies":[]}],"android":[{"name":"flutter_jscore","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_jscore-1.0.0\\\\","dependencies":[]},{"name":"path_provider_android","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_android-2.0.9\\\\","dependencies":[]},{"name":"permission_handler","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler-8.3.0\\\\","dependencies":[]},{"name":"shared_preferences_android","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_android-2.0.9\\\\","dependencies":[]},{"name":"url_launcher","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\url_launcher-6.0.15\\\\","dependencies":[]}],"macos":[{"name":"flutter_jscore","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_jscore-1.0.0\\\\","dependencies":[]},{"name":"path_provider_macos","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_macos-2.0.3\\\\","dependencies":[]},{"name":"shared_preferences_macos","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_macos-2.0.2\\\\","dependencies":[]},{"name":"url_launcher_macos","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\url_launcher_macos-2.0.2\\\\","dependencies":[]}],"linux":[{"name":"flutter_jscore","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_jscore-1.0.0\\\\","dependencies":[]},{"name":"path_provider_linux","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_linux-2.1.2\\\\","dependencies":[]},{"name":"shared_preferences_linux","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_linux-2.0.3\\\\","dependencies":["path_provider_linux"]},{"name":"url_launcher_linux","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\url_launcher_linux-2.0.2\\\\","dependencies":[]}],"windows":[{"name":"flutter_jscore","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_jscore-1.0.0\\\\","dependencies":[]},{"name":"path_provider_windows","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_windows-2.0.4\\\\","dependencies":[]},{"name":"shared_preferences_windows","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_windows-2.0.3\\\\","dependencies":["path_provider_windows"]},{"name":"url_launcher_windows","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\url_launcher_windows-2.0.2\\\\","dependencies":[]}],"web":[{"name":"shared_preferences_web","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_web-2.0.2\\\\","dependencies":[]},{"name":"url_launcher_web","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\url_launcher_web-2.0.4\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_jscore","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_ios","path_provider_linux","path_provider_macos","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_ios","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_ios","shared_preferences_linux","shared_preferences_macos","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_ios","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2021-12-13 08:26:45.743616","version":"2.5.3"}
1+
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_jscore","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_jscore-1.0.0\\\\","dependencies":[]},{"name":"path_provider_ios","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_ios-2.0.7\\\\","dependencies":[]},{"name":"permission_handler","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler-8.3.0\\\\","dependencies":[]},{"name":"shared_preferences_ios","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_ios-2.0.8\\\\","dependencies":[]},{"name":"url_launcher","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\url_launcher-6.0.15\\\\","dependencies":[]}],"android":[{"name":"flutter_jscore","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_jscore-1.0.0\\\\","dependencies":[]},{"name":"path_provider_android","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_android-2.0.9\\\\","dependencies":[]},{"name":"permission_handler","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\permission_handler-8.3.0\\\\","dependencies":[]},{"name":"shared_preferences_android","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_android-2.0.9\\\\","dependencies":[]},{"name":"url_launcher","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\url_launcher-6.0.15\\\\","dependencies":[]}],"macos":[{"name":"flutter_jscore","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_jscore-1.0.0\\\\","dependencies":[]},{"name":"path_provider_macos","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_macos-2.0.3\\\\","dependencies":[]},{"name":"shared_preferences_macos","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_macos-2.0.2\\\\","dependencies":[]},{"name":"url_launcher_macos","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\url_launcher_macos-2.0.2\\\\","dependencies":[]}],"linux":[{"name":"flutter_jscore","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_jscore-1.0.0\\\\","dependencies":[]},{"name":"path_provider_linux","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_linux-2.1.2\\\\","dependencies":[]},{"name":"shared_preferences_linux","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_linux-2.0.3\\\\","dependencies":["path_provider_linux"]},{"name":"url_launcher_linux","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\url_launcher_linux-2.0.2\\\\","dependencies":[]}],"windows":[{"name":"flutter_jscore","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\flutter_jscore-1.0.0\\\\","dependencies":[]},{"name":"path_provider_windows","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_windows-2.0.4\\\\","dependencies":[]},{"name":"shared_preferences_windows","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_windows-2.0.3\\\\","dependencies":["path_provider_windows"]},{"name":"url_launcher_windows","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\url_launcher_windows-2.0.2\\\\","dependencies":[]}],"web":[{"name":"shared_preferences_web","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\shared_preferences_web-2.0.2\\\\","dependencies":[]},{"name":"url_launcher_web","path":"D:\\\\Programming\\\\Flutter\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\url_launcher_web-2.0.4\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_jscore","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_ios","path_provider_linux","path_provider_macos","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_ios","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_ios","shared_preferences_linux","shared_preferences_macos","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_ios","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2021-12-13 12:12:32.625939","version":"2.5.3"}

lib/modules/jsapi.dart

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import 'dart:convert';
22
import 'dart:ffi';
3+
import 'dart:io';
34
import 'dart:typed_data';
45
import 'package:corecoder_develop/modules/module_jsplugins.dart';
56
import 'package:corecoder_develop/util/modules_manager.dart';
7+
import 'package:corecoder_develop/util/plugins_manager.dart';
68
import 'package:flutter/material.dart';
79
import 'package:ffi/ffi.dart';
810
import 'package:flutter_jscore/flutter_jscore.dart';
@@ -187,6 +189,20 @@ class CoreCoder {
187189
return nullptr;
188190
}
189191

192+
static Pointer jsGetProjectFolder(Pointer ctx,
193+
Pointer function,
194+
Pointer thisObject,
195+
int argumentCount,
196+
Pointer<Pointer> arguments,
197+
Pointer<Pointer> exception){
198+
if(argumentCount != 2){
199+
debugPrint("JS Plugin Error: getProjectFolder: Argument Count expected: 2");
200+
return nullptr;
201+
}
202+
var result = PluginsManager.projectsPath;
203+
return JSValue.makeString(context, result).pointer;
204+
}
205+
190206

191207
/// # ======== THE PRINT FUNCTION ========== # ///
192208
static Pointer jsPrint(
@@ -220,4 +236,221 @@ class CoreCoder {
220236
class FileIO{
221237
static late JsModule module; // set by the parent object
222238
static late JSContext context; // set by the parent object
239+
240+
static FileIO? _instance;
241+
static FileIO get instance{
242+
_instance ??= FileIO();
243+
return _instance!;
244+
}
245+
246+
void fileExists(Pointer ctx,
247+
Pointer function,
248+
Pointer thisObject,
249+
int argumentCount,
250+
Pointer<Pointer> arguments,
251+
Pointer<Pointer> exception){
252+
if (argumentCount > 0) {
253+
Pointer jsValueRef = arguments[0];
254+
if (js.jSValueIsObject(ctx, jsValueRef) == 1) {
255+
/// the provided argument 0 is an object, then parse it
256+
String name, description, version, identifier;
257+
Pointer obj = js.jSValueToObject(ctx, jsValueRef, nullptr);
258+
name = _getJsValue(ctx,js.jSObjectGetProperty(ctx, obj,
259+
js.jSStringCreateWithUTF8CString('name'.toNativeUtf8()), nullptr));
260+
261+
description = _getJsValue(ctx,js.jSObjectGetProperty(
262+
ctx,
263+
obj,
264+
js.jSStringCreateWithUTF8CString('description'.toNativeUtf8()),
265+
nullptr));
266+
267+
version = _getJsValue(ctx,js.jSObjectGetProperty(ctx, obj,
268+
js.jSStringCreateWithUTF8CString('version'.toNativeUtf8()), nullptr));
269+
270+
identifier = _getJsValue(ctx,js.jSObjectGetProperty(
271+
ctx,
272+
obj,
273+
js.jSStringCreateWithUTF8CString('identifier'.toNativeUtf8()),
274+
nullptr));
275+
276+
var _options = js.jSObjectGetProperty(ctx, obj,
277+
js.jSStringCreateWithUTF8CString('options'.toNativeUtf8()), nullptr);
278+
var options = jsObjectToDartMap(ctx,_options);
279+
280+
var onCreate = (Map<String, dynamic> args) async {};
281+
var _onCreate = js.jSObjectGetProperty(ctx, obj,
282+
js.jSStringCreateWithUTF8CString('onCreate'.toNativeUtf8()), nullptr);
283+
if (js.jSValueIsObject(ctx, _onCreate) == 1) {
284+
onCreate = (Map<String, dynamic> args) async {
285+
var optionsObj = JSObject.make(
286+
context,
287+
JSClass.create(
288+
JSClassDefinition(className: "OptionsObj")));
289+
for (var key in args.keys) {
290+
var value = args[key];
291+
if (value is String) {
292+
optionsObj.setProperty(
293+
key,
294+
JSValue.makeString(context, value),
295+
JSPropertyAttributes.kJSPropertyAttributeReadOnly);
296+
} else if (value is int || value is double) {
297+
optionsObj.setProperty(
298+
key,
299+
JSValue.makeNumber(context, value as double),
300+
JSPropertyAttributes.kJSPropertyAttributeReadOnly);
301+
}
302+
}
303+
js.jSObjectCallAsFunction(
304+
ctx,
305+
_onCreate,
306+
obj,
307+
1,
308+
JSValuePointer.array([optionsObj.toValue()]).pointer,
309+
nullptr);
310+
};
311+
}
312+
313+
module.templates.add(Template(
314+
name,
315+
description,
316+
version,
317+
options,
318+
onCreate,
319+
module.icon,
320+
identifier,
321+
));
322+
}
323+
}
324+
}
325+
326+
static Pointer jsIsExists(Pointer ctx,
327+
Pointer function,
328+
Pointer thisObject,
329+
int argumentCount,
330+
Pointer<Pointer> arguments,
331+
Pointer<Pointer> exception){
332+
bool exists = false;
333+
if(argumentCount == 1){
334+
//TODO: better exception handling
335+
var path = _getJsValue(context.pointer, arguments[0]);
336+
exists = File(path).existsSync();
337+
}
338+
return JSValue.makeBoolean(context, exists).pointer;
339+
}
340+
341+
static Pointer jsIsFile(Pointer ctx,
342+
Pointer function,
343+
Pointer thisObject,
344+
int argumentCount,
345+
Pointer<Pointer> arguments,
346+
Pointer<Pointer> exception){
347+
bool exists = false;
348+
if(argumentCount == 1){
349+
//TODO: better exception handling
350+
var path = _getJsValue(context.pointer, arguments[0]);
351+
exists = File(path).existsSync();
352+
}
353+
return JSValue.makeBoolean(context, exists).pointer;
354+
}
355+
356+
static Pointer jsIsDirectory(Pointer ctx,
357+
Pointer function,
358+
Pointer thisObject,
359+
int argumentCount,
360+
Pointer<Pointer> arguments,
361+
Pointer<Pointer> exception){
362+
bool exists = false;
363+
if(argumentCount == 1){
364+
//TODO: better exception handling
365+
var path = _getJsValue(context.pointer, arguments[0]);
366+
exists = Directory(path).existsSync();
367+
}
368+
return JSValue.makeBoolean(context, exists).pointer;
369+
}
370+
static Pointer jsWriteFile(Pointer ctx,
371+
Pointer function,
372+
Pointer thisObject,
373+
int argumentCount,
374+
Pointer<Pointer> arguments,
375+
Pointer<Pointer> exception){
376+
if(argumentCount == 2){
377+
//TODO: better exception handling
378+
//TODO: check if successfully written the file
379+
var path = _getJsValue(context.pointer, arguments[0]);
380+
var content = _getJsValue(context.pointer, arguments[1]);
381+
File(path).writeAsStringSync(content);
382+
}
383+
return nullptr;
384+
}
385+
static Pointer jsAppendFile(Pointer ctx,
386+
Pointer function,
387+
Pointer thisObject,
388+
int argumentCount,
389+
Pointer<Pointer> arguments,
390+
Pointer<Pointer> exception){
391+
if(argumentCount == 2){
392+
//TODO: better exception handling
393+
//TODO: check if successfully written the file
394+
var path = _getJsValue(context.pointer, arguments[0]);
395+
var content = _getJsValue(context.pointer, arguments[1]);
396+
File(path).writeAsStringSync(content, mode: FileMode.append);
397+
}
398+
return nullptr;
399+
}
400+
static Pointer jsReadFile(Pointer ctx,
401+
Pointer function,
402+
Pointer thisObject,
403+
int argumentCount,
404+
Pointer<Pointer> arguments,
405+
Pointer<Pointer> exception){
406+
var content = "";
407+
if(argumentCount == 1){
408+
//TODO: better exception handling
409+
var path = _getJsValue(context.pointer, arguments[0]);
410+
content = File(path).readAsStringSync();
411+
}
412+
return JSValue.makeString(context, content).pointer;
413+
}
414+
415+
416+
static Pointer jsMkdir(Pointer ctx,
417+
Pointer function,
418+
Pointer thisObject,
419+
int argumentCount,
420+
Pointer<Pointer> arguments,
421+
Pointer<Pointer> exception){
422+
if(argumentCount == 1){
423+
//TODO: better exception handling
424+
var path = _getJsValue(context.pointer, arguments[0]);
425+
Directory(path).createSync();
426+
}
427+
return nullptr;
428+
}
429+
430+
static Pointer jsMkdirRecursive(Pointer ctx,
431+
Pointer function,
432+
Pointer thisObject,
433+
int argumentCount,
434+
Pointer<Pointer> arguments,
435+
Pointer<Pointer> exception){
436+
if(argumentCount == 1){
437+
//TODO: better exception handling
438+
var path = _getJsValue(context.pointer, arguments[0]);
439+
Directory(path).createSync(recursive: true);
440+
}
441+
return nullptr;
442+
}
443+
static Pointer jsRmdir(Pointer ctx,
444+
Pointer function,
445+
Pointer thisObject,
446+
int argumentCount,
447+
Pointer<Pointer> arguments,
448+
Pointer<Pointer> exception){
449+
if(argumentCount == 1){
450+
//TODO: better exception handling
451+
var path = _getJsValue(context.pointer, arguments[0]);
452+
Directory(path).deleteSync(recursive: true);
453+
}
454+
return nullptr;
455+
}
223456
}

0 commit comments

Comments
 (0)